惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
Engineering at Meta
Engineering at Meta
C
Cisco Blogs
H
Heimdal Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Securelist
N
Netflix TechBlog - Medium
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Exploit Database - CXSecurity.com
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Project Zero
Project Zero
Spread Privacy
Spread Privacy
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
T
Threatpost
The Hacker News
The Hacker News
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
Latest news
Latest news
P
Privacy International News Feed
T
Tenable Blog
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
NISL@THU
NISL@THU
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
The Cloudflare Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
K
Kaspersky official blog
小众软件
小众软件
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Know Your Adversary
Know Your Adversary
B
Blog RSS Feed
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
N
News | PayPal Newsroom
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
About on SuperTechFans
V
Visual Studio Blog

博客园 - 陋室

成功与一截树枝 sql 操作全集-整理收藏 JavaScript使用技巧精萃(转载) ASP.NET 中在指定的位置处插入字符 提示按下大写键的控件:MQTool(提供下载) 如何在mail的正文显示图片 微软AJAX 教学系列第一讲:ScriptManager控件 微软AJAX 教学系列第一讲:局部刷新Partial Page Updates(翻译) 李开复:21世纪最需要的7种人才 Building a File Service 超卓越的你_读完后让你恢复自信 how to write professional business letters? 到底什么是托管,什么是非托管的研究 数据库设计中的五个范式(本文转载,收藏下) 如何直接用XML做数据源? ASP.NET程序的优化建议<转> ASP.NET部署与安装_MSI制作图文教程. 在打包的时候,创建应用程序池,并自动将程序assign到新创建的池中(MSI制作) Understand SQL Cache Notifications
NET设计模式之一:装饰模式(Decorator Pattern)
陋室 · 2008-05-23 · via 博客园 - 陋室

    最近看了blog牛人张逸写的设计之道,在文中设计模式的例子中运用了Decorator模式.怎么看怎么不理解(忘记说了,本人智商Te低),于是一个晚上没有睡着觉,在网上搜索Decorator的讲解.看了Terrylee的设计模式.看了lovecherry的无废话设计模式,也拜读了wxj1020<head First>设计模式系列(在此特别感谢各位,特献上最崇高的敬意).经过720个分钟的努力终于对decorator模式有一点点理解,为了加深对她的记忆.特此记录下来(也是怕忘记了.智商低的人忘记的特快).
    Decorator模式
    1:意图:动态的为一些对象添加一些职责(何为动态?晕死,我的理解就是,不通过继承而增加对象功能!).
    2:结构图(不是俺画的)
   
    3
实例(别讲那些高深的理论的东西,实践出真知,抓紧看一下吧)
          项目背景:一个图书馆有两种刊物可以外借书籍(Books)和音像(Videos),开始都免费.看下类图吧
                              
       都是很简单的关系.继承.代码也很简单
       LibraryItem.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7   public  abstract class LibraryItem
 8    {
 9       public abstract void Free();
10      
11       // void Charge();
12    }

13}

14

       

Books.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7    public class Books : LibraryItem
 8    {       
 9        public override  void Free()
10        {              
12            Console.WriteLine("
借书籍准则");
13        }

14    }

15}

16

       

Vedios.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7   public  class Vedios:LibraryItem
 8    {            
 9       public override void Free()
10       
11           Console.WriteLine("借录像准则");        
12       }
      
13    }

14}

15

    实现以上的功能.我们的设计还可以胜任.突然某天,图书馆老板变成"黄世仁"了.晕死.看书要书费.不过为了能顺利的进行不收费到收费的过度,他制定了详细的计划女生借书要钱,男生借Videos要钱.说不定改天对男生女生都收钱.
.完了.本来想通过自家继承的子类来实现,发现这样要增加3个子类,如果要是有其他的变化,子类又要多了.咋办?呵呵.聪明的你想到了.Decorator帮你实现(现代人就是轻松,老一辈啥都给你准备好了).看一下Decorator类图吧

看看代码吧
BooksDecorator.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7   public class BooksDecorator:LibraryDecorator
 8    {
 9       public BooksDecorator(LibraryItem liraryItem)
10            : base(liraryItem)
11        { }
12        public override  void Free()
13        {
14            base.Free();
15            //数据对女孩收费
16            ChargeForGirls();
17           
18        }

19        public void ChargeForGirls()
20        {
21            Console.WriteLine("Books cost 100$ for Girls");
22        }

23    }

24}

25

 VideosDecorator.cs

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7   public  class VideosDecorator:LibraryDecorator
 8    {
 9       public VideosDecorator(LibraryItem libraryItem)
10           : base(libraryItem)
11       { }
12       public override void Free()
13       {
14           base.Free();
15           //videos 对男生
收费
16           ChargeForBoys();   
17       }

18       public void ChargeForBoys()
19       {
20           Console.WriteLine("Videos cost 150$ for boys !");
21       }

22    }

23}

24

最后看下条用的程序

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace Decorator
 6{
 7    class Program
 8    {
 9        static void Main(string[] args)
10        {
11            //
12            LibraryItem libItem = null;
13            libItem = new Books();
14          
15            //decorator效果
16            LibraryDecorator libDecorator = null;
17            //增加女孩借书免费的功能
18            Console.WriteLine("增加女生书籍收费的功能");
19            libDecorator = new BooksDecorator(libItem);
20            libDecorator.Free();
21            Console.WriteLine();
22
23            libItem = new Vedios();
24          
25            //增加男生借Videos免费的功能
26            Console.WriteLine("增加男生Videos收费的功能");
27            libDecorator = new VideosDecorator(libItem);
28            libDecorator.Free();
29            Console.WriteLine();
30
31            //对于所有男生女生,书籍和videos都免费
32            Console.WriteLine("增加男生,女生对书籍和videos都收费");
33            libDecorator = new BooksDecorator(libDecorator);
34            libDecorator.Free();
35
36
37        }

38    }

39}

40

看看运行结果

适用性

在以下情况下应当使用装饰模式:

1.需要扩展一个类的功能,或给一个类增加附加责任。

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

总结

Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。

参考资料