装饰模式值的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象
需要扩展一个类的功能,或给一个类添加附件职责
需要动态的给一个对象添加功能,这些功能可以再动态的撤销
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实
当不能采用生成子类的方法进行扩充时,一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的结构就可以在外部
增加附加的功能。在面向对象的设计中,通常是通过继承来实现给定类的功能扩展
装饰模式:可以就在字面意思理解
比如人的衣服装饰 早上天气好 我要穿上上衣还有裤子。但是到了中午的时候天气不好了,就要加一件外套。
当如果要用Java设计对象来表现的话,就会想到的是继承,冷了我就继承这个原有的我加一个外套属性,如果继续冷,我就继续加。加到不冷为止
这个时候就会发现继承类是不是太多了。为了不断的加衣服。这个时候装饰模式就有了作用
对象设计
共有的:人和衣服都是可以被展示出来的
人是有名字的
衣服都是装饰品
首先是人这个类
public class Person {
public Person(){}
private String name;
public Person(String name){
this.name = name;
}
public void show(){
System.out.println("装扮的--->"+name);
}
}
穿衣要继承自人这个类 穿衣可以理解为一个行为。有了这个行为才可以装饰衣服
public class Costume extends Person {
protected Person component;
public void Decorate(Person component){
this.component = component;
}
@Override
public void show(){
if (component != null){
component.show();
}
}
}
穿上衣服要有穿衣行为这个动作 所以要继承这个行为
public class BigTrouser extends Costume{
@Override
public void show() {
super.show();
System.out.println("裤子");
}
}
裤子也就是和这个一样 只要继承这个穿衣行文就可以了
在main方法中。使用代码
Person person = new Person("老大");
TShirte tShirte = new TShirte();
BigTrouser bigTrouser = new BigTrouser();
tShirte.Decorate(person);
bigTrouser.Decorate(tShirte);
bigTrouser.show();
这个是不是和IO流的包裹很像,IO流是使用的装饰模式。这就就不能累加继承而是进行包裹来增加功能
如果想穿上外套就只要在继承这个穿衣行文,进行包裹就可以了。
下面是百度百科的
优点:
- Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点:
- 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
- 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
- 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择
设计原则:
- 多用组合,少用继承。
利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。
- 类应设计的对扩展开放,对修改关闭。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。