装饰者设计模式举例

代码实现:

代码实现:
Drink.java               被装饰者对象的接口【豆奶继承该接口 :饮品接口,未来可能还有其它类继承该接口也是饮品类如汽水】
SoyaBeanMilk.java        具体的被装饰者对象【豆奶是用下面的:鸡蛋、糖、黑豆 来装饰】
EggDecorator.java        具体装饰者对象
SugarDecorator.java      具体装饰者对象
BlackBeanDecorator.java  具体装饰者对象
Decorator.java           装饰者基类        【一般定义为抽象类:即具体的装饰者类(鸡蛋、糖、黑豆)分别是继承它的】
Test.java                测试

Drink.java

//被装饰者的接口(接口就是基类)
public interface Drink {
    
    float cost();          //计算价格的方法 (接口的抽象方法)
    String description();  //返回描述信息的方法(接口的抽象方法)
    
}

SoyaBeanMilk.java

//具体的被装饰者类:豆浆类
public class SoyaBeanMilk implements Drink {

    @Override
    public float cost() {         //豆浆继承Drink接口,必须实现接口的抽象方法
        return 10f;
    }

    @Override
    public String description() {  //豆浆继承Drink接口,必须实现接口的抽象方法
        return "纯豆浆";
    }
    
}

Decorator.java

//装饰者的基类(是抽象类)
public abstract class Decorator implements Drink {
    private Drink drink;             //维护一个要装饰的对象【用到适配器的知识点】
    public Decorator(Drink drink) {  //通过构造方法传进来【抽象类可以有构造方法】
        this.drink=drink;
    }
    @Override
    public float cost() {            //Decorator也是继承了接口Drink,必须实现接口的方法
        return drink.cost();
    }

    @Override
    public String description() {    //Decorator也是继承了接口Drink,必须实现接口的方法
        return drink.description();
    }
    
}

SugarDecorator.java

//具体的装饰者类:糖类
public class SugarDecorator extends Decorator {

    public SugarDecorator(Drink drink) {  //构造方法;因为父类构造方法传入了参数,所有子类构造方法要传入参数时,类型一定是和父类构造的传参构造一致
        super(drink);                     //用到继承的概念:必须显示的调用父类的构造方法,当父类的构造方法有传参时,无论子类构造有传参还是无传参
    }
    
    public float cost() {                 //重写父类的方法
        return super.cost()+1.0f;         //super.cost()表示调用父类的方法,即调用Decorator类的cost方法
    }
    
    public String description() {         //重写父类的方法
        return super.description()+"糖";  //super.description()表示调用父类的方法,即调用Decorator类的cost方法
    }
}

BlackBeanDecorator.java

//具体的装饰者类:黑豆类
public class BlackBeanDecorator extends Decorator {

    public BlackBeanDecorator(Drink drink) { //构造方法;因为父类构造方法传入了参数,所有子类构造方法要传入参数时,类型一定是和父类构造的传参构造一致
        super(drink);                        //用到继承的概念:必须显示的调用父类的构造方法,当父类的构造方法有传参时,无论子类构造有传参还是无传参
    }
    
    public float cost() {                    //重写父类的方法
        return super.cost()+2.0f;            //super.cost()表示调用父类的方法,即调用Decorator类的cost方法
    }
    
    public String description() {            //重写父类的方法
        return super.description()+"黑豆";   //super.description()表示调用父类的方法,即调用Decorator类的cost方法
    }
}

EggDecorator.java

//具体的装饰者类:鸡蛋类
public class EggDecorator extends Decorator {

    public EggDecorator(Drink drink) {    //构造方法;因为父类构造方法传入了参数,所有子类构造方法要传入参数时,类型一定是和父类构造的传参构造一致
        super(drink);                     //用到继承的概念:必须显示的调用父类的构造方法,当父类的构造方法有传参时,无论子类构造有传参还是无传参
    }
    
    public float cost() {                 //重写父类的方法
        return super.cost()+3.0f;         //super.cost()表示调用父类的方法,即调用Decorator类的cost方法
    }
    
    public String description() {         //重写父类的方法
        return super.description()+"鸡蛋"; //super.description()表示调用父类的方法,即调用Decorator类的cost方法
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        
//      OutputStream out = new FileOutputStream("xxx");
//      BufferedOutputStream bos = new BufferedOuputStream(out);
//      PrintStream ps = new PrintStream(bos);
//      ps.print(...);
        
        Drink drink = new SoyaBeanMilk();
        SugarDecorator sugar = new SugarDecorator(drink);
        EggDecorator egg = new EggDecorator(sugar);
        BlackBeanDecorator black = new BlackBeanDecorator(egg);
        
        System.out.println("你点的豆浆是:"+black.description());
        System.out.println("一共花了"+black.cost()+"元");
    }

}

你可能感兴趣的:(装饰者设计模式举例)