Head First 设计模式 笔记

策略模式

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

设计原则:将变化部分提取出来进行封装、针对接口编程、多用组合,使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”。

观察模式

有新类型的观察者出现,主题不需要修改代码,只要新的类实现观察者接口,并且注册成为观察者即可,主题不在乎其他,只会发送通知给所有实现了观察者接口的对象。

设计原则:为了交互对象之间的松耦合设计而努力。

装饰者模式

在不修改被装饰者对象代码的情况下,动态地将责任附加到对象上。通过继承扩展被装饰者的行为,可以在被装饰者的行为前面/后面加上自己的行为。装饰者会导致设计中出现许多小对象。

设计原则:对扩展开放-对修改关闭

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()方法。

定义工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

适配器模式

将一个类的接口,转换成客户期望的另一个接口。(装饰者将一个对象包装起来以增加新的行为)

适配器模式的意图是转换接口符合客户的期望。

实现一个适配器,继承客户接口,引用被适配者对象,将工作委托给被适配者执行。

外观模式

提供一个统一的接口,用来访问子系统中的一群接口。 

外观模式的意图是统一和简化接口,将客户从组件的子系统中解耦。

实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。(类中包含子系统的引用)

"最少知识"原则:只和你的密友谈话(减少对象之间的交互,只留下几个“密友”)

模板方法模式

在一个方法中定义一个算法的骨架,而将一些步奏延迟到子类中。

钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现,由子类去决定覆不覆盖它。

策略方式和模板方式都是封装算法,一个用组合(组合的类实现了整个算法),另一个用继承(子类只是填补一些算法步奏)。

迭代器模式

提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示(把遍历的任务放在迭代器上,而不是集合上,简化集合的实现)。

组合模式

允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

猜你喜欢

转载自www.cnblogs.com/zhengzc/p/8596504.html