Component 给出一个抽象接口,以规范准备接收附加责任的对象。
Concrete Component 定义一个将要接收附加责任的类。
Decorator 持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
Concrete Decorator 负责给构件对象"贴上"附加的责任。
该例子演示了通过装饰模式为图书馆的图书与录像带添加"可借阅"装饰。
// Component
abstract class LibraryItem {
private int numCopies;
public int getNumCopies() {
return numCopies;
}
public void setNumCopies(int numCopies) {
this.numCopies = numCopies;
}
public abstract void Display();
}
// ConcreteComponent
class 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 );
}
}
// ConcreteComponent
class 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 );
}
}
// Decorator
abstract class Decorator extends LibraryItem {
protected LibraryItem libraryItem;
public Decorator ( LibraryItem libraryItem ) {
this.libraryItem = libraryItem;
}
public void Display() {
libraryItem.Display();
}
}
// ConcreteDecorator
class 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的责任合并成一个类。