设计模式之装饰模式(Decorator)

1、 装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。

2、组合和继承的区别

继承。继承是给一个类添加行为的比较有效的途径。通过使用继承,可以使得子类在拥有自身方法的同时,还可以拥有父类的方法。但是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制增加行为的方式和时机。

组合。组合即将一个对象嵌入到另一个对象中,由另一个对象来决定是否引用该对象来扩展自己的行为。这是一种动态的方式,我们可以在应用程序中动态的控制。

与继承相比,组合关系的优势就在于不会破坏类的封装性,且具有较好的松耦合性,可以使系统更加容易维护。但是它的缺点就在于要创建比继承更多的对象。

3、装饰者模式的优缺点

优点

1、装饰者模式可以提供比继承更多的灵活性

2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点

1、会产生很多的小对象,增加了系统的复杂性

2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

4、装饰者的使用场景

  1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

  2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。  当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

以上内容来自网络

5、UML图(Astah/jude)下载地址:http://pan.baidu.com/s/1eQiVePc

6、示例:

装饰者基类

 1 package com.xinye.test.decoration;
 2 /**
 3  * 食物基类
 4  * @author xinye
 5  *
 6  */
 7 public abstract class Food {
 8
 9     protected String desc;
10
11     public abstract String getDesc();
12 }

鸡肉

 1 package com.xinye.test.decoration;
 2 /**
 3  * 鸡肉
 4  * @author xinye
 5  *
 6  */
 7 public class Chicken extends Food {
 8     public Chicken(){
 9         desc = "鸡肉";
10     }
11     @Override
12     public String getDesc() {
13         return desc;
14     }
15
16 }

鸭肉

 1 package com.xinye.test.decoration;
 2 /**
 3  * 鸭肉
 4  * @author xinye
 5  *
 6  */
 7 public class Duck extends Food {
 8     public Duck(){
 9         desc = "鸭肉";
10     }
11     @Override
12     public String getDesc() {
13         return desc;
14     }
15
16 }

装饰者基类

 1 package com.xinye.test.decoration;
 2 /**
 3  *
 4  * @author xinye
 5  *
 6  */
 7 public abstract class FoodDecoration extends Food {
 8
 9     @Override
10     public abstract String getDesc();
11
12 }

蒸-装饰者

 1 package com.xinye.test.decoration;
 2 /**
 3  * 蒸食物
 4  * @author xinye
 5  *
 6  */
 7 public class SteamedFood extends FoodDecoration {
 8
 9     private Food food;
10
11     public SteamedFood(Food f){
12         this.food = f;
13     }
14
15     @Override
16     public String getDesc() {
17         return getDecoration() + food.getDesc();
18     }
19
20     private String getDecoration(){
21         return "蒸";
22     }
23 }

烤-装饰者

 1 package com.xinye.test.decoration;
 2 /**
 3  * 烤食物
 4  * @author xinye
 5  *
 6  */
 7 public class RoastFood extends FoodDecoration {
 8
 9     private Food food;
10
11     public RoastFood(Food f){
12         this.food = f;
13     }
14
15     @Override
16     public String getDesc() {
17         return getDecoration() + food.getDesc();
18     }
19
20     private String getDecoration(){
21         return "烤";
22     }
23 }

客户端

 1 package com.xinye.test.decoration;
 2 /**
 3  * 客户端
 4  * @author xinye
 5  *
 6  */
 7 public class Client {
 8     public static void main(String[] args) {
 9         // 测试单纯的食物
10         Food f1 = new Chicken();
11         System.out.println(f1.getDesc());
12
13         System.out.println("----------------------");
14         // 测试单重修饰的食物
15         RoastFood rf = new RoastFood(f1);
16         System.out.println(rf.getDesc());
17
18         System.out.println("----------------------");
19         // 测试多重修饰的食物
20         SteamedFood sf = new SteamedFood(rf);
21         System.out.println(sf.getDesc());
22     }
23 }

执行结果: 鸡肉 ---------------------- 烤鸡肉 ---------------------- 蒸烤鸡肉

时间: 2024-10-06 09:37:17

设计模式之装饰模式(Decorator)的相关文章

