继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

设计模式之装饰模式

芜湖不芜
关注TA
已关注
手记 511
粉丝 77
获赞 339

装饰模式(Decorator):

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

 

 

 (再来一波生硬的概念...)"Component"是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到个Component添加职责的功能。

 

案例走起

  现在公司有很多钢笔,纸张和书本,笔记本电脑等等...有桌子和书柜等...这些东西放在哪里完全由你决定...例如桌子,开始是个空桌子,用什么来"修饰"呢?我可以放钢笔也可以放纸张...接下来看看怎么实现的把!

    

 

 

 

1.根据上面的uml图,首先我们来创建家具()把,赋予它放置东西的能力(行为)

复制代码

 1 package component; 2  3 /** 4  * 家具 5  * @author DeepSleeping 6  * 7  */ 8 public interface Furniture { 9 10     /**11      * 放置物品12      */13     void place();14 }

复制代码

2.接下来我们创建具体被修饰类(这里我就创建桌子table把)

 

复制代码

 1 package component.concreteComponent; 2  3 import component.Furniture; 4  5 /** 6  * 具体被装饰类 7  * 桌子 8  * @author DeepSleeping 9  *10  */11 public class Table implements Furniture{12 13     @Override14     public void place() {15         System.out.println("桌子...");16     }17 18 }

复制代码

 

3.然后就是创建抽象修饰类把

 

复制代码

 1 package decoration; 2  3 import component.Furniture; 4  5 /** 6  * 装饰抽象类 7  * @author DeepSleeping 8  * 9  */10 public class Decorator implements Furniture{11 12     //持有被装饰类的引用13     Furniture furniture;14     15     //通过构造方法传入被装饰类16     public Decorator(Furniture furniture){17         18         this.furniture = furniture;19     }20     21     22     @Override23     public void place() {24         //调用被装饰类的方法25         furniture.place();26     }27 28 }

复制代码

 

4.抽象修饰类下面自然是那些用来修饰具体被修饰类(桌子、书柜...)的具体修饰类(钢笔,纸张...)

 

复制代码

 1 package decoration.concreteDecoration; 2  3 import component.Furniture; 4 import decoration.Decorator; 5  6 /** 7  * 具体修饰类(纸张) 8  * @author DeepSleeping 9  *10  */11 public class Paper extends Decorator{12 13     /**14      * 因为父类Decorator中写了有参构造方法,所以无参构造方法就会没有了15      * 子类继承父类会默认实现父类的无参构造方法,现在必须得手动实现父类中的有参构造方法...16      * 这样就把被装饰类传进来了...17      * @param furniture18      */19     public Paper(Furniture furniture) {20         super(furniture);21         22     }23 24     /**25      * 修饰26      */27     @Override28     public void place() {29         super.place();30         //添加自己对应的修饰内容31         System.out.print("放置了一张纸...\t");32     }33     34 35 }

复制代码

 

复制代码

 1 package decoration.concreteDecoration; 2  3 import component.Furniture; 4 import decoration.Decorator; 5  6 /** 7  * 具体修饰类(钢笔) 8  * @author DeepSleeping 9  *10  */11 public class Pen extends Decorator {12 13     Furniture furniture;14     15     public Pen(Furniture furniture) {16         super(furniture);17     }18 19     @Override20     public void place() {21         super.place();22         System.out.println("放置了一支钢笔...");23     }24 }

复制代码

5.好了,接下来就是测试了...

 

复制代码

 1 package test; 2  3 import component.Furniture; 4 import component.concreteComponent.Table; 5 import decoration.concreteDecoration.Paper; 6 import decoration.concreteDecoration.Pen; 7  8  9 public class TestDecorator {10 11     public static void main(String[] args) {12         //实例化被装饰类的对象13         Furniture table = new Table();14         15         System.out.println("******************领导A:放一张纸到桌子上...******************");16         table = new Paper(table);    
17         table.place();18         19         System.out.println();20         //再放一支钢笔在桌子上21         System.out.println("******************领导B:放一支钢笔到桌子上...******************");22         table = new Pen(table);23         table.place();24         25         System.out.println();26         System.out.println("******************领导C:放4支钢笔和一张纸到桌子上...******************");27         //再放4支钢笔和一张纸在桌子上28         table = new Pen(new Pen(new Pen(new Pen(new Paper(table)))));29         table.place();30     }31 }

复制代码

 

6.运行结果...

 小结:

    从上述代码中很明显可以看的出来,首先是一个空的桌子我们可以用钢笔或者纸张等来"修饰"这个桌子..

    如果需要拓展,可以继续写书柜,然后添加 书,各种修饰,书柜中想放什么动态添加就是了,非常的方便,如果有新的东西比如运来了一批海鲜,添加个海鲜类就好了,至于想放在书柜上还是书桌上由你自己来定

       不需要去修改之前的代码。

    一个软件肯定会有需求的变更拓展,这时候只要增加那些"修饰"就可以了,这里就是"开闭原则"的良好体现把!

    "开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可拓展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的哪些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。"

  

学习心得:

  学习设计模式以及了解与设计有关的东西或者看看源码,对自己的思想有了一些启发把,还是挺有作用的,学习应该心平气和脚踏实地。

  不过目前呢给我的感觉还是"干嘛这么麻烦...就那样放一起不就好了,有改变的话改下代码就好了",不过在学习中,发现,到处都在强调"开闭"等,拓展性啥的。。

  基础!基础!基础!基础真的很重要!之前看代理模式完全看不懂,去补了一下多态,这里我觉得又是很好的利用了多态来进行"通信"

      多态,反射,注解,各种,还有多线程啊好多好多需要去学习和巩固深入的,漫漫长路共勉吧!

 

 

装饰模式在JAVA中的IO流就是很好的例子...):

具体的例子以及前辈运用装饰模式自定义IO流的demo在下面的参考博客中有体现...

本文参考

博客:https://blog.csdn.net/android_zyf/article/details/68343953

书籍:《大话设计模式》

 

原文出处:https://www.cnblogs.com/deepSleeping/p/9695809.html  

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP