fbpx
维基百科

修饰模式

修饰模式,是面向对象程式领域中,一种动态地往一个類別中添加新的行为的设计模式。就功能而言,修饰模式相比生成子類別更为灵活,这样可以给某个对象而不是整个類別添加一些功能。[1]

UML 修饰模式的UML类图

介绍

通过使用修饰模式,可以在运行时扩充一个類別的功能。原理是:增加一个修饰类包裹原来的類別,包裹的方式是在修饰类的构造函数中将原来的类以参数的形式传入。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的類別中的方法。修饰类必须和原来的類別有相同的接口。

修饰模式是類別继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。

当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,類別不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味著要为每一种组合创建一个新類別。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个修饰模式的示例是JAVA里的Java I/O Streams的实现。

动机

舉個例子來說,在一個視窗軟體系統中呈現的一個視窗,為了讓視窗中呈現的內容資料能夠捲動,我们希望给它添加水平或垂直滚动条。假设窗口通过“Window”类实例来表示,并且假设它没有添加滚动条功能。我们可以创建一个子类“ScrollingWindow”来提供,或者我们可以创建一个ScrollingWindowDecorator来为已存在的Window对象添加这个功能。在这点上,只要是解决方案就可以了。 现在我们假设希望选择给我们的窗口添加边框,同样,我们的原始Window类不支持。ScrollingWindow子类现在会造成一个问题,因为它会有效的创建一种新的窗口。如果我们想要给所有窗口添加边框,我们必须创建WindowWithBorderScrollingWindowWithBorder子类。显然,这个问题由于被添加类而变得更糟了。对于修饰模式,我们简单的创建一个新类BorderedWindowDecorator,在运行时,我们能够使用ScrollingWindowDecoratorBorderedWindowDecorator或两者结合来修饰已存在的窗口。 一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集(不同的用户凭据等)限制访问对象的属性或方法时。

一个对象的属性或方法按照某组规则或几个并行规则(不同用户证书等)需要限制访问时,在这种情况下,不是在原始对象中实现访问控制而是在他的使用中不变或不知道任何限制,并且他被包装在一个访问控制修饰对象中,这个对象能够对允许的原始对象的接口子集服务。

应用

Java IO 流为典型的装饰模式。

代码示例

Java

这个JAVA示例使用window/scrolling情境。

// The Window interface class public interface Window { public void draw(); // Draws the Window public String getDescription(); // Returns a description of the Window } // implementation of a simple Window without any scrollbars public class SimpleWindow implements Window { public void draw() { // Draw window } public String getDescription() { return "simple window"; } } 

以下类包含所有Window类的decorator,以及修饰类本身。

// abstract decorator class - note that it implements Window public abstract class WindowDecorator implements Window {  protected Window decoratedWindow; // the Window being decorated   public WindowDecorator (Window decoratedWindow) {  this.decoratedWindow = decoratedWindow;  }   @Override  public void draw() {  decoratedWindow.draw();  }   @Override  public String getDescription() {  return decoratedWindow.getDescription();  } }   // The first concrete decorator which adds vertical scrollbar functionality public class VerticalScrollBar extends WindowDecorator {  public VerticalScrollBar(Window windowToBeDecorated) {  super(windowToBeDecorated);  }   @Override  public void draw() {  super.draw();  drawVerticalScrollBar();  }   private void drawVerticalScrollBar() {  // Draw the vertical scrollbar  }   @Override  public String getDescription() {  return super.getDescription() + ", including vertical scrollbars";  } }   // The second concrete decorator which adds horizontal scrollbar functionality public class HorizontalScrollBar extends WindowDecorator {  public HorizontalScrollBar (Window windowToBeDecorated) {  super(windowToBeDecorated);  }   @Override  public void draw() {  super.draw();  drawHorizontalScrollBar();  }   private void drawHorizontalScrollBar() {  // Draw the horizontal scrollbar  }   @Override  public String getDescription() {  return super.getDescription() + ", including horizontal scrollbars";  } } 

