定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计原则:将变化部分提取出来进行封装、针对接口编程、多用组合,使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”。
有新类型的观察者出现,主题不需要修改代码,只要新的类实现观察者接口,并且注册成为观察者即可,主题不在乎其他,只会发送通知给所有实现了观察者接口的对象。
设计原则:为了交互对象之间的松耦合设计而努力。
在不修改被装饰者对象代码的情况下,动态地将责任附加到对象上。通过继承扩展被装饰者的行为,可以在被装饰者的行为前面/后面加上自己的行为。装饰者会导致设计中出现许多小对象。
设计原则:对扩展开放-对修改关闭
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰者模式 { public class Program { static void Main(string[] args) { Beverage beverage = new CaramelMilkTea(); beverage = new Pearl(beverage); beverage = new Mesona(beverage); Console.WriteLine(beverage.GetDescription() + " ¥" + beverage.Cost()); ; Beverage beverage1 = new LightOolongMilkTea(); beverage1 = new Pearl(beverage1); beverage1 = new RedBean(beverage1); beverage1 = new NataDeCoco(beverage1); beverage1.SetSize(1); Console.WriteLine(beverage1.GetDescription() + " ¥" + beverage1.Cost()); Beverage beverage2 = new Ovaltine(); beverage2 = new NataDeCoco(beverage2); beverage2 = new NataDeCoco(beverage2); beverage2 = new Mesona(beverage2); beverage2.SetSize(2); Console.WriteLine(beverage2.GetDescription() + " ¥" + beverage2.Cost()); Beverage beverage3 = new TeaMacchiato(); Console.WriteLine(beverage3.GetDescription() + " ¥" + beverage3.Cost()); Console.ReadKey(); } } public abstract class Beverage { protected string description; protected int beverageSize = 0; public virtual string GetDescription() { switch (beverageSize) { case 0: return "中杯 " + description; case 1: return "大杯 " + description; case 2: return "超大杯 " + description; default: return "中杯 " + description; } } public virtual int GetSize() { return beverageSize; } public virtual void SetSize(int size) { beverageSize = size; } public abstract double Cost(); } #region 饮料代码 public class CaramelMilkTea : Beverage { public CaramelMilkTea() { description = "焦糖奶茶"; } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 10; else if (beverageSize == 1) return 12; else if (beverageSize == 2) return 14; return 10; } } public class LightOolongMilkTea : Beverage { public LightOolongMilkTea() { description = "四季奶青"; } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 9; else if (beverageSize == 1) return 13; else if (beverageSize == 2) return 15; return 9; } } public class TeaMacchiato : Beverage { public TeaMacchiato() { description = "红茶玛奇朵"; } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 11; else if (beverageSize == 1) return 14; else if (beverageSize == 2) return 16; return 11; } } public class Ovaltine : Beverage { public Ovaltine() { description = "阿华田"; } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 12; else if (beverageSize == 1) return 15; else if (beverageSize == 2) return 18; return 12; } } #endregion // 调料抽象类 public abstract class CondimentDecorator : Beverage { protected Beverage beverage; } #region 调料代码 public class Pearl : CondimentDecorator { public Pearl(Beverage beverage) { this.beverage = beverage; } public override string GetDescription() { return beverage.GetDescription() + ",珍珠"; } public override int GetSize() { return beverage.GetSize(); } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 2.0 + beverage.Cost(); else if (beverageSize == 1) return 2.5 + beverage.Cost(); else if (beverageSize == 2) return 3.0 + beverage.Cost(); return 2.0 + beverage.Cost(); } public override void SetSize(int size) { beverage.SetSize(size); } } public class Mesona : CondimentDecorator { public Mesona(Beverage beverage) { this.beverage = beverage; } public override string GetDescription() { return beverage.GetDescription() + ",仙草"; } public override int GetSize() { return beverage.GetSize(); } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 1.5 + beverage.Cost(); else if (beverageSize == 1) return 2.0 + beverage.Cost(); else if (beverageSize == 2) return 2.5 + beverage.Cost(); return 1.5 + beverage.Cost(); } public override void SetSize(int size) { beverage.SetSize(size); } } public class NataDeCoco : CondimentDecorator { public NataDeCoco(Beverage beverage) { this.beverage = beverage; } public override string GetDescription() { return beverage.GetDescription() + ",椰果"; } public override int GetSize() { return beverage.GetSize(); } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 2.0 + beverage.Cost(); else if (beverageSize == 1) return 3.0 + beverage.Cost(); else if (beverageSize == 2) return 4.0 + beverage.Cost(); return 2.0 + beverage.Cost(); } public override void SetSize(int size) { beverage.SetSize(size); } } public class RedBean : CondimentDecorator { public RedBean(Beverage beverage) { this.beverage = beverage; } public override string GetDescription() { return beverage.GetDescription() + ",红豆"; } public override int GetSize() { return beverage.GetSize(); } public override double Cost() { int beverageSize = GetSize(); if (beverageSize == 0) return 1.0 + beverage.Cost(); else if (beverageSize == 1) return 1.5 + beverage.Cost(); else if (beverageSize == 2) return 2.0 + beverage.Cost(); return 1.0 + beverage.Cost(); } public override void SetSize(int size) { beverage.SetSize(size); } } #endregion }
在原有的基础上添加饮料容量大小,使得饮料以及调料根据容量收费,需要在基类加上GetSize()和SetSize()方法,并且在调料装饰者类中需要重写GetSize()的方法使其获取其引用的Beverage对象的GetSize()方法,而不是直接获取其继承的父类的GetSize()方法。
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
将一个类的接口,转换成客户期望的另一个接口。(装饰者将一个对象包装起来以增加新的行为)
适配器模式的意图是转换接口符合客户的期望。
实现一个适配器,继承客户接口,引用被适配者对象,将工作委托给被适配者执行。
提供一个统一的接口,用来访问子系统中的一群接口。
外观模式的意图是统一和简化接口,将客户从组件的子系统中解耦。
实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。(类中包含子系统的引用)
"最少知识"原则:只和你的密友谈话(减少对象之间的交互,只留下几个“密友”)
在一个方法中定义一个算法的骨架,而将一些步奏延迟到子类中。
钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现,由子类去决定覆不覆盖它。
策略方式和模板方式都是封装算法,一个用组合(组合的类实现了整个算法),另一个用继承(子类只是填补一些算法步奏)。
提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示(把遍历的任务放在迭代器上,而不是集合上,简化集合的实现)。
允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
原文:https://www.cnblogs.com/zhengzc/p/8596504.html