装饰模式

动态的给一个对象添加一些额外的职责,就增加功能呢来说,装饰模式比生成子类更加灵活。

 

装饰模式结构图

Component 是定义一个对象接口,可以给这些对象动态地添加职责,ConcreteComponent是定义了一个具体对象,也可以给这个对象添加职责,Decorator装饰抽象类,继承了Component从外类扩展Component类的功能,对于Component来说,是无需知道Decorator存在的,concreteDecoratorA和concreteDecoratorB是具体的装饰对象,给Component添加职责的,

1.案例1:

public abstract class Component {

    public abstract  void operation();


}


public class ConcreteComponent extends Component {

    @Override
    public void operation() {
        System.out.println("具体对象的操作");
    }
}


public class Decorator extends  Component {

    protected Component component;

    public  void setComponent(Component component){
        this.component = component;
    }

    @Override
    public void operation() {
        if(null != component){
            component.operation();
        }
    }
}


public class ConcreteDecoratorA  extends  Decorator{

    private String addStates;

    @Override
    public void operation() {
        super.operation();
        addStates = "ConcreteDecoratorA decorator!";
        System.out.println("具体装饰对象A的操作:"+addStates);
    }

}

public class ConcreteDecoratorB extends  Decorator {

    @Override
    public void operation() {
        super.operation();
        addedBehavior();
    }


    private void addedBehavior(){
        System.out.println("具体装饰对象B的操作...");
    }

}


public class baseTestMain {

    public static void main(String[] args) {
        ConcreteComponent concreteComponent = new ConcreteComponent();
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
        concreteDecoratorA.setComponent(concreteComponent);
        concreteDecoratorB.setComponent(concreteDecoratorA);
        concreteDecoratorB.operation();
    }
}

结果如下:

/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=51079:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/lib/tools.jar:/Users/liuxuwei/IdeaProjects/dahuadesignmodel/out/production/dahuadesignmodel decorationmodel3.baseexample.baseTestMain
具体对象的操作
具体装饰对象A的操作:ConcreteDecoratorA decorator!
具体装饰对象B的操作...

Process finished with exit code 0

 

此外,如果没有Compoment类,只有一个ConcreteComponent类,那么Decorator类就可以是ComcreteComponent的一个子类,

同样,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类了,而可以把Decorator和ConcreteComponent合并成一个类。

2.案例2:对人进行衣服装饰,采用《大话设计模式》中的案例

代码结构图如下:

代码注释:

“Person”类(ConcreteComponent)

服饰类:Finery (Decorator)

具体服饰类:BigTrouser,Suit,Tie,TShirts  (ConcreteDecorator)

public class Person {

    private String name;

    public Person(){}

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

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

}

public class Finery extends  Person {

    protected  Person component;

    //装饰
    public void decorate(Person component){
        this.component = component;
    }

    @Override
    public void show() {
        if(null != component){
            component.show();
        }
    }
}


public class BigTrouser extends  Finery {
    @Override
    public void show() {
        System.out.print("垮裤  ");
        super.show();
    }
}


public class Suit extends Finery {

    @Override
    public void show() {
        System.out.print("西服  ");
        super.show();
    }
}


public class Tie extends Finery {

    @Override
    public void show() {
        System.out.print("领带  ");
        super.show();
    }
}


public class TShirts extends Finery {

    @Override
    public void show() {
        System.out.print("big TShirts  ");
        super.show();
    }
}

public class TestMain {

    public static void main(String[] args) {
        Person xc = new Person("小王");

        System.out.println("第一种装扮:");
        TShirts tShirts = new TShirts();
        BigTrouser bigTrouser = new BigTrouser();

        tShirts.decorate(xc);
        bigTrouser.decorate(tShirts);
        bigTrouser.show();

        System.out.println("\n第二种装扮:");
        Suit suit = new Suit();
        Tie tie = new Tie();

        suit.decorate(xc);
        tie.decorate(suit);
        tie.show();
    }
}

结果如下:

第一种装扮:
垮裤  big TShirts  装扮的:小王

第二种装扮:
领带  西服  装扮的:小王

Process finished with exit code 0

总结:

装饰模式优点:把类中的装饰功能从类中移出去,简化原有的类,有效把核心职责和装饰功能区分开,而且可以去除相关类中重复逻辑。

 

 

参考:《大话设计模式》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值