设计模式之装饰者模式

本文介绍装饰者模式的基本概念,通过UML类图展示其结构,并提供C#代码示例,演示如何为对象动态添加职责,避免使用子类扩展功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Decorator Design Pattern

definition

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Frequency of use:  nbsp;medium

UML class diagram

participants

    The classes and/or objects participating in this pattern are:

  • Component   (LibraryItem)
    • defines the interface for objects that can have responsibilities added to them dynamically.
  • ConcreteComponent   (Book, Video)
    • defines an object to which additional responsibilities can be attached.
  • Decorator   (Decorator)
    • maintains a reference to a Component object and defines an interface that conforms to Component's interface.
  • ConcreteDecorator   (Borrowable)
    • adds responsibilities to the component.

sample code in C#

This structural code demonstrates the Decorator pattern which dynamically adds extra functionality to an existing object.

Hide code

// Decorator pattern -- Structural example

using System;

namespace DoFactory.GangOfFour.Decorator.Structural
{

   // MainApp test application

   class MainApp
  {
     static void Main()
    {
       // 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();

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

   // "Component"

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

   // "ConcreteComponent"

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

   // "Decorator"

   abstract class Decorator : Component
  {
     protected Component component;

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

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

   // "ConcreteDecoratorA"

   class ConcreteDecoratorA : Decorator
  {
     private string addedState;

     public override void Operation()
    {
       base.Operation();
      addedState = "New State";
      Console.WriteLine("ConcreteDecoratorA.Operation()");
    }
  }

   // "ConcreteDecoratorB"

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

     void AddedBehavior()
    {
    }
  }
}

Output
ConcreteComponent.Operation()
ConcreteDecoratorA.Operation()
ConcreteDecoratorB.Operation()




This real-world code demonstrates the Decorator pattern in which 'borrowable' functionality is added to existing library items (books and videos).

Hide code

// 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", 23, 92);
      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
    {
       get{ return 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

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值