装饰模式(Decorator Pattern)

Posted LoveTomato

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰模式(Decorator Pattern)相关的知识,希望对你有一定的参考价值。

模式定义

装饰模式(Decorator Pattern)
动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。

UML类图

  • 抽象构件(Component) 需要被装饰的类,定义了对象的接口,装饰器可以给它增加额外的职责(方法)
  • 具体构建(Concrete Component)抽象构件的子类,实现了接口, 实现具体的抽象方法逻辑(而为方法添加职责,添加职责交给具体装饰者)
  • 抽象装饰类(Decorator) 抽象构件的子类且关联抽象构件类型变量( 调用原有方法,再修改或添加职责
  • 具体装饰类(Concrete Decorator) 实现为抽象类型方法添加或修改职责

代码结果

  public static class DecoratorApp
    {
        public static void Run()
        {
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();

            d1.SetComponent(c);
            d2.SetComponent(d1);

            d2.Operation();

            Console.ReadKey();
        }
    }
    public abstract class Componet
    {
        public abstract void Operation();
    }
    public class ConcreteComponent : Componet
    {
        public override void Operation()
        {
            Console.WriteLine("Concrete Component.Operation()");
        }
    }
    public abstract class Decorator : Componet
    {
        protected Componet component;

        public void SetComponent(Componet component)
        {
            this.component = component;
        }
        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }
    public class ConcreteDecoratorA : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            Console.WriteLine("Concrete DecoratorA.Operation()");
        }
    }
    public class ConcreteDecoratorB : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            Console.WriteLine("Concrete DecoratorB.Operation()");
            AddedBehavior();
        }
        void AddedBehavior()
        {
            Console.WriteLine("add behavior");
        }
    }

情景模式

这里以图书馆借阅为例,图书馆可借阅的有书和光盘,将书和光盘抽象为可借阅的东西。通过装饰类为书和光盘添加不同借阅功能。

  public static class RealWorldDecoratorApp
    {
        public static void Run()
        {
            Book book = new Book() { Author = "Worley", Title = "Inside ASP.NET", NumCopies = 10 };
            book.Display();

            Video video = new Video() { Director = "Spielberg", Title = "Jaws", NumCopies = 23, PlayTime = 92 };
            video.Display();

            Console.WriteLine("\\nMaking video borrowable:");

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

            borrowvideo.Display();
        }
    }
    public abstract class LibraryItem
    {
        public int NumCopies { get; set; }
        public abstract void Display();
    }
    public class Book : LibraryItem
    {
        public string Author { get; set; }
        public string Title { get; set; }

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

    public class Video : LibraryItem
    {
        public string Director { get; set; }
        public string Title { get; set; }

        public int PlayTime { get; set; }

        public override void Display()
        {
            Console.WriteLine("\\nVideo-----");
            Console.WriteLine("Director:{0}", this.Director);
            Console.WriteLine("Title:{0}", this.Title);
            Console.WriteLine("# Copies:{0}", NumCopies);
            Console.WriteLine("Playtime:{0}", this.PlayTime);
        }
    }
    public abstract class Decorator : LibraryItem
    {
        protected LibraryItem libraryItem;
        public Decorator(LibraryItem libraryItem)
        {
            this.libraryItem = libraryItem;
        }
        public override void Display()
        {
            libraryItem.Display();
        }
    }
    public class Borrowable : Decorator
    {
        protected List<string> borrowers = new List<string>();
        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);
            }
        }
    }

以上是关于装饰模式(Decorator Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

装饰模式(decorator-pattern)

装饰模式(decorator-pattern)

Decorator Pattern(装饰模式)

Head First设计模式之装饰者模式(Decorator Pattern)

装饰模式(Decorator Pattern)

设计模式-装饰模式(Decorator Pattern)