C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

模式设计c#--结构型--decorator

名称 Decorator
结构 o_decorator.bmp
意图 动态地给一个对象添加一些额外的职责。就增加功能来说,D e c o r a t o r 模式相比生成子类更为灵活。
适用性
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤消的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

Code Example
namespace Decorator_DesignPattern
{
    
using System;

    
abstract class Component
    
{
        
public abstract void Draw();         
    }


    
class ConcreteComponent : Component
    
{
        
private string strName;
        
public ConcreteComponent(string s)
        
{
            strName 
= s;            
        }


        
public override void Draw()
        
{
            Console.WriteLine(
"ConcreteComponent - {0}", strName);            
        }
        
    }


    
abstract class Decorator : Component
    
{
        
protected Component ActualComponent;

        
public void SetComponent(Component c)
        
{
            ActualComponent 
= c;
        }

        
public override void Draw()
        
{
            
if (ActualComponent != null)
                ActualComponent.Draw();        
        }

    }


    
class ConcreteDecorator : Decorator 
    
{
        
private string strDecoratorName;
        
public ConcreteDecorator (string str)
        
{
            
// how decoration occurs is localized inside this decorator
            
// For this demo, we simply print a decorator name
            strDecoratorName = str; 
        }

        
public override void Draw()
        
{
            CustomDecoration();
            
base.Draw();
        }

        
void CustomDecoration()
        
{
            Console.WriteLine(
"In ConcreteDecorator: decoration goes here");
            Console.WriteLine(
"{0}", strDecoratorName);
        }

    }


    
    
/// <summary>
    
///    Summary description for Client.
    
/// </summary>

    public class Client
    
{
        Component Setup() 
        
{
            ConcreteComponent c 
= new ConcreteComponent("This is the real component");

            ConcreteDecorator d 
= new ConcreteDecorator("This is a decorator for the component");

            d.SetComponent(c);

            
return d;
        }

        
        
public static int Main(string[] args)
        
{
            Client client 
= new Client();
            Component c 
= client.Setup();    

            
// The code below will work equally well with the real component, 
            
// or a decorator for the component

            c.Draw();
            
            
return 0;
        }

    }

}


更好的例子区别于代理模式:
装饰模式,对相同性质的东东的更好的一个抽象.
代理模式只是代理,所代理的对象可以有类的父子关系,但是只有一个类对象.
// Decorator pattern -- Real World example  


using System;
using System.Collections;

namespace DoFactory.GangOfFour.Decorator.RealWorld
{

  
// MainApp test application 

  
class MainApp
  
{
    
static void Main()
    
{
      
// Create book 
      Book book = new Book ("Worley""Inside ASP.NET"10);
      book.Display();

      
// Create video 
      Video video = new Video ("Spielberg""Jaws"2392);
      video.Display();

      
// Make video borrowable, then borrow and display 
      Console.WriteLine("\nMaking video borrowable:");

      Borrowable borrowvideo 
= new Borrowable(video);
      borrowvideo.BorrowItem(
"Customer #1");
      borrowvideo.BorrowItem(
"Customer #2");

      borrowvideo.Display();

      
// Wait for user 
      Console.Read();
    }

  }


  
// "Component" 

  
abstract class LibraryItem
  
{
    
private int numCopies;

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


    
public abstract void Display();
  }


  
// "ConcreteComponent" 

  
class Book : LibraryItem
  
{
    
private string author;
    
private string title;

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


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

  }


  
// "ConcreteComponent" 

  
class Video : LibraryItem
  
{
    
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;
    }


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

  }


  
// "Decorator" 

  
abstract class Decorator : LibraryItem
  
{
    
protected LibraryItem libraryItem;

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


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

  }


  
// "ConcreteDecorator" 

  
class Borrowable : Decorator
  
{
    
protected ArrayList borrowers = new ArrayList();

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


    
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: " + borrower);
      }

    }

  }

}

 

Output
Book ------
Author: Worley
Title: Inside ASP.NET
# Copies: 10

Video -----
Director: Spielberg
Title: Jaws
# Copies: 23
Playtime: 92


Making video borrowable:

Video -----
Director: Spielberg
Title: Jaws
# Copies: 21
Playtime: 92

borrower: Customer #1
borrower: Customer #2

posted on 2006-01-03 15:47 梦在天涯 阅读(741) 评论(3)  编辑 收藏 引用 所属分类: Design pattern

评论

# re: 模式设计c#--结构型--decorator 2006-04-24 15:04 梦在天涯

装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。  回复  更多评论   

# re: 模式设计c#--结构型--decorator 2006-04-24 15:10 梦在天涯

装饰模式应当在什么情况下使用
在以下情况下应当使用装饰模式:

需要扩展一个类的功能,或给一个类增加附加责任。
需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。  回复  更多评论   

# re: 模式设计c#--结构型--decorator 2006-04-24 15:14 梦在天涯

使用装饰模式的优点和缺点
使用装饰模式主要有以下的优点:

装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错。
使用装饰模式主要有以下的缺点:

由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1784901
  • 排名 - 5

最新评论

阅读排行榜