23种设计模式——装饰者模式

装饰者模式

一、定义

装饰者模式:动态的给对象添加一些额外的属性或者行为(方法),无需修改原本的对象,直接添加就行,相比于继承,装饰者模式更加的灵活。

UML图

Component是一个基类,被装饰类ConcreateComponent和装饰类Decorator都是继承这个基类。

二、实例运用

需求:一个人出门,根据不同的时候穿不同的衣服,现有短T,卫衣,夹克。

因为在此需求中,没有基类的抽象类。因此人即代表基类的抽象类Component也代表具体的被装饰者类ConcreteComponent。

 

第一步:创建被装饰类Person

package com.golf.decoration;

public class Person {
  private String name;
  public Person(){

  }

  public Person(String name) {
      this.name = name;
  }

  public void show(){
      System.out.println("装扮的是:"+name);
  }
}

第二步:创建抽象的装饰类Cloth

package com.golf.decoration;

//装饰类(接口)
public class Cloth extends Person {
  private Person component;

  //装饰
  public void decorate(Person component){
      this.component = component;
  }
   
  public void show(){   //调用被修饰类Person的show方法
      if(component != null)
            component.show();
  }
}

第三步:创建各个具体的装饰类

Tshirt类

package com.golf.decoration;

//具体的修饰类
public class Tshirt extends Cloth {
  @Override
  public void show() {     //Tshirt类特有的信息
      System.out.println("Tshirt");
      super.show();
  }
}

Jacket类

package com.golf.decoration;

//具体的装饰类
public class Jacket extends Cloth{
  @Override
  public void show() {
      System.out.println("夹克");
      super.show();
  }
}

Hoodie类

package com.golf.decoration;

//具体的装饰类
public class Hoodie extends Cloth {
  @Override
  public void show() {
      System.out.println("卫衣");
      super.show();
  }
}

第四步:创建客户端进行调用

package com.golf.decoration;


public class Client {
  public static void main(String[] args) {
      Person person = new Person("吴彦祖"); //创建被修饰类
  //   person.show();
      Hoodie hoodie = new Hoodie();
      Jacket jacket = new Jacket();
      hoodie.decorate(person);
      jacket.decorate(hoodie);
      jacket.show();

  }
}

第二个实例:

卖蛋糕,蛋糕原价66元,倘若加奶油需要加10元,倘若加蜡烛加16元

第一步:创建被修饰类和修饰类的基类

package com.golf.decoration2;

//创建被修饰类和修饰类的基类
public abstract class Sweet {
  private String name;
   
  //修饰的方法
  public String getDescription(){   //让继承的被修饰类的方法能够继承
      return name;
  }
   
  //修饰的方法
  public abstract double cost(); //让继承的被修饰类的方法能够继承
}

 

第二步:创建被修饰类

package com.golf.decoration2;

//创建被修饰类 concreteComponent
public class Cake extends Sweet {

  @Override
  public String getDescription() { //写入被修饰类的特性
        return "蛋糕";
  }

  @Override
  public double cost() {   //写入被修饰类的特性
      return 66;
  }
}

第二步:创建修饰类的基类

package com.golf.decoration2;

//创建修饰类
public abstract class Decoration extends Sweet{
  @Override
  public abstract String getDescription(); //创建抽象方法的装饰 便于具体的装饰方法使用

  @Override
  public abstract double cost();
}

第三步:创建具体的修饰类

package com.golf.decoration2;

//创建修饰类
public class Candle extends Decoration {
  private Sweet sweet;
   
  public Candle(Sweet sweet){ //通过构造方法选择修饰那个类
    this.sweet = sweet;
  }
   
  @Override
  public String getDescription() {
      return sweet.getDescription()+"蜡烛";
  }

  @Override
  public double cost() {
      return sweet.cost()+16;
  }
}
package com.golf.decoration2;

//创建修饰类
public class Cream extends Decoration {
  private Sweet sweet; //对于修饰类创建基类,以此知道修饰的是哪个类
  public Cream(Sweet sweet){
      this.sweet = sweet;
  }
  @Override
  public String getDescription() {
      return sweet.getDescription()+"奶油";
  }

  @Override
  public double cost() {
      return sweet.cost()+10;
  }
}

第四步:客户端

package com.golf.decoration2;

public class Client {
  public static void main(String[] args) {
      Cake cake = new Cake();
      String name = cake.getDescription();
      double cost = cake.cost();
      System.out.print(name);
      System.out.println(cost);
      Cream cream = new Cream(cake);
      Candle candle = new Candle(cream);
      Candle candle1 = new Candle(new Cream(new Cake())); //是不是很像IO流中创建时的样子,IO流就是用来装饰者模式
      System.out.println(candle1.cost());
      System.out.println(cream.getDescription()+cream.cost());
      System.out.println(candle.getDescription()+candle.cost());
  }
}

猜你喜欢

转载自www.cnblogs.com/bm654/p/11900878.html
今日推荐