设计模式-1.11装饰模式

装饰模式:

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

   装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。

实例:

  比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。下面给出装饰模式的UML图。

在这种设计中,手机的装饰功能被独立出来,可以单独发展,进而简化了具体手机类的设计。下面给出Phone类的实现:

 1 //公共抽象类
 2 class Phone
 3 {
 4 public:
 5     Phone() {}
 6     virtual ~Phone() {}
 7     virtual void ShowDecorate() {}
 8 };
 9
10 //具体的手机类
11 class iPhone : public Phone
12 {
13 private:
14     char * m_name; //手机名称
15 public:
16     iPhone(char* name): m_name(name){}
17     ~iPhone() {}
18     void ShowDecorate()
19     {
20         cout<<m_name<<"的装饰"<<endl;
21     }
22 };
23
24 //具体的手机类
25 class NokiaPhone : public Phone
26 {
27 private:
28     char* m_name;
29 public:
30     NokiaPhone(char* name): m_name(name){}
31     ~NokiaPhone() {}
32     void ShowDecorate()
33     {
34         cout<<m_name<<"的装饰"<<endl;
35     }
36 };
 1 //装饰类
 2 class DecoratorPhone : public Phone
 3 {
 4 private:
 5     Phone *m_phone;  //要装饰的手机
 6 public:
 7     DecoratorPhone(Phone *phone): m_phone(phone) {}
 8     virtual void ShowDecorate()
 9     {
10         m_phone->ShowDecorate();
11     }
12 };
13
14 //具体的装饰类
15 class DecoratorPhoneA : public DecoratorPhone
16 {
17 public:
18     DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}
19     //此处体现了顺序,可以在这里修改顺序,AddDecorate(); DecoratorPhone::ShowDecorate();
20     void ShowDecorate()
21     {
22         DecoratorPhone::ShowDecorate();
23         AddDecorate();
24     }
25
26 private:
27     void AddDecorate() { cout<<"增加挂件"<<endl; } //增加的装饰
28 };
29
30 //具体的装饰类
31 class DecoratorPhoneB : public DecoratorPhone
32 {
33 public:
34     DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}
35     //此处体现了顺序,可以在这里修改顺序,AddDecorate(); DecoratorPhone
36     void ShowDecorate()
37     {
38         DecoratorPhone::ShowDecorate();
39         AddDecorate();
40     }
41
42 private:
43     void AddDecorate() { cout<<"屏幕贴膜"<<endl; } //增加的装饰
44 };
 1 // 装饰模式.cpp : Defines the entry point for the console application.
 2 //
 3
 4 #include "stdafx.h"
 5 #include <STDIO.H>
 6 #include <STRING.H>
 7 #include <IOSTREAM>
 8 using namespace std;
 9 int main(int argc, char* argv[])
10 {
11     Phone *phone = new iPhone("IPhone");//使用指针类型,形参不会成才新的实例对象
12     DecoratorPhone *dpa = new DecoratorPhoneA(phone);//体现选择性,选择需要的装饰
13     DecoratorPhone *dpb = new DecoratorPhoneB(dpa);//选择需要的装饰
14     phone->ShowDecorate();
15     //IPhone的装饰
16     cout<<endl;
17     dpa->ShowDecorate();
18     //IPhone的装饰
19     //增加挂件
20     cout<<endl;
21     dpb->ShowDecorate();
22     //IPhone的装饰
23     //增加挂件
24     //屏幕贴膜
25     return 0;
26 }

使用场景:

  当系统需要新功能的时候,是想旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为,这种做法的问题在于,在主类中加入了新的字段、新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地按顺序地使用装饰功能包装对象。

优点:

  把类中的装饰功能从类中搬移去除,有效地把类的核心职责和装饰功能区分开来,而且可以去除相关类中重复的装饰逻辑,这也可以简化原有的类。

时间: 2024-08-28 19:12:51

设计模式-1.11装饰模式的相关文章

设计模式(11)--代理模式之RMI

(1)确定变量和返回值是属于原语(primitive)类型或者可序列化的(Seriailizable)类型.原语类型 都实现了Seriailizable接口. (2)transient  关键字,告诉JVM不要序列化这个字段. 动态类下载(dynamic class downloading ) 代理模式 :控制对象的访问 代理模式有很多种.如:远程代理,虚拟代理.动态代理(保护代理) 客户调用本地的方法,本地的方法调用远程的方法. 本地方法就是"代理"."代理"处理

