装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活,它是一种对象结构型模式。
结构:
角色:
Component:给出一个抽象接口,可以给对象动态添加职责。
ConcreteComponent:定义一个将要接收附加责任的类。
Decorator:维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
Concrete Decorator:负责给构件对象“贴上”附加的责任。
示例代码:
using System;
using System.Collections;
// "Component"
abstract class LibraryItem
{
// Fields
private int numCopies;
// Properties
public int NumCopies
{
get{ return 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();
foreach( string borrower in borrowers )
Console.WriteLine( " borrower: {0}", borrower );
}
}
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", 23, 60 );
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();
}
}
装饰模式的特点:
装饰者和被装饰者对象有相同的基类。
可以用一个或多个装饰者包装一个对象。
在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态的、不限量的用装饰者来装饰对象。