以下是一个测试程序,它创建了一个包含多重装饰的Window实例(如,包含了垂直的和水平的滚动条),然后输出它的描述:

public class Main { // for print descriptions of the window subclasses static void printInfo(Window w) { System.out.println("description:"+w.getDescription()); } public static void main(String[] args) { // original SimpleWindow SimpleWindow sw = new SimpleWindow(); printInfo(sw); // HorizontalScrollBar mixed Window HorizontalScrollBar hbw = new HorizontalScrollBar(sw); printInfo(hbw); // VerticalScrollBar mixed Window VerticalScrollBar vbw = new VerticalScrollBar(hbw); printInfo(vbw); } } 

以下是SimpleWindow及添加了组件HorizontalScrollBar和VerticalScrollBar后的Window测试结果:

description:simple window description:simple window, including horizontal scrollbars description:simple window, including horizontal scrollbars, including vertical scrollbars 

C++

C++代码示例:

#include <iostream> using namespace std; /* Component (interface) */ class Widget { public:   virtual void draw() = 0;   virtual ~Widget() {} };  /* ConcreteComponent */ class TextField : public Widget { private:   int width, height; public:  TextField( int w, int h ){   width = w;  height = h;   }    void draw() {   cout << "TextField: " << width << ", " << height << '\n';   } }; /* Decorator (interface) */  class Decorator : public Widget { private:  Widget* wid; // reference to Widget   public:  Decorator( Widget* w ) {   wid = w;   }  void draw() {   wid->draw();   }  ~Decorator() {  delete wid;  } }; /* ConcreteDecoratorA */ class BorderDecorator : public Decorator {  public:  BorderDecorator( Widget* w ) : Decorator( w ) { }  void draw() {  Decorator::draw();   cout << " BorderDecorator" << '\n';   }  }; /* ConcreteDecoratorB */ class ScrollDecorator : public Decorator {  public:  ScrollDecorator( Widget* w ) : Decorator( w ) { }  void draw() {  Decorator::draw();   cout << " ScrollDecorator" << '\n';  }  }; int main( void ) {    Widget* aWidget = new BorderDecorator(  new BorderDecorator(  new ScrollDecorator(  new TextField( 80, 24 ))));  aWidget->draw();  delete aWidget; } 

C#

C#代码示例:

namespace GSL_Decorator_pattern {  interface IWindowObject  {  void Draw(); // draws the object  string GetDescription(); // returns a description of the object  }  class ControlComponent : IWindowObject  {  public ControlComponent()  {  }  public void Draw() // draws the object  {  Console.WriteLine( "ControlComponent::draw()" );   }  public string GetDescription() // returns a description of the object  {  return "ControlComponent::getDescription()";  }  }  abstract class Decorator : IWindowObject  {  protected IWindowObject _decoratedWindow = null; // the object being decorated  public Decorator( IWindowObject decoratedWindow)  {  _decoratedWindow = decoratedWindow;  }  public virtual void Draw()  {  _decoratedWindow.Draw();  Console.WriteLine("\tDecorator::draw() ");  }  public virtual string GetDescription() // returns a description of the object  {  return _decoratedWindow.GetDescription() + "\n\t" + "Decorator::getDescription() ";  }  }  // the first decorator   class DecorationA : Decorator  {  public DecorationA(IWindowObject decoratedWindow) : base(decoratedWindow)  {  }  public override void Draw()  {  base.Draw();  DecorationAStuff();  }  private void DecorationAStuff()  {  Console.WriteLine("\t\tdoing DecorationA things");  }  public override string GetDescription()  {  return base.GetDescription() + "\n\t\tincluding " + this.ToString();  }  }// end class ConcreteDecoratorA : Decorator  class DecorationB : Decorator  {  public DecorationB(IWindowObject decoratedWindow) : base(decoratedWindow)  {  }  public override void Draw()  {  base.Draw();  DecorationBStuff();  }  private void DecorationBStuff()  {  Console.WriteLine("\t\tdoing DecorationB things");  }  public override string GetDescription()  {  return base.GetDescription() + "\n\t\tincluding " + this.ToString();  }  }// end class DecorationB : Decorator  class DecorationC : Decorator  {  public DecorationC(IWindowObject decoratedWindow) : base(decoratedWindow)  {  }  public override void Draw()  {  base.Draw();  DecorationCStuff();  }  private void DecorationCStuff()  {  Console.WriteLine("\t\tdoing DecorationC things");  }  public override string GetDescription()  {  return base.GetDescription() + "\n\t\tincluding " + this.ToString();  }  }// end class DecorationC : Decorator }// end of namespace GSL_Decorator_patternpublic class MyClass 

Go

Go代码示例:

package main import "fmt" // step1: 编写基础功能,刚开始不需要定义接口 type Base struct { } func (b *Base) Call() string {  return "base is called" } // step2: 将上面的方法声明为接口类型,基础功能中的 Call() 调用自动满足下面的接口 type DecoratorI interface {  Call() string } // step3: 编写新增功能,结构中保存接口类型的参数 type Decorator struct {  derorator DecoratorI } func (d *Decorator) Call() string {  return "decorator: " + d.derorator.Call() } func main() {  base := &Base{}  fmt.Println(base.Call())  decorator := Decorator{base}  fmt.Println(decorator.Call()) } 

参考资料

