zoukankan      html  css  js  c++  java
  • 装饰者模式【java版】

    一、基本结构

    1.层次一:原始抽象类

       抽象类:Cake

    abstract class Cake {
    protected String description="Unknown Cake";

    public abstract void printDescription();//抽象方法必须指定为abstract类型

    }

    2.层次二:具体实现者、装饰者抽象类

      具体实现者1:WhiteCake

    public class WhiteCake extends Cake {

    public WhiteCake() {
    description="WhiteCake";
    }

    @Override
    public void printDescription() {

    System.out.println("制作最简单的蛋糕,蛋糕名为:"+description.toString());
    }

    }

      具体实现者2:YellowCake

    public class YellowCake extends Cake{
    public YellowCake() {
    description="YellowCake";
    }

    @Override
    public void printDescription() {

    System.out.println("制作最简单的蛋糕,蛋糕名为:"+description.toString());
    }

    }

      装饰者抽象类:CakeDecorator

    public abstract class CakeDecorator extends Cake {

    @Override
    public abstract void printDescription();

    }

    说明之所以要定义一个并未进行任何实现的“装饰者抽象类”,是由于:如果装饰类,

       直接实现接口并添加装饰,则会表现为“基本实现类”和“装饰类”位于同一层上,显然

       不符合大家通常的理解习惯。

             此种设计思想可参照java I/O类图。

    3.层次三:具体装饰者

      具体装饰者A:MilkCake

    public class MilkCake extends CakeDecorator {

    Cake cake;

    public MilkCake(Cake cake) {
    this.cake=cake;
    }

    @Override
    public void printDescription() {
    this.cake.printDescription();
    addMilk();
    }

    private void addMilk(){//新增加的装饰性的方法
    System.out.println("添加装饰A:Milk");
    }
    }

      具体装饰者B:ChocolateCake

    public class ChocolateCake extends CakeDecorator {

    Cake cake;

    public ChocolateCake(Cake cake) {
    this.cake=cake;
    }

    @Override
    public void printDescription() {
    this.cake.printDescription();
    addChocolate();
    }

    private void addChocolate(){//新增加的装饰性的方法
    System.out.println("添加装饰B:Chocolate");
    }
    }

      具体装饰者C:FruitCake

    public class FruitCake extends CakeDecorator {

    Cake cake;

    public FruitCake(Cake cake) {
    this.cake=cake;
    }

    @Override
    public void printDescription() {
    this.cake.printDescription();
    addFruit();

    }

    private void addFruit(){//新增加的装饰性的方法
    System.out.println("添加装饰C: Fruit");
    }
    }


    二、测试

        测试代码:

    public class Main {

    public static void main(String[] args) {
    System.out.println("开始测试装饰者模式。。。");

    Cake theCake=new WhiteCake();

    //测试“被装饰者”
    theCake.printDescription();
    System.out.println("");

    //测试单重“装饰者”
    CakeDecorator theSingleCakeDecorator=new MilkCake(theCake);
    theSingleCakeDecorator.printDescription();
    System.out.println("");

    //测试多重“装饰者”
    CakeDecorator theMultiCakeDecorator=new FruitCake(new ChocolateCake(new MilkCake(theCake)));
    theMultiCakeDecorator.printDescription();
    System.out.println("");
    }

    }

        运行结果:

       说明:如何体现动态加载,而不是在编译阶段就确定好实例的所有特征?

            凡是new出实例都是在“运行阶段”进行的,假如有三个装饰物: 装饰物A,装饰物B, 装饰物C
           装饰者模式:三个装饰者类,使用时任意组合,可以有A,B,C,AB,AC,BC,ABC共7种组合。
           传统继承的方式:三个装饰者类,使用时实例化子类,只有A,B,C三种组合,而且在编译

                      阶段就规定要了可能的所有组合方式,要达到前面的效果,就必须有七个装饰者类
           最显著的区别:装饰者模式只需定义好几个基本装饰元素,最终的装饰结果由这些“装饰元素”

                      在运行期任意组合。


     

            

  • 相关阅读:
    Android使用注解代替枚举从而节省系统使用的内存开销
    android9.0系统适配遇到的问题
    android 图片上传图片 报Socket: Broken pipe
    android H5支付 网络环境未能通过安全验证,请稍后再试
    Error:Execution failed for task ':app:processDebugManifest'. Manifest merger failed with multiple errors, see logs
    NightWatch端到端测试
    JavaScript生成斐波那契数列
    Vue Material
    Jasmine
    Postman
  • 原文地址:https://www.cnblogs.com/edisonfeng/p/2300817.html
Copyright © 2011-2022 走看看