欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
裝飾模式(Decorator Pattern)

一、 裝飾(Decorator)模式

裝飾(Decorator)模式又名包裝(Wrapper)模式[GOF95]。裝飾模式以對客戶(hù)端透明的方式擴展對象的功能,是繼承關(guān)系的一個(gè)替代方案。

引言

孫悟空有七十二般變化,他的每一種變化都給他帶來(lái)一種附加的本領(lǐng)。他變成魚(yú)兒時(shí),就可以到水里游泳;他變成雀兒時(shí),就可以在天上飛行。而不管悟空怎么變化,在二郎神眼里,他永遠是那只猢猻。

裝飾模式以對客戶(hù)透明的方式動(dòng)態(tài)地給一個(gè)對象附加上更多的責任。換言之,客戶(hù)端并不會(huì )覺(jué)得對象在裝飾前和裝飾后有什么不同。裝飾模式可以在不使用創(chuàng )造更多子類(lèi)的情況下,將對象的功能加以擴展。


二、 裝飾模式的結構

裝飾模式使用原來(lái)被裝飾的類(lèi)的一個(gè)子類(lèi)的實(shí)例,把客戶(hù)端的調用委派到被裝飾類(lèi)。裝飾模式的關(guān)鍵在于這種擴展是完全透明的。

在孫猴子的例子里,老孫變成的魚(yú)兒相當于老孫的子類(lèi),這條魚(yú)兒與外界的互動(dòng)要通過(guò)"委派",交給老孫的本尊,由老孫本尊采取行動(dòng)。

裝飾模式的類(lèi)圖如下圖所示:

 

在裝飾模式中的各個(gè)角色有:

  • 抽象構件(Component)角色:給出一個(gè)抽象接口,以規范準備接收附加責任的對象。
  • 具體構件(Concrete Component)角色:定義一個(gè)將要接收附加責任的類(lèi)。
  • 裝飾(Decorator)角色:持有一個(gè)構件(Component)對象的實(shí)例,并定義一個(gè)與抽象構件接口一致的接口。
  • 具體裝飾(Concrete Decorator)角色:負責給構件對象"貼上"附加的責任。


三、 裝飾模式示例性代碼

以下示例性代碼實(shí)現了裝飾模式:

 

// Decorator pattern -- Structural example  
using System;

// "Component"
abstract class Component
{
  
// Methods
  abstract public void Operation();
}


// "ConcreteComponent"
class ConcreteComponent : Component
{
  
// Methods
  override public void Operation()
  
{
    Console.WriteLine(
"ConcreteComponent.Operation()");
  }

}


// "Decorator"
abstract class Decorator : Component
{
  
// Fields
  protected Component component;

  
// Methods
  public void SetComponent( Component component )
  
{
    
this.component = component;
  }


  
override public void Operation()
  
{
    
if( component != null )
      component.Operation();
  }

}


// "ConcreteDecoratorA"
class ConcreteDecoratorA : Decorator
{
  
// Fields
  private string addedState;

  
// Methods
  override public void Operation()
  
{
    
base.Operation();
    addedState 
= "new state";
    Console.WriteLine(
"ConcreteDecoratorA.Operation()");
  }

}


// "ConcreteDecoratorB"
class ConcreteDecoratorB : Decorator
{
  
// Methods
  override public void Operation()
  
{
    
base.Operation();
    AddedBehavior();
    Console.WriteLine(
"ConcreteDecoratorB.Operation()");
  }


  
void AddedBehavior()
  
{
  }

}


/// 
/// Client test
/// 

public class Client
{
  
public static void Main( string[] args )
  
{
    
// Create ConcreteComponent and two Decorators
    ConcreteComponent c = new ConcreteComponent();
    ConcreteDecoratorA d1 
= new ConcreteDecoratorA();
    ConcreteDecoratorB d2 
= new ConcreteDecoratorB();

    
// Link decorators
    d1.SetComponent( c );
    d2.SetComponent( d1 );

    d2.Operation();
  }

}

 

上面的代碼在執行裝飾時(shí)是通過(guò)SetComponent方法實(shí)現的,在實(shí)際應用中,也有通過(guò)構造函數實(shí)現的,一個(gè)典型的創(chuàng )建過(guò)程可能如下:

 

new Decorator1(
   
new Decorator2(
      
new Decorator3(
         
new ConcreteComponent()
         )
      )
   )

 

裝飾模式常常被稱(chēng)為包裹模式,就是因為每一個(gè)具體裝飾類(lèi)都將下一個(gè)具體裝飾類(lèi)或者具體構件類(lèi)包裹起來(lái)。


