标签:
有很久没谈关于设计模式的内容了,这次我想来谈谈新的看法。
在这里我还想再次啰嗦两句设计的原则:开闭原则,依赖倒置,接口隔离,里氏替换原则,最小知识,单一职责。
还有几个规范:面向接口编程是稳定的架构,能使用组合尽量不使用继承来关联,重写破坏了对象的封装性破坏了开闭原则。
关于设计模式,没有特定的规范,这只是一种思想,同一种设计模式可能演变出很多类似的变种,这个时候死板硬套并不好,应该理解内在的设计思想,为什么这么设计,说不出这么设计的好处就很有可能造成过度设计,应该尽量避免为了设计模式而设计模式。
掌握设计模式的要点在于角色,和解决的问题,思想。
这次我来聊聊装饰模式,装饰模式(Decrator despattern),这个模式的意义就是为原来的类添加新的功能,最近也在学习动态代理AOP等等东西,区别在于动态代理更多的是运行时候添加一些通用的功能,而装饰模式更多的是静态的在代码层面添加新功能,类似代理模式当中的静态模式。
再次重申学习设计模式一定要掌握每个角色的职责和角色之间的关系。
装饰模式设计的角色有:
接口组件:定义规则,需要实现的方法。
被修饰的类:实现了接口定义的规则。
装饰类:也实现了接口,它拥有接口的引用,用于指向被修饰的类,这里类似于代理模式。
具体装饰类:继承装饰类,因为装饰方法可能多种多样,这样可以增加扩展性。
引用一下百科的UML图:
我们这里举个栗子:
妹纸都喜欢买衣服,买了衣服然后觉得没配套的裤子,买了裤子觉得应该搭新的衣服,然后又没裤子了。。总之就是买买买。我们首先抽象定义一个Person
interface Person {
void wear();
}
实现了该类的Girl,这里我们是被装饰的类
class Girl implements Person {
@Override
public void wear() {
System.out.println("我看了看衣柜,什么也没有");
}
}
妹纸看了衣柜什么也没有然后要一个装饰:
class Decrator implements Person {
Person person;
@Override
public void wear() {
/*如果只有一个装饰器,就在这里写,
不用另外写子类实现,
通常情况下我们有不同的装饰实现可扩展性更强*/
}
public Decrator(Person person) {
this.person = person;
}
}
然后分别有两个实现类,要么去买了牛仔裤,要么去优衣库买了衣服:
class Jazz extends Decrator {
public Jazz(Person person) {
super(person);
}
// 重写装饰的方法
@Override
public void wear() {
person.wear();
System.out.println("我买了条牛仔裤");
}
}
class UNIQU extends Decrator {
public UNIQU(Person person) {
super(person);
}
@Override
public void wear() {
person.wear();
System.out.println("我买了优衣库的衣服");
}
}
客户端使用的时候:
// 没有装饰
Person girl = new Girl();
girl.wear();
System.out.println("----我去买牛仔裤----");
// 牛仔裤装饰
girl = new Jazz(new Girl());
girl.wear();
System.out.println("----我去买优衣库----");
// 优衣库装饰
girl = new UNIQU(new Girl());
girl.wear();
运行结果如下:
我看了看衣柜
----我去买牛仔裤----
我看了看衣柜
我买了条牛仔裤
----我去买优衣库----
我看了看衣柜
我买了优衣库的衣服
关键理解几个角色,定义接口,被修饰,修饰类拥有接口,装饰类构造方法把被装饰的保存进来进行修饰。
标签:
原文地址:http://blog.csdn.net/micro_hz/article/details/51330587