装饰模式值的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象

需要扩展一个类的功能,或给一个类添加附件职责

需要动态的给一个对象添加功能,这些功能可以再动态的撤销

需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实

当不能采用生成子类的方法进行扩充时,一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的结构就可以在外部
增加附加的功能。在面向对象的设计中,通常是通过继承来实现给定类的功能扩展

装饰模式:可以就在字面意思理解
比如人的衣服装饰 早上天气好 我要穿上上衣还有裤子。但是到了中午的时候天气不好了,就要加一件外套。
当如果要用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流是使用的装饰模式。这就就不能累加继承而是进行包裹来增加功能

如果想穿上外套就只要在继承这个穿衣行文,进行包裹就可以了。

下面是百度百科的
优点:

  1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

  1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择

设计原则:

  1. 多用组合,少用继承。

利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

  1. 类应设计的对扩展开放,对修改关闭。

YacaToy
2 声望3 粉丝