博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Decorator Pattern
阅读量:5307 次
发布时间:2019-06-14

本文共 7080 字,大约阅读时间需要 23 分钟。

 

Intent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

 

While reading the  book on CD I noticed that the original name of this pattern was "Wrapper". -- 

 

See also:  ,  , 

 

This pattern was also called 
shadowing in LPC.

 


  •  


 

This pattern can also be used as a way to refactor a complex class into smaller pieces. Even if you don't need to attach responsibilities dynamically it can be clearer to have each responsibility in a different class. Somewhat like  s. -- 

 

Also see 

The "Adapter" pattern is also known as "Wrapper" pattern (). Is Wrapper/Adapter/Decorator the same pattern?

 

No.   is used to convert the interface of an object into something else.   is used to extend the functionality of an object while maintaining its interface. Both of these are probably sometimes called   since both of them do "wrap" an object.

 


 

My understanding is that the   does not refer to just 
any dynamic modifications to a class. My understanding is that it works like this:

 

  • You have an instance, and you put another instance inside of it. They both support the same (or similar) interfaces. The one on the outside is a "decorator."
  • You use the one on the outside. It either masks, changes, or pass-throughs the methods of the instance inside of it.
    • (Jim Coplien calls this a Letter/Envelope idiom, with the inner instance being the letter and the outer instance being the envelope.)

       

This is 
very different from what I've heard people say "the Decorator Pattern" means - I've heard people saying that 
pretty much anything that dynamically changes a class is an instance of "the Decorator Pattern."

 

So for instance, if you dynamically change a class at run-time in a language that lets you do that, you are now using, "The Decorator Pattern." If there's a feature of a language that lets you add a method to a class at run-time, they're calling that use of "the decorator pattern."

 

Reality check?

 


 

The description above implies that decorating an object changes its behaviour but not its interface. Is that necessarily true? For example, say you have a spell-check dictionary object. You want to get statistics on the most commonly misspelled words, so you wrap your spell-check dictionary in an envelope that tracks statistics. It exposes new methods for reading the stats.

 

Now it's true that the original client of the spell-check dictionary is in no way aware of the expanded interface. So from its perspective, your modification has not changed the interface. Isn't this an example of the  ?

 


 

In python, the 'random' module has a shuffle function which shuffles a list: random.shuffle(lyst) but what you mean is lyst.shuffle(); so importing the random module should add the shuffling behaviour to lists. Is this the  ?

 


 

An example of this pattern is how java.io's Readers and Writers work.

 


 

The difference that I see between a   and subclassing is that you can decorate any class that implements an interface with a single class. Say I wanted to give myself a java.util.Map that printed a message whenever I added or removed a key. If I only ever actually used java.util.  I could just create PrintingMap  as a subclass of   and override put & remove. But if I want to create a printing version of   then I either create PrintingTreeMap  (which has almost identical code to PrintingMap  (which should itself become PrintingHashMap )), or I create a Map decorator.

 

In short, you are trading "have to write pass-throughs for every method, not just the ones you're changing & do 2 step object creation", for "have to write a subclass for each concrete class you want to change". This goes from helpful to imperative if you are writing a library for others to use.

 

In java jdk 1.3 added dynamic proxy

 

that is a great way to "decorate" any object

 

author has added pre-method / post-method processing, which is decorating the instance

 

 


 

The term "wrapper" its used for several software design patterns, so an alternative, more specific identifier, should be used.

 

The Decorator Design Pattern has several requirements.

 

(1) An object that requires the extension.

 

Example:

 

A window control that requires additional optional features like:

 

  • horizontal scrollbar
  • vertical scrollbar
  • titlebar
  • footerbar or statusbar
  • other

     

     

An example with an Object Oriented C style pseudocode:

 

public class WindowClass?  {    // ...  } // class

  

 

(2) Several objects that support the extension by "decoration". Usually, those objects share a common interface, traits, or superclass, and sometimes, additional, intermediate superclasses .

 

/* abstract */ public class WindowDecoratorClass?  {    // ...  } // class   /* concrete*/ public class WindowTitleBarClass?:     extends WindowDecoratorClass?  {    // ...  } // class   /* concrete*/ public class WindowStatusBarClass?:     extends WindowDecoratorClass?  {    // ...  } // class   /* abstract */  public class WindowScrollbarClass?:     extends WindowDecoratorClass?  {    // ...  } // class   /* concrete*/ public class WindowHorizontalScrollbarClass?:     extends WindowScrollbarClass?  {    // ...  } // class   /* concrete*/ public class WindowVerticalScrollbarClass?:     extends WindowScrollbarClass?  {    // ...  } // class

  

 

(3) The decorated object (class or prototype instantation), and the decorator objects have one or several common features. In order to enssure that functuonality, the decorated object & the decorators have a common interface, traits, or class inheritance.

 

 

In the next example, the "Draw();" method & the "GetDescription ();" method are the features that are the requirement, and are defined by the "DrawingControlInterface ",

 

public interface WindowDecoratorInterface?  {    // ...     public String GetDescription?() { ... }     public void Draw() { ... }     // ...  } // interface   public class WindowClass?:    implements WindowDecoratorInterface?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* abstract */ public class WindowDecoratorClass?:    implements WindowDecoratorInterface?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* concrete*/ public class WindowTitleBarClass?:     extends WindowDecoratorClass?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* concrete*/ public class WindowStatusBarClass?:     extends WindowDecoratorClass?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* abstract */  public class WindowScrollbarClass?:     extends WindowDecoratorClass?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* concrete*/ public class WindowHorizontalScrollbarClass?:     extends WindowScrollbarClass?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class   /* concrete*/ public class WindowVerticalScrollbarClass?:     extends WindowScrollbarClass?  {    public String GetDescription?() { ... }     public void Draw() { ... }  } // class

  

转载于:https://www.cnblogs.com/hephec/p/4587466.html

你可能感兴趣的文章
Dreamweaver如何开启代码错误提示,报错代码。
查看>>
理解go语言 协程之间的通讯
查看>>
论企业租赁经营
查看>>
Node.js 模块
查看>>
[NOIP10.6模拟赛]1.merchant题解--思维+二分
查看>>
SQL Server触发器创建、删除、修改、查看示例步骤
查看>>
操作系统笔记(七)进程同步
查看>>
c语言博客作业03-函数
查看>>
实习第1天
查看>>
While reading xxx.png pngcrush caught libpng error: Not a PNG file..
查看>>
ios推送-B/S架构-socket
查看>>
UVALive 4426 Blast the Enemy! 计算几何求重心
查看>>
结对编程收获
查看>>
【技术案例】双目摄像头数据采集
查看>>
PHPStorm 批量选择,多光标同时编辑相同的内容
查看>>
数据库复习总结(3)-创建数据库、表、以及数据类型的介绍
查看>>
列表与导航,内联
查看>>
C# EPL USB 指令打印
查看>>
关于GetSystemMetrics()函数
查看>>
BInd绑定
查看>>