设计模式学习之装饰模式:IO流的装饰器

IO流的装饰器 题目分析:通过对java的io系列类分析得知,java的io流使用了设计模式中的装饰模式,以动态的给一个对象增加职责,能够更加灵活的增加功能.通过看io的源代码得知FilterOutputStream类继承了OutputStream类并拥有父类的一个对象,它和父类具有组合聚合的关系.因此要实现我们自己的加密类只需扩展FilterOutputStream类重写它的wite方法即可 UML图: 源代码: package com.cmc import java.io.FilterOut

JAVA设计模式(11):结构型-装饰模式(Decorator)

职责: 动态的为一个对象增加新的功能. 装饰模式是一种用于代替继承的技术,无须通过继承增加之类就能扩展对象的新功能. 使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀. 实现细节: Componment抽象构件角色 真实对象和装饰对象有相同的接口.这样,客户端对象能够以真实对象相同的方式同装饰对象交互. ConcreteComponment具体构件角色(真实对象) io流中的FileInputStream.FileOutStream Decorator装饰角色: 持有一个抽象

《Java设计模式》之装饰模式

装饰模式(Decorator) 1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式.装饰模式以对client透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.    装饰模式以对client透明的方式动态的给一个对象附加上很多其它的责任.换言之client并不会觉的对象在装饰前和装饰后有什么差别. 3.    装饰模式能够在不创造很多其它的子类的模式下,将对象的功能加以扩展. 4.    装饰模式与类继承的差别: 1)    装饰模式是一种动态行为,对已经存

我所理解的设计模式之Java装饰模式

快要毕业了,之前学习的设计模式没有想到这么重要,马马虎虎就应付过去了,现在重新学习一下. 在这里写一下自己所理解的装饰模式,语言不多,看代码吧-- ? 1 2 3 4 5 6 7 8 9 10 11 12 13 package decorator; /**  * User.java  * 定义一个接口,规定好一个方法,以后所有的类都去实现或重写这个方法  * @author sztsiang  *  */ public interface User {     void show(); } ?

《java与设计模式》之装饰模式详解&amp;Java IO中的装饰器模式

1 概述 在一个项目中,你会有非常多的因素考虑不到,特别是业务的变更,不时的冒出一个需求是很正常的情况.有三个继承关系的类:Father.Son.GrandSon,我们要在Son类上增强一些功能怎么办?给Son类增加方法吗?那对GrandSon的影响呢?特别是对GrandSon有多个的情况,你会怎么办?认真看完本文,你会找到你的答案. JavaIO中,像下面的嵌套语句是不是很常见,为什么要怎样定义呢?理解装饰模式后,你会找到答案. DataInputStream in = new DataInp

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

装饰模式: 动态地给对象添加一些相关的职责.装饰模式相比与添加子类提供了一种更加灵活的方式. UML图如下所示: 感觉上图中关键的有这几点: Decorator与Component的聚合关系(即Decorator中存在一个Component类型的引用),由于这个聚合关系的存在,Decorator可以通过一个Component的引用调用Component的接口 Decorator与Component的继承关系,这个关系不是很容易理解.但是在这里联想到继承的里氏代换原则(父类出现的地方都可以替换成子

设计模式笔记4 装饰模式

1.1 定义 动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活. 1.2 类图 1.3 代码 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 装饰模式 8 { 9 class Person 10 { 11 private string n

大话设计模式C++版——装饰模式

女人常说男人喜新厌旧,只见新人笑,那闻旧人哭,但装饰模式(Decorator)却是一种结交新朋友不忘老朋友的设计模式,非常适合去古代当老公(现代是不行的,因为只能娶一个老婆了).装饰模式的本质是每一个装饰对象都被保留一个被其装饰的对象,装饰对象在展示新功能时会同时去调用被其装饰的对象的同功能函数,通过如此层层包含调用(即装饰),形成一个类似链表的结构,接下来的介绍中,我们还会看到更多的类似链表结构的设计模式,比如职责链模式.状态模式. 仍以<大话设计模式>一书中装饰模式的小菜穿衣的例子为例,来