四、 裝飾模式應當在什么情況下使用

在以下情況下應當使用裝飾模式:

  1. 需要擴展一個(gè)類(lèi)的功能,或給一個(gè)類(lèi)增加附加責任。
  2. 需要動(dòng)態(tài)地給一個(gè)對象增加功能,這些功能可以再動(dòng)態(tài)地撤銷(xiāo)。
  3. 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變得不現實(shí)。

五、 裝飾模式實(shí)際應用的例子

該例子演示了通過(guò)裝飾模式為圖書(shū)館的圖書(shū)與錄像帶添加"可借閱"裝飾。

 

// Decorator pattern -- Real World example  
using System;
using System.Collections;

// "Component"
abstract class LibraryItem
{
  
// Fields
  private int numCopies;

  
// Properties
  public int NumCopies
  
{
    
getreturn numCopies; }
    
set{ numCopies = value; }
  }


  
// Methods
  public abstract void Display();
}


// "ConcreteComponent"
class Book : LibraryItem
{
  
// Fields
  private string author;
  
private string title;

  
// Constructors
  public Book(string author,string title,int numCopies)
  
{
    
this.author = author;
    
this.title = title;
    
this.NumCopies = numCopies;
  }


  
// Methods
  public override void Display()
  
{
    Console.WriteLine( 
" Book ------ " );
    Console.WriteLine( 
" Author: {0}", author );
    Console.WriteLine( 
" Title: {0}", title );
    Console.WriteLine( 
" # Copies: {0}", NumCopies );
  }

}


// "ConcreteComponent"
class Video : LibraryItem
{
  
// Fields
  private string director;
  
private string title;
  
private int playTime;

  
// Constructor
  public Video( string director, string title,
    
int numCopies, int playTime )
  
{
    
this.director = director;
    
this.title = title;
    
this.NumCopies = numCopies;
    
this.playTime = playTime;
  }


  
// Methods
  public override void Display()
  
{
    Console.WriteLine( 
" Video ----- " );
    Console.WriteLine( 
" Director: {0}", director );
    Console.WriteLine( 
" Title: {0}", title );
    Console.WriteLine( 
" # Copies: {0}", NumCopies );
    Console.WriteLine( 
" Playtime: {0}", playTime );
  }

}


// "Decorator"
abstract class Decorator : LibraryItem
{
  
// Fields
  protected LibraryItem libraryItem;

  
// Constructors
  public Decorator ( LibraryItem libraryItem )
  
this.libraryItem = libraryItem; }

  
// Methods
  public override void Display()
  
{ libraryItem.Display(); }
}


// "ConcreteDecorator"
class Borrowable : Decorator
{
  
// Fields
  protected ArrayList borrowers = new ArrayList();

  
// Constructors
  public Borrowable( LibraryItem libraryItem )
    : 
base( libraryItem ) {}

  
// Methods
  public void BorrowItem( string name )
  
{
    borrowers.Add( name );
    libraryItem.NumCopies
--;
  }


  
public void ReturnItem( string name )
  
{
    borrowers.Remove( name );
    libraryItem.NumCopies
++;
  }


  
public override void Display()
  
{
    
base.Display();
    
foreachstring borrower in borrowers )
      Console.WriteLine( 
" borrower: {0}", borrower );
  }

}

 
/// 
///  DecoratorApp test
/// 

public class DecoratorApp
{
  
public static void Main( string[] args )
  
{
    
// Create book and video and display
    Book book = new Book( "Schnell""My Home"10 );
    Video video 
= new Video( "Spielberg",
      
"Schindler‘s list"2360 );
    book.Display();
    video.Display();

    
// Make video borrowable, then borrow and display
    Console.WriteLine( " Video made borrowable:" );
    Borrowable borrowvideo 
= new Borrowable( video );
    borrowvideo.BorrowItem( 
"Cindy Lopez" );
    borrowvideo.BorrowItem( 
"Samuel King" );

    borrowvideo.Display();
  }

}

 


六、 使用裝飾模式的優(yōu)點(diǎn)和缺點(diǎn)

使用裝飾模式主要有以下的優(yōu)點(diǎn):

  1. 裝飾模式與繼承關(guān)系的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。
  2. 通過(guò)使用不同的具體裝飾類(lèi)以及這些裝飾類(lèi)的排列組合,設計師可以創(chuàng )造出很多不同行為的組合。
  3. 這種比繼承更加靈活機動(dòng)的特性,也同時(shí)意味著(zhù)裝飾模式比繼承更加易于出錯。

使用裝飾模式主要有以下的缺點(diǎn):

