我选择的是设计模式是装饰模式,采用一个穿衣服的应用范例来分析其代码结构特性。
-
定义
-
特点
-
适用性
-
缺点
-
优点
-
设计原则
-
相关区别
-
类图
ConcreteComponent(具体组件):实现抽象组件的接口。
Decorator(抽象装饰角色):一般是抽象类,持有一个被装饰者的引用,用来调用被装饰者的方法,同时可以给被装饰者增加新的职责。
ConcreteDecorator(具体装饰类):抽象装饰角色的具体实现。
-
原始代码
新建一个男人类
public class Man { public String name; public Man(String name) { this.name = name; } public void dress() { System.out.println("装扮的" + name); } public void dressTie() { System.out.println("系一条领带"); } public void dressTShirt() { System.out.println("穿一件TShirt"); } public void dressSuit() { System.out.println("穿一件西装"); }
public void dressSportShoes(){ System.out.println("穿运动鞋"); } //...... }
调用这个男人类,根据不同场合任意搭配
public static void main(String[] args) { //场合一: Man xiaoMing = new Man("小软"); xiaoMing.dressTShirt(); xiaoMing.dressTie(); xiaoMing.dressSuit(); //场合二:...... }
需要为新场合新增衣服时,改动了原来的类,违背了开闭原则,用继承的方法会令到子类的数量暴增并且可能存在大量重复代码,造成代码臃肿,最终就是难以维护。
-
装饰模式
使用场景:
1. 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
2.多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
3.产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
因此在此场景下利用装饰模式,可以有效地解决
增加一个dress方法:
public class Man { public String name; public Man(){ } public Man(String name) { this.name = name; } public void dress() { System.out.println("装扮的" + name); } }
创建一个装饰者类,命名为Finery(服饰):
public class Finery extends Man{ protected Man man; public void decorate(Man man){ this.man = man; } public void dress(){ if (man != null){ man.dress(); } } }
创建一堆具体装饰者类,它们继承自Finery:
public class TShirt extends Finery { @Override public void dress() { System.out.println("T恤衫"); super.dress(); } } public class SportShoes extends Finery { @Override public void dress() { System.out.println("运动鞋"); super.dress(); } } //......
实现:
public static void main(String[] args) { Man xiaoMing = new Man("小软"); //场合一:运动 Finery sportShoes = new SportShoes(); sportShoes.decorate(xiaoMing); //穿了运动鞋的小软 Finery tShirt = new TShirt(); tShirt.decorate(sportShoes); //穿了运动鞋的小软再穿一件T恤衫 tShirt.dress(); //装扮好了 //场合二:...... }
-
引入该设计模式后对系统架构和代码结构带来了哪些好处?
引入该设计模式后,在新增场景的情况又不需要改动原来的类,随心所欲增加任何的功能,相比继承的方法,引用该种设计模式只需要实例化对象,而并不会继承大量Man的子类,不会导致代码臃肿不宜维护。装饰模式属于结构型模式。它动态地给一个对象添加额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
-
解释其中用到的多态机制
在引入装饰模式后,创建一堆具体装饰者类,它们继承自Finery,而Finert则是继承自Man,在不同的场景下,只需要创建具体装饰类的对象,在decorate函数中每次通过参数传递赋值给父类对象man,每次装饰之后都重写dress方法,通过super(),再调用父类对象的dress()方法,通过父类对象的man.dress便可以实现装饰的需求。
-
说明模块抽象封装的方法
在装饰模式中,将需要被装饰的对象抽象成Man类,装饰器继承自Man,各种服饰类又继承自Finery。把装饰这个过程封装乘一个类,在Finery类中,对Man对象隐藏,通过装饰方法decorate对其进行修改。