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

推荐订阅源

Cyberwarzone
Cyberwarzone
V
Vulnerabilities – Threatpost
T
Tenable Blog
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
Project Zero
Project Zero
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Visual Studio Blog
WordPress大学
WordPress大学
Latest news
Latest news
K
Kaspersky official blog
T
Tailwind CSS Blog
T
Threat Research - Cisco Blogs
B
Blog RSS Feed
C
Cisco Blogs
博客园 - 聂微东
Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss
小众软件
小众软件
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
S
SegmentFault 最新的问题
Security Latest
Security Latest
Y
Y Combinator Blog
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 最新话题
月光博客
月光博客
The GitHub Blog
The GitHub Blog
博客园 - 三生石上(FineUI控件)
S
Security Affairs
P
Proofpoint News Feed
D
DataBreaches.Net
有赞技术团队
有赞技术团队
云风的 BLOG
云风的 BLOG

博客园 - Vengen

【笔记】DataTable或IList使用GroupBy方法的lamda表达式 WSS学习笔记(3) – 在“用户控件”中使用SPGridView WSS学习笔记(2) - 用QuickPart部署“用户控件”来替代WebPart WSS学习笔记(1) - 创建简单的WebPart 用ILmerge工具将C#中的EXE和DLL文件合并成单个文件 修改WordPress文章索引列表的日期格式 Windows7部署Android开发环境傻瓜式教程(Eclipse+ADT) 如何使用C#访问WordPress的xmlrpc.php - Vengen - 博客园 Windows7部署WordPress傻瓜式教程(IIS7.5+MySQL+PHP+WordPress) C#面向对象设计模式学习笔记(10) - Facade 外观模式(结构型模式) C#面向对象设计模式学习笔记(8) - Composite 组合模式(结构型模式) C#面向对象设计模式学习笔记(7) - Bridge 桥接模式(结构型模式) C#面向对象设计模式学习笔记(6) - Adapter 适配器模式(结构型模式) C#面向对象设计模式学习笔记(5) - Prototype 原型模式(创建型模式) C#面向对象设计模式学习笔记(4) - Factory Method 工厂方法模式(创建型模式) C#面向对象设计模式学习笔记(3) - Builder 生成器模式(创建型模式) C#面向对象设计模式学习笔记(2) - Abstract Factory 抽象工厂模式(创建型模式) - Vengen C#面向对象设计模式学习笔记(1) - Singleton 单件模式(创建型模式) C#面向对象设计模式学习笔记 - 开篇
C#面向对象设计模式学习笔记(9) - Decorator 装饰模式(结构型模式)
Vengen · 2009-12-13 · via 博客园 - Vengen

在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态(编译时)特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。

如何使“对象功能的扩展”能够根据需要来动态(运行时)地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?

意图(Intent 

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

image 

public abstract class Tank
{
public abstract void Shot();
public abstract void Run();
}
public abstract class Decorator : Tank //接口继承
{
private Tank tank;//Has-A 对象组合

public Decorator(Tank tank)
{
this.tank = tank;
}
public override void Shot()
{
tank.Shot();
}
public override void Run()
{
tank.Run();
}
}

/// <summary>
/// 装饰类A
/// </summary>
public class DecoratorA : Decorator
{
public DecoratorA(Tank tank)
:
base(tank)
{
}
public override void Shot()
{
//红外功能扩展
//Do Shot...
base.Shot();
}
public override void Run()
{
//红外功能扩展
//Do Run...
base.Run();
}
}
/// <summary>
/// 装饰类B
/// </summary>
public class DecoratorB : Decorator
{
public DecoratorB(Tank tank)
:
base(tank)
{
}
public override void Shot()
{
//水陆两栖功能扩展
//Do Shot...
base.Shot();
}
public override void Run()
{
//水陆两栖功能扩展
//Do Run...
base.Run();
}
}
/// <summary>
/// 装饰类C
/// </summary>
public class DecoratorC : Decorator
{
public DecoratorC(Tank tank)
:
base(tank)
{
}
public override void Shot()
{
//卫星定位功能扩展
//Do Shot...
base.Shot();
}
public override void Run()
{
//卫星定位功能扩展
//Do Run...
base.Run();
}
}

class App
{
public static void Main()
{
Tank tank
= new T50();
DecoratorA da
= new DecoratorA(tank);//红外功能扩展
DecoratorA db = new DecoratorA(da);//水陆两栖功能扩展
DecoratorA dc = new DecoratorA(db);//卫星定位功能扩展
}
}

要点:

通过采用组合而非继承的手法, Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。

Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。

Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。

适用性 

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

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

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

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