第 6 章 —— 装饰模式

6.6 装扮模式总结

    装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

    装扮模式是为已有功能动态地添加更多功能的一种方式。

  装饰模式的优点:

    有效地把类的核心职责和装饰功能区分开了(将装饰功能从类中移除,简化了原有的类)。而且可以去除相关类中重复的装饰逻辑(具体的装饰类都继承了抽象装饰类)。

  需要注意的问题:

    装饰模式的顺序很重要,比如加密数据和过滤词汇都可以是数据持久化(存储)以前的装饰功能,但若先加密了数据再用过滤功能就会出问题了,最理想的情况,是保证装饰类之间彼此独立,这样它们就可以以任意的顺序进行组合了。

6.4 装饰模式

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

基本的实现代码:

  Component 类:

      abstract class Component{public abstract void Operation();}

    Component 定义了一个对象接口(抽象类的抽象方法),可以给这些对象动态地添加职责。

  ConcreteComponent 类:

      class ConcreteComponent : Component{public override void Operation(){Console.WriteLine("具体对象的操作");}}

    ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。

  Decorator 类:(抽象的装饰类,需要继承定义的对象接口)

      abstract class Decorator : Component{protected Component component;public void SetComponent(Component component)       //设置Component
          {this.component = component;}public override void Operation()                    //重写Operation(),实际执行的是Component的Operation()
          {if(component != null){component.Operation();}}}

    Decorator,抽象装饰类,继承了 Component,从类外面来扩展 Component 类的功能,但对于 Component 来说,是无需知道 Decorator 的存在的

  具体的装饰类:

      class ConcreteDecoratorA : Decorator{private string addedState;          //本类的独有功能,以区别于ConcreteDecoratorBpublic override void Operation(){base.Operation();       //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰addedState = "New State";Console.WriteLine("具体装饰对象A的操作");}}class ConcreteDecoratorB : Decorator{public override void Operation(){base.Operation();       //首先运行原Component的Operation(),再执行本类的功能,AddBehavitor(),相当于对原Component进行了装饰
              AddBehavitor();Console.WriteLine("具体装饰对象A的操作");}private void AddBehavitor()         //本类独有的方法,以区别于ConcreteDecoratorA
          {}}

  客户端代码:

        static void Main(string[] args){ConcreteComponent c = new ConcreteComponent();ConcreteDecoratorA d1 = new ConcreteDecoratorA();ConcreteDecoratorB d2 = new ConcreteDecoratorB();d1.SetComponent(c);d2.SetComponent(d1);d2.Operation();         //装饰的方法是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()
Console.Read();}

6.5 装饰模式的实际应用

  “Person” 类(ConcreteComponent)

      class Person{public Person(){ }private string name;public Person(string name){this.name = name;}public virtual void Show(){Console.WriteLine("装扮的{0}", name);}}

  服饰类(Decorator)

      class Finery : Person{protected Person component;//打扮public void Decorate(Person component){this.component = component;}public override void Show(){if(component != null){component.Show();}}}

  具体服饰类(ConcreteDecorator)

    class TShirts : Finery{public override void Show(){Console.WriteLine("大T恤 ");base.Show();}}class BigTrouser : Finery{public override void Show(){Console.WriteLine("垮裤 ");base.Show();}}

  客户端代码

        static void Main(string[] args){Person xc = new Person("小菜");Console.WriteLine("\n第一种装扮:");BigTrouser kk = new BigTrouser();       //垮裤TShirts dtx = new TShirts();            //大T恤
kk.Decorate(xc);            //装扮过程
            dtx.Decorate(kk);dtx.Show();Console.Read();}

 

转载于:https://www.cnblogs.com/zhangchaoran/p/8538062.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453328.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

广义表及其存储方式简介

广义表(Lists,又称列表)是线性表的推广。线性表定义为n>0个元素a1,a2,a3,…,an的有限序列。线性表的元素仅限于原子项,原子是作为结构上不可分割的成分,它可以是一个数或一个结构,若放松对表元素的这种限…

Vue.js:路由

ylbtech-Vue.js:路由1.返回顶部 1、Vue.js 路由 本章节我们将为大家介绍 Vue.js 路由。 Vue.js 路由允许我们通过不同的 URL 访问不同的内容。 通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)。 Vue.…

图片转excel:“保留数字格式”在什么场景下该勾

保留数字格式是什么意思呢?顾名思义,就是将转出来的数字保留为数字格式,而不是文本格式。我们知道,OCR程序将图片上的文字识别为电脑可编辑的文字后,如果导入到excel不加处理,则单个数字过长的文字就会被ex…

html概述和基本结构

html概述 HTML是 HyperText Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制作网页的语言,这种语言由一个个的标签组成,用这种语言制作的文件保存的是…

linux添加三权,基于SELinux的三权分离技术的研究

目前,Linux操作系统已广泛应用于各种设备和产品中,如服务器、PC机、机顶盒及路由器等。随着Linux系统的不断发展和广泛应用,Linux系统的安全问题也引起越来越多的关注。在Linux操作系统中,存在一个超级用户即root用户。root也称为…

二叉树、树和有序树的区别

树:子树没有左右之分 二叉树、有序树:左右有序 二叉树与有序树:在只有一棵树的情况下,二叉树有左右之分、有序树无左右之分 另外:二叉树是有序的,可以为空或一个根节点以及两个分别称为左子树和右子树的互不相交的二叉…