设计模式 笔记 装饰模式 Decorator

//---------------------------15/04/17---------------------------- //Decorator 装饰模式----对象结构型模式 /* 1:意图: 动态地给一个对象添加额外的职业,就增加功能来说,Decorator模式相比生成子类更为灵活. 2:别名: 包装器(Wrapper) 3:动机: 4:适用性: 1>在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责. 2>处理那些可以撤销的职责. 3>当不能采用生成子类的方法

【设计模式】—— 装饰模式Decorator

前言:[模式总览]——————————by xingoo 模式意图 在不改变原来类的情况下,进行扩展. 动态的给对象增加一个业务功能,就功能来说,比生成子类更方便. 应用场景 1 在不生成子类的情况下,为对象动态的添加某些操作. 2 处理一些可以撤销的职责. 3 当不能使用生成子类来扩充时. 模式结构 Component 外部接口,用于定义外部调用的形式.提供默认的处理方法. interface Component{ public void operation(); } ConcreteComp

设计模式之装饰模式 Decorator

代码实现 public interface ICar { void move(); } 抽象构建角色 //具体构件角色(真实对象,被装饰角色) class Car implements ICar{ @Override public void move() { System.out.println("陆地上跑"); } } 具体构建角色 //装饰角色 class SuperCar implements ICar{ private ICar car; public SuperCar(ICa

JAVA设计模式之 装饰模式【Decorator Pattern】

一.概述 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活.装饰模式是一种对象结构型模式.装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系.在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能. 二.适用场景 装饰原有对象.在不改变原有对象的情况下扩展增强新功能/新特征..当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式. 三.UML类图 四

设计模式--装饰模式(Decorator)

装饰模式(Decorator) : 动态的给一个对象加入一些额外的职能,就添加功能来说,装饰模式比生成子类更为灵活. 实例: ConcreteComponent:让Decorator对象为自己加入功能.有时候使用ConcreteComponent的派生类提供核心功能.在这样的情况就是用ConcreteComponent替代了Component的功能,并且装饰者是继承于ConcreteComponent的子类. Component:定义ConcreteComponent和Decorator类要实现

设计模式之装饰模式20170726

结构型设计模式之装饰模式: 一.含义 动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活. 通俗来讲,装饰模式是对类的功能进行加强或减弱. 二.代码说明 1.主要有两个角色 1)构件 最核心.最原始.最基本的对象,也就是要装饰的对象. 2)装饰角色 把最核心.最原始.最基本的东西装饰成其他东西 2.在用C实现过程中也是参考这种思想,以修饰成绩单举例,具体实现如下: 1)装饰模式使用场景: 1 /***********************************

设计模式之装饰模式 c++实现和详细分析

Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案. 它使功能具有动态性 已经开发完毕的对象,后期由于业务需要,对旧的对象需要扩展特别多的功能,这时候使用给对象动态地添加新的状态或者行为(即装饰模式)方法,而不是使用子类静态继承. 引入装饰模式的原因  : 由于若有很多个功能,这么多功能 可能会出现各种组合,而每个组合都要对应一个类,这是指数级的类的数量增长(因为我们要扩展不应直接修改类,所以采取继承 而不是改变原有类)  

【设计模式】——装饰模式

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 装饰模式结构图: Component是定义一个对象接口,可以给这些对象动态地添加职责.ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责.Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的.至于ConcreteDecorator就是具体

设计模式笔记——装饰模式

装饰模式 装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 1.装饰模式的特点 (1)装饰对象和真实对象有相同的接口.这样客户端对象就能以和真实对象相同的方式和装饰对象交互. (2)装饰对象包含一个真实对象的引用(reference) (3)装饰对象接受所有来自客户端的请求.它把这些请求转发给真实的对象. (4)装饰对象可以在转发这些请求以前或以后增加一些附加功能.这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功

学习大话设计模式06_装饰模式

装饰模式(Decorator): 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 1 /** 2 * Component 是定义一个对象接口,可以给这些对象动态地添加职责 3 * @author Monica 4 * 5 */ 6 public abstract class Component { 7 public abstract void Operation(); 8 } 9 10 11 /** 12 * ConcreteComponent 是定义了一个具体