由于使用裝飾模式,可以比使用繼承關(guān)系需要較少數目的類(lèi)。使用較少的類(lèi),當然使設計比較易于進(jìn)行。但是,在另一方面,使用裝飾模式會(huì )產(chǎn)生比使用繼承關(guān)系更多的對象。更多的對象會(huì )使得查錯變得困難,特別是這些對象看上去都很相像。


七、 模式實(shí)現的討論

大多數情況下,裝飾模式的實(shí)現都比上面定義中給出的示意性實(shí)現要簡(jiǎn)單。對模式進(jìn)行簡(jiǎn)化時(shí)需要注意以下的情況:

(1)一個(gè)裝飾類(lèi)的接口必須與被裝飾類(lèi)的接口相容。

(2)盡量保持Component作為一個(gè)"輕"類(lèi),不要把太多的邏輯和狀態(tài)放在Component類(lèi)里。

(3)如果只有一個(gè)ConcreteComponent類(lèi)而沒(méi)有抽象的Component類(lèi)(接口),那么Decorator類(lèi)經(jīng)??梢允荂oncreteComponent的一個(gè)子類(lèi)。如下圖所示:

 

(4)如果只有一個(gè)ConcreteDecorator類(lèi),那么就沒(méi)有必要建立一個(gè)單獨的Decorator類(lèi),而可以把Decorator和ConcreteDecorator的責任合并成一個(gè)類(lèi)。


八、 透明性的要求

透明的裝飾模式

裝飾模式通常要求針對抽象編程。裝飾模式對客戶(hù)端的透明性要求程序不要聲明一個(gè)ConcreteDecorator類(lèi)型的變量,而應當聲明一個(gè)Component類(lèi)型的變量。換言之,下面的做法是對的:

 

Component c = new ConcreteComponent();
Component c1 
= new ConcreteDecorator1(c);
Component c2 
= new ConcreteDecorator(c1);

 

而下面的做法是不對的:

 

ConcreteComponent c = new ConcreteDecorator();

 

這就是前面所說(shuō)的,裝飾模式對客戶(hù)端是完全透明的含義。

用孫悟空的例子來(lái)說(shuō),必須永遠把孫悟空的所有變化都當成孫悟空來(lái)對待,而如果把老孫變成的雀兒當成雀兒,而不是老孫,那就被老孫騙了,而這是不應當發(fā)生的。

下面的做法是不對的:

 

大圣本尊 c = new 大圣本尊();
雀兒 bird 
= new 雀兒 (c);

 

半透明的裝飾模式

然而,純粹的裝飾模式很難找到。裝飾模式的用意是在不改變接口的前提下,增強所考慮的類(lèi)的性能。在增強性能的時(shí)候,往往需要建立新的公開(kāi)的方法。即便是在孫大圣的系統里,也需要新的方法。比如齊天大圣類(lèi)并沒(méi)有飛行的能力,而雀兒有。這就意味著(zhù)雀兒應當有一個(gè)新的fly()方法。

這就導致了大多數的裝飾模式的實(shí)現都是"半透明"(semi-transparent)的,而不是完全"透明"的。換言之,允許裝飾模式改變接口,增加新的方法。即聲明ConcreteDecorator類(lèi)型的變量,從而可以調用ConcreteDecorator類(lèi)中才有的方法:

 

齊天大圣 c = new 大圣本尊();
雀兒 bird 
= new 雀兒(c);
bird.fly();

 

齊天大圣接口根本沒(méi)有fly()這個(gè)方法,而雀兒接口里有這個(gè)方法。


九、 裝飾模式在.NET中的應用

.net中存在如下類(lèi)模型:

 

下面的代碼段用來(lái)將XmlDocument的內容格式輸出。我們可以體會(huì )Decorator模式在這里所起的作用。

 

 

// 生成ConcreteComponent(內存流ms)
MemoryStream ms = new MemoryStream();

// 用XmlTextWriter對內存流 ms 進(jìn)行裝飾
// 此處使用了半透明的裝飾模式
XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8);
xtw.Formatting 
= Formatting.Indented;

// 對裝飾xtw的操作會(huì )轉而操作本體-內存流ms
xmlDoc.Save(xtw);

byte[] buf = ms.ToArray();
txtResult.Text 
= Encoding.UTF8.GetString(buf,0,buf.Length);
xtw.Close();
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
大話(huà)設計-裝飾模式
C#設計模式系列:裝飾模式(Decorator)
設計模式學(xué)習筆記(十)——Decorator裝飾模式
設計模式之裝飾模式篇(Decorator)
C# 設計模式系列教程-裝飾模式
設計模式(1)裝飾模式總結
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久