高效程序员

软件开发人员的作战手册 - 让程序员活的久一点 1. 程序员的职业准则是:诚实(如实的报告你的状态,风险和出现的问题),守信(承诺完成的任务就要按时完成),尊重(尊重给你的代…

PHP学习笔记1

1.什么是PHP? Hypertext Preprocessor(超文本预处理语言)。 是脚本语言。 是最流行的网站开发语言。 2.PHP能做什么? 可以生成动态页面内容。 可以创建、打开、读取、写入、关闭服务器上的文件。 可以手机表单数据。 可以发送和接收cookies。&#xf…

Redis在windows下的配置

原文:Redis在windows下的配置 Redis在windows下的配置(在windows-64下安装redis,请参考微软redis的github:https://github.com/MSOpenTech/redis/releases)下面是windows32的配置 下载地址http://files.cnblogs.com/files/cuiweny…

linux磁盘符变化autofs,Linux基础教程学习笔记之Autofs自动挂载

Linux基础教程学习笔记之Autofs自动挂载Autofs自动挂载:yum -y install autofsvim /etc/auto.master 在文件中添加下面行/home/guests /etc/auto.tianyunvim /etc/auto.tianyun 子挂载点监控ldapuser0 -rw,sync classroom:/home/guests/ldapuser0systemctl enable …

二叉树的递归遍历(先序,中序,后序)

#include "stdio.h" #include "malloc.h" #define M 100 typedef struct node { /* 采用二叉链表存储结构 */char data;struct node *lchild,*rchild; }BTnode; BTnode *create()/*利用先序遍历的过程创建二叉树*/ {BTnode *t;char ch;scanf("%c&quo…

DOM-动态操作心得

这个知识点都是之前看过的,就当是复习了 一、创建元素的三种方法 第一种: document.write() 识别标签但会覆盖之前内容第二种: 用元素自身的innerHTML方法 不识别标签但可以不覆盖之前内容 ul.innerHTML "<li></li>"; 第三种:利用DOM自身api创建元素 …

linux探索之旅pdf,【Linux探索之旅】第四部分第一課:壓縮文件,解壓無壓力

內容簡介1、第四部分第一課&#xff1a;壓縮文件&#xff0c;解壓無壓力2、第四部分第二課&#xff1a;SSH連接&#xff0c;安全快捷壓縮文件&#xff0c;解壓無壓力最近小編因為換工作&#xff0c;從南法搬到巴黎。折騰了很久。網絡一直用的是公共的無線網&#xff0c;信號不行…

遍历二叉树的全部方法(递归+非递归)

#include<iostream> #include<queue> #include<stack> using namespace std; //二叉树结点的描述 typedef struct BiTNode { char data; struct BiTNode *lchild, *rchild; //左右孩子 }BiTNode,*BiTree; //按先序遍…

如何在本地搭建一个Android应用crashing跟踪系统-ACRA

https://github.com/bboyfeiyu/android-tech-frontier/tree/master/others/%E5%A6%82%E4%BD%95%E5%9C%A8%E6%9C%AC%E5%9C%B0%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AAAndroid%E5%BA%94%E7%94%A8crashing%E8%B7%9F%E8%B8%AA%E7%B3%BB%E7%BB%9F%EF%BC%8DACRA 如何在本地搭建一个Andr…

20165222第一周查漏补缺

一&#xff0c;第一章要点总结 1&#xff0c;java的特点&#xff1a;面向对象&#xff0c;动态&#xff0c;平台无关。 2&#xff0c;对于带包程序的编译&#xff1a;注意javac -d 编译到一个文件夹内&#xff0c;然后java -cp 文件夹名 包名.类名。 第一章是比较简单的&#x…

学习中的十七条建议

作者&#xff1a;孤剑 对于一个自学的人来说&#xff0c;几条规则当然是必要的了&#xff0c;以下是我自己的一些心得。 1。自信是你成功的第一要素&#xff1b; 2。用心去学&#xff0c;活学活用&#xff1b; 3。新手不要“好高骛远”&#xff0c;老手不要“骄傲自大”&#x…

tp5 linux路由不跳转,thinkphp5路由不生效一直跳到首页的解决方法

自从用laravel框架后&#xff0c;好久没用过thinkphp框架了&#xff0c;早期用的3.x系列&#xff0c;想熟悉一下thinkphp5&#xff0c;结果入坑了&#xff1b;路由配置一直不起作用&#xff0c;总是跳到首页&#xff0c;折腾了好久&#xff0c;后来发现是nginx配置的问题&#…

stack堆栈简介

stack堆栈简介 堆栈是一个线性表&#xff0c;插入和删除只在表的一端进行。这一端称为栈顶(Stack Top)&#xff0c;另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈&#xff0c;元素的删除称为出栈。由于元素的入栈和出栈总在栈顶进行&#xff0c;因此&#xff0c;堆栈是…

一份从 0 到 1 的 Java 项目实践清单

2019独角兽企业重金招聘Python工程师标准>>> 看了一篇文章&#xff0c;感觉还可以&#xff0c;就给大家共享一下&#xff1a; 对于着手一个项目的时候&#xff0c;要从以下入手&#xff08;即项目清单&#xff09;&#xff1a; 1. 项目规划 1.1 首先&#xff0c;你得…