  1. ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. 设计模式:可复用面向对象软件的基础. 北京: 机械工业出版社. 2000: 115. ISBN 9787111075752 (中文). 

外部链接

  • Article "" (Java) by Antonio García and Stephen Wong
  • Article "" (Java) by Budi Kurniawan
  • Sample Chapter "" (C#) by James W. Cooper
  • A PHP approach[永久失效連結] (PHP)
  • (Delphi)
  • J2EE Pattern Oriented Framework
  • (Ruby)


修饰模式, 是面向对象程式领域中, 一种动态地往一个類別中添加新的行为的设计模式, 就功能而言, 相比生成子類別更为灵活, 这样可以给某个对象而不是整个類別添加一些功能, 的uml类图, 目录, 介绍, 动机, 应用, 代码示例, java, 参考资料, 外部链接介绍, 编辑通过使用, 可以在运行时扩充一个類別的功能, 原理是, 增加一个修饰类包裹原来的類別, 包裹的方式是在修饰类的构造函数中将原来的类以参数的形式传入, 装饰类实现新的功能, 但是, 在不需要用到新功能的地方, 它可以直接调用原来的類別中的方法, . 修饰模式 是面向对象程式领域中 一种动态地往一个類別中添加新的行为的设计模式 就功能而言 修饰模式相比生成子類別更为灵活 这样可以给某个对象而不是整个類別添加一些功能 1 UML 修饰模式的UML类图 目录 1 介绍 2 动机 3 应用 4 代码示例 4 1 Java 4 2 C 4 3 C 4 4 Go 5 参考资料 6 外部链接介绍 编辑通过使用修饰模式 可以在运行时扩充一个類別的功能 原理是 增加一个修饰类包裹原来的類別 包裹的方式是在修饰类的构造函数中将原来的类以参数的形式传入 装饰类实现新的功能 但是 在不需要用到新功能的地方 它可以直接调用原来的類別中的方法 修饰类必须和原来的類別有相同的接口 修饰模式是類別继承的另外一种选择 类继承在编译时候增加行为 而装饰模式是在运行时增加行为 当有几个相互独立的功能需要扩充时 这个区别就变得很重要 在有些面向对象的编程语言中 類別不能在运行时被创建 通常在设计的时候也不能预测到有哪几种功能组合 这就意味著要为每一种组合创建一个新類別 相反 修饰模式是面向运行时候的对象实例的 这样就可以在运行时根据需要进行组合 一个修饰模式的示例是JAVA里的Java I O Streams的实现 动机 编辑舉個例子來說 在一個視窗軟體系統中呈現的一個視窗 為了讓視窗中呈現的內容資料能夠捲動 我们希望给它添加水平或垂直滚动条 假设窗口通过 Window 类实例来表示 并且假设它没有添加滚动条功能 我们可以创建一个子类 ScrollingWindow 来提供 或者我们可以创建一个ScrollingWindowDecorator来为已存在的Window对象添加这个功能 在这点上 只要是解决方案就可以了 现在我们假设希望选择给我们的窗口添加边框 同样 我们的原始Window类不支持 ScrollingWindow子类现在会造成一个问题 因为它会有效的创建一种新的窗口 如果我们想要给所有窗口添加边框 我们必须创建WindowWithBorder和ScrollingWindowWithBorder子类 显然 这个问题由于被添加类而变得更糟了 对于修饰模式 我们简单的创建一个新类BorderedWindowDecorator 在运行时 我们能够使用ScrollingWindowDecorator或BorderedWindowDecorator或两者结合来修饰已存在的窗口 一个修饰能够被应用的另一个好例子是当有需要根据某套规则或者几个平行的规则集 不同的用户凭据等 限制访问对象的属性或方法时 一个对象的属性或方法按照某组规则或几个并行规则 不同用户证书等 需要限制访问时 在这种情况下 不是在原始对象中实现访问控制而是在他的使用中不变或不知道任何限制 并且他被包装在一个访问控制修饰对象中 这个对象能够对允许的原始对象的接口子集服务 应用 编辑Java IO 流为典型的装饰模式 代码示例 编辑Java 编辑 这个JAVA示例使用window scrolling情境 The Window interface class public interface Window public void draw Draws the Window public String getDescription Returns a description of the Window implementation of a simple Window without any scrollbars public class SimpleWindow implements Window public void draw Draw window public String getDescription return simple window 以下类包含所有Window类的decorator 以及修饰类本身 abstract decorator class note that it implements Window public abstract class WindowDecorator implements Window protected Window decoratedWindow the Window being decorated public WindowDecorator Window decoratedWindow this decoratedWindow decoratedWindow Override public void draw decoratedWindow draw Override public String getDescription return decoratedWindow getDescription The first concrete decorator which adds vertical scrollbar functionality public class VerticalScrollBar extends WindowDecorator public VerticalScrollBar Window windowToBeDecorated super windowToBeDecorated Override public void draw super draw drawVerticalScrollBar private void drawVerticalScrollBar Draw the vertical scrollbar Override public String getDescription return super getDescription including vertical scrollbars The second concrete decorator which adds horizontal scrollbar functionality public class HorizontalScrollBar extends WindowDecorator public HorizontalScrollBar Window windowToBeDecorated super windowToBeDecorated Override public void draw super draw drawHorizontalScrollBar private void drawHorizontalScrollBar Draw the horizontal scrollbar Override public String getDescription return super getDescription including horizontal scrollbars 以下是一个测试程序 它创建了一个包含多重装饰的Window实例 如 包含了垂直的和水平的滚动条 然后输出它的描述 public class Main for print descriptions of the window subclasses static void printInfo Window w System out println description w getDescription public static void main String args original SimpleWindow SimpleWindow sw new SimpleWindow printInfo sw HorizontalScrollBar mixed Window HorizontalScrollBar hbw new HorizontalScrollBar sw printInfo hbw VerticalScrollBar mixed Window VerticalScrollBar vbw new VerticalScrollBar hbw printInfo vbw 以下是SimpleWindow及添加了组件HorizontalScrollBar和VerticalScrollBar后的Window测试结果 description simple window description simple window including horizontal scrollbars description simple window including horizontal scrollbars including vertical scrollbars C 编辑 C 代码示例 include lt iostream gt using namespace std Component interface class Widget public virtual void draw 0 virtual Widget ConcreteComponent class TextField public Widget private int width height public TextField int w int h width w height h void draw cout lt lt TextField lt lt width lt lt lt lt height lt lt n Decorator interface class Decorator public Widget private Widget wid reference to Widget public Decorator Widget w wid w void draw wid gt draw Decorator delete wid ConcreteDecoratorA class BorderDecorator public Decorator public BorderDecorator Widget w Decorator w void draw Decorator draw cout lt lt BorderDecorator lt lt n ConcreteDecoratorB class ScrollDecorator public Decorator public ScrollDecorator Widget w Decorator w void draw Decorator draw cout lt lt ScrollDecorator lt lt n int main void Widget aWidget new BorderDecorator new BorderDecorator new ScrollDecorator new TextField 80 24 aWidget gt draw delete aWidget C 编辑 C 代码示例 namespace GSL Decorator pattern interface IWindowObject void Draw draws the object string GetDescription returns a description of the object class ControlComponent IWindowObject public ControlComponent public void Draw draws the object Console WriteLine ControlComponent draw public string GetDescription returns a description of the object return ControlComponent getDescription abstract class Decorator IWindowObject protected IWindowObject decoratedWindow null the object being decorated public Decorator IWindowObject decoratedWindow decoratedWindow decoratedWindow public virtual void Draw decoratedWindow Draw Console WriteLine tDecorator draw public virtual string GetDescription returns a description of the object return decoratedWindow GetDescription n t Decorator getDescription the first decorator class DecorationA Decorator public DecorationA IWindowObject decoratedWindow base decoratedWindow public override void Draw base Draw DecorationAStuff private void DecorationAStuff Console WriteLine t tdoing DecorationA things public override string GetDescription return base GetDescription n t tincluding this ToString end class ConcreteDecoratorA Decorator class DecorationB Decorator public DecorationB IWindowObject decoratedWindow base decoratedWindow public override void Draw base Draw DecorationBStuff private void DecorationBStuff Console WriteLine t tdoing DecorationB things public override string GetDescription return base GetDescription n t tincluding this ToString end class DecorationB Decorator class DecorationC Decorator public DecorationC IWindowObject decoratedWindow base decoratedWindow public override void Draw base Draw DecorationCStuff private void DecorationCStuff Console WriteLine t tdoing DecorationC things public override string GetDescription return base GetDescription n t tincluding this ToString end class DecorationC Decorator end of namespace GSL Decorator patternpublic class MyClass Go 编辑 Go代码示例 package main import fmt step1 编写基础功能 刚开始不需要定义接口 type Base struct func b Base Call string return base is called step2 将上面的方法声明为接口类型 基础功能中的 Call 调用自动满足下面的接口 type DecoratorI interface Call string step3 编写新增功能 结构中保存接口类型的参数 type Decorator struct derorator DecoratorI func d Decorator Call string return decorator d derorator Call func main base amp Base fmt Println base Call decorator Decorator base fmt Println decorator Call 参考资料 编辑 Erich Gamma Richard Helm Ralph Johnson John Vlissides 设计模式 可复用面向对象软件的基础 北京 机械工业出版社 2000 115 ISBN 9787111075752 中文 使用 accessdate 需要含有 url 帮助 外部链接 编辑Article The Decorator Design Pattern Java by Antonio Garcia and Stephen Wong Article Using the Decorator Pattern Java by Budi Kurniawan Sample Chapter C Design Patterns The Decorator Pattern C by James W Cooper A PHP approach 永久失效連結 PHP A Delphi approach Delphi A JavaScript implementation Jt J2EE Pattern Oriented Framework Decorator Pattern with Ruby in 8 Lines Ruby 取自 https zh wikipedia org w index php title 修饰模式 amp oldid 69323490, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。