Component 给出一个抽象接口,以规范准备接收附加责任的对象。 Concrete Component 定义一个将要接收附加责任的类。 Decorator 持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。 Concrete Decorator 负责给构件对象"贴上"附加的责任。
该例子演示了通过装饰模式为图书馆的图书与录像带添加"可借阅"装饰。
// Componentabstract class LibraryItem { private int numCopies;
public int getNumCopies() { return numCopies; }
public void setNumCopies(int numCopies) { this.numCopies = numCopies; }
public abstract void Display();}
// ConcreteComponentclass Book extends LibraryItem { private string author; private string title;
public Book(string author,string title,int numCopies) { this.author = author; this.title = title; this.numCopies = numCopies; }
public void Display() { System.out.println( " Book ------ " ); System.out.println( " Author: ", author ); System.out.println( " Title: " + title ); System.out.println( " # Copies: " + NumCopies ); }}
// ConcreteComponentclass Video extends LibraryItem { private string director; private string title; private int playTime;
public Video( string director, string title, int numCopies, int playTime ) { this.director = director; this.title = title; this.NumCopies = numCopies; this.playTime = playTime; }
public void Display() { System.out.println( " Video ----- " ); System.out.println( " Director: " + director ); System.out.println( " Title: " + title ); System.out.println( " # Copies: " + NumCopies ); System.out.println( " Playtime: " + playTime ); }}
// Decoratorabstract class Decorator extends LibraryItem { protected LibraryItem libraryItem;
public Decorator ( LibraryItem libraryItem ) { this.libraryItem = libraryItem; }
public void Display() { libraryItem.Display(); }}
// ConcreteDecoratorclass Borrowable extends Decorator { protected ArrayList<String> borrowers = new ArrayList><String>();
public Borrowable( LibraryItem libraryItem ) { super( libraryItem ); }
public void BorrowItem( string name ) { borrowers.Add( name ); libraryItem.numCopies--; }
public void ReturnItem( string name ) { borrowers.Remove( name ); libraryItem.NumCopies++; }
public void Display() { super.Display(); for( string borrower in borrowers ) System.out.println( " borrower: " + 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 System.out.println( " Video made borrowable:" ); Borrowable borrowvideo = new Borrowable( video ); borrowvideo.BorrowItem( "Cindy Lopez" ); borrowvideo.BorrowItem( "Samuel King" );
borrowvideo.Display(); }}
尽量保持Component作为一个"轻"类,不要把太多的逻辑和状态放在Component类里。
如果只有一个ConcreteComponent类而没有抽象的Component类(接口),那么Decorator类经常可以是ConcreteComponent的一个子类。
如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。