GOF 23种设计模式

SunnyFan大约 95 分钟约 28360 字

GOF 23种设计模式

23类

设计模式(GOF)分为三种类型,共23类。

单例模式 (Singleton)

保证一个类仅有一个实例,且该类能自行创建这个实例,并提供一个访问它的全局访问点。单例模式是最简单的设计模式之一。

单例模式的实现:
懒汉式:该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。代码如下:

{
   /// <summary>
   /// 单例类:一个构造对象很耗时耗资源类型
   /// 
   /// 懒汉式
   /// </summary>
   public sealed class Singleton
   {
       /// <summary>
       /// 对象会持有资源
       /// </summary>
       private List<string> ConnList = new List<string>()
       {
           "这里是数据库连接1",
           "这里是数据库连接2",
           "这里是数据库连接3",
           "这里是数据库连接4",
           "这里是数据库连接5"//一些其他资源
       };

       /// <summary>
       /// 构造函数耗时耗资源
       /// </summary>
       private Singleton()
       {
           long lResult = 0;
           for (int i = 0; i < 10000000; i++)
           {
               lResult += i;
           }
           Thread.Sleep(1000);
           Console.WriteLine($"{this.GetType().Name}被构造一次");
       }

       private static Singleton _Singleton = null;
       private static readonly object Singleton_Lock = new object();
       public static Singleton CreateInstance()
       {
           //开始多线程初始化---lock锁定--线程请求锁--开始判断创建
           //以上多线程都结束后---再来多个线程请求呢?--都需要等待锁
           //--拿到锁--进去判断--不为空--返回对象--。。。。
           //有点浪费,不需要等待锁,直接判断就行了
           if (_Singleton == null)
           {
               lock (Singleton_Lock)//可以保证任意时刻只有一个线程进入,其他线程等待
               {
                   if (_Singleton == null)//这个判断不能去掉,保证只初始化一次
                   {
                       _Singleton = new Singleton();
                   }
               }
           }
           return _Singleton;
       }

       public static void DoNothing()
       { }

       public void Show()
       {
           Console.WriteLine($"这里是{this.GetType().Name}.Show");
       }

       public int Num = 0;//不是线程安全的  10000个线程同时来+1  结果一定小于10000
       /// <summary>
       /// 一个操作,有个计数
       /// </summary>
       public void Invoke()
       {
           this.Num++;
       }

   }
}

如果编写的是多线程程序,则不要删除上例代码中的关键字 volatile 和 synchronized,否则将存在线程非安全的问题。如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。

饿汉式:该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。

{
   /// <summary>
   /// 饿汉式
   /// </summary>
   public sealed class SingletonSecond
   {
       /// <summary>
       /// 对象会持有资源
       /// </summary>
       private List<string> ConnList = new List<string>()
       {
           "这里是数据库连接1",
           "这里是数据库连接2",
           "这里是数据库连接3",
           "这里是数据库连接4",
           "这里是数据库连接5"//一些其他资源
       };

       /// <summary>
       /// 构造函数耗时耗资源
       /// </summary>
       private SingletonSecond()
       {
           long lResult = 0;
           for (int i = 0; i < 10000000; i++)
           {
               lResult += i;
           }
           Thread.Sleep(1000);
           Console.WriteLine($"{this.GetType().Name}被构造一次");
       }

       private static SingletonSecond _SingletonSecond = null;
       /// <summary>
       /// 静态构造函数:由CLR保证,在第一次使用到这个类型之前,自动被调用且只调用一次
       /// 很多初始化都可以写在这里
       /// </summary>
       static SingletonSecond()
       {
           _SingletonSecond = new SingletonSecond();
       }
       public static SingletonSecond CreateInstance()
       {
           return _SingletonSecond;
       }
       public static void DoNothing()
       { }
       public void Show()
       {
           Console.WriteLine($"这里是{this.GetType().Name}.Show");
       }

       public void Log(string text)
       {

       }

   }
}
{
    /// <summary>
    /// 饿汉式
    /// </summary>
    public sealed class SingletonThird
    {
        /// <summary>
        /// 对象会持有资源
        /// </summary>
        private List<string> ConnList = new List<string>()
        {
            "这里是数据库连接1",
            "这里是数据库连接2",
            "这里是数据库连接3",
            "这里是数据库连接4",
            "这里是数据库连接5"//一些其他资源
        };

        /// <summary>
        /// 构造函数耗时耗资源
        /// </summary>
        private SingletonThird()
        {
            long lResult = 0;
            for (int i = 0; i < 10000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(1000);
            Console.WriteLine($"{this.GetType().Name}被构造一次");
        }
        /// <summary>
        /// 静态字段:由CLR保障,在第一次使用这个类型之前,会自动初始化且只初始化一次
        /// </summary>
        private static SingletonThird _SingletonThird = new SingletonThird();
        public static SingletonThird CreateInstance()
        {
            return _SingletonThird;
        }

        public void Show()
        {
            Console.WriteLine($"这里是{this.GetType().Name}.Show");
        }

        public void Log(string text)
        {

        }

    }
}

饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。

原型模式 (Prototype)

用原型实例指定创建对象的种类,并且通过复制这个原型来创建一个和原型相同或相似的新对象。

{
    public class SerializeHelper
    {
        public static string Serializable(object target)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, target);

                return Convert.ToBase64String(stream.ToArray());
            }
        }
        public static T Derializable<T>(string target)
        {
            byte[] targetArray = Convert.FromBase64String(target);

            using (MemoryStream stream = new MemoryStream(targetArray))
            {
                return (T)(new BinaryFormatter().Deserialize(stream));
            }
        }
        public static T DeepClone<T>(T t)
        {
            return Derializable<T>(Serializable(t));
        }
    }
}

{
    /// <summary>
    /// 原型类
    /// </summary>
    [Serializable]
    public class StudentPrototype
    {
        /// <summary>
        /// 1 构造函数私有化--避免随意构造
        /// </summary>
        private StudentPrototype()
        {
            Thread.Sleep(2000);
            long lResult = 0;
            for (int i = 0; i < 1000000; i++)
            {
                lResult += i;
            }
            Console.WriteLine("{0}被构造..", this.GetType().Name);
        }
        /// <summary>
        /// 3 私有的静态字段--内存唯一,不会释放,且在第一次使用这个类被初始化且只初始化一次
        /// </summary>
        private static StudentPrototype _Student = new StudentPrototype()
        {
            Id = 123,
            Name = "ywa",
            Class = new Class()
            {
                ClassId = 1,
                ClassName = ".Net班"
            }
        };
        /// <summary>
        /// 2 公开的静态方法来提供实例
        /// </summary>
        /// <returns></returns>
        public static StudentPrototype CreateInstance()
        {
            StudentPrototype student = (StudentPrototype)_Student.MemberwiseClone();
            //MemberwiseClone:内存拷贝,不走构造函数,直接内存copy,所以没有性能损失;而且产生的是新对象----浅拷贝--只拷贝引用
            student.Class = new Class()
            {
                ClassId = student.Class.ClassId,
                ClassName = student.Class.ClassName
            };
            //把引用的地址重新赋值,完成了深copy--不仅拷贝引用,还得拷贝引用类型的值
            //麻烦? 晚点还有答案
            return student;
        }
        //deepcopy:1 直接new  2 子类型提供原型方式  3 序列化反序列化

        public static StudentPrototype CreateInstanceSerialize()
        {
            return SerializeHelper.DeepClone<StudentPrototype>(_Student);
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public Class Class { get; set; }

        public void Study()
        {
            Console.WriteLine("{0}在学习.net设计模式特训", this.Name);
        }

    }
    [Serializable]
    public class Class
    {
        public int ClassId { get; set; }
        public string ClassName { get; set; }
    }

}

简单工厂模式 (SimpleFactory Mode)

定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。(它不属于23种模式里面的)

{
    public interface IRace
    {
        void ShowKing();
    }
}
 
{
    /// <summary>
    /// War3种族之一
    /// </summary>
    public class Human : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Sky");
        }
    }
}

{
    /// <summary>
    /// War3种族之一
    /// </summary>
    public class NE : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Moon");
        }
    }
}

{
    /// <summary>
    /// War3种族之一
    /// </summary>
    public class Undead : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "GoStop");
        }
    }
}

{
    /// <summary>
    /// War3种族之一
    /// </summary>
    public class ORC : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Grubby");
        }
    }
}

{
    public class Five : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Alex");
        }
    }
}

{
    /// <summary>
    /// 
    /// </summary>
    public class ObjectFactory
    {
        public static IRace CreateInstance(RaceType raceType)
        {


            IRace race = null;
            switch (raceType)
            {
                case RaceType.Human:
                    race = new Human();
                    break;
                case RaceType.NE:
                    race = new NE();
                    break;
                case RaceType.ORC:
                    race = new ORC();
                    break;
                case RaceType.Undead:
                    race = new Undead();
                    break;
                default:
                    throw new Exception("wrong raceType");
            }
            return race;
        }

        private static string IRaceType = ConfigurationManager.AppSettings["IRaceType"];
        public static IRace CreateInstanceConfig()
        {
            RaceType raceType = (RaceType)Enum.Parse(typeof(RaceType), IRaceType);
            return CreateInstance(raceType);
        }

        //真正的把细节依赖给去掉,意味着不能直接new,那怎么获取对象? 反射

        private static string IRaceTypeReflection = ConfigurationManager.AppSettings["IRaceTypeReflection"];
        public static IRace CreateInstanceConfigReflection()
        {
            Assembly assembly = Assembly.Load(IRaceTypeReflection.Split(',')[1]);
            Type type = assembly.GetType(IRaceTypeReflection.Split(',')[0]);
            return (IRace)Activator.CreateInstance(type);
        }

        //1  可配置后,如果一个接口,可能需要不同的实例?
        //2  今天只是创建Race,就需要一个方法;那项目中有N多个接口,难道每个接口都去创建一个工厂方法吗?
        //3  IOC&&DI。。。。
    }
    public enum RaceType
    {
        Human,
        NE,
        ORC,
        Undead
    }
}

工厂方法模式 (Factory Method)

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public interface IFactory
    {
        IRace CreateInstance();
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class FiveFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Five();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class HumanFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Human();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class NEFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new NE();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class ORCFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new ORC();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class UndeadFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Undead();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类    框架原始工厂
    /// </summary>
    public class SixFactory : IFactory
    {
        public virtual IRace CreateInstance()
        {
            IRace race = new Six("Yoyo", 123, new Undead(), new Undead(), new Human(), new NE());//一些具体业务
            return race;
        }
    }


    /// <summary>
    /// 我们扩展的工厂
    /// </summary>
    public class SixFactoryExtend : SixFactory
    {
        public override IRace CreateInstance()
        {
            Console.WriteLine("这里是我们扩展的工厂");

            return base.CreateInstance();
        }
    }

}

{
    /// <summary>
    /// war3种族之一
    /// </summary>
    public class Five : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name);
        }
    }
}

{
    /// <summary>
    /// war3种族之一
    /// </summary>
    public class Six : IRace
    {
        public Six(string name, int id, object special, IRace race1, IRace race2, IRace race3)
        {

        }

        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name);
        }
    }
}

{
    IRace human = new Human();
    IRace undead = new Undead();
    IRace ne = new NE();
    IRace orc = new ORC();
}

抽象工厂模式 (Abstract Factory)

是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

模式的实现:

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public interface IFactory
    {
        IRace CreateInstance();
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class FiveFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Five();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class HumanFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Human();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class NEFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new NE();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class ORCFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new ORC();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类
    /// </summary>
    public class UndeadFactory : IFactory
    {
        public IRace CreateInstance()
        {
            IRace race = new Undead();
            return race;
        }
    }

}

{
    /// <summary>
    /// 工厂类    框架原始工厂
    /// </summary>
    public class SixFactory : IFactory
    {
        public virtual IRace CreateInstance()
        {
            IRace race = new Six("Yoyo", 123, new Undead(), new Undead(), new Human(), new NE());//一些具体业务
            return race;
        }
    }


    /// <summary>
    /// 我们扩展的工厂
    /// </summary>
    public class SixFactoryExtend : SixFactory
    {
        public override IRace CreateInstance()
        {
            Console.WriteLine("这里是我们扩展的工厂");

            return base.CreateInstance();
        }
    }

}

{
    /// <summary>
    /// war3种族之一
    /// </summary>
    public class Five : IRace
    {
        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name);
        }
    }
}

{
    /// <summary>
    /// war3种族之一
    /// </summary>
    public class Six : IRace
    {
        public Six(string name, int id, object special, IRace race1, IRace race2, IRace race3)
        {

        }

        public void ShowKing()
        {
            Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name);
        }
    }
}

{
    IFactory humanFactory = new HumanFactory();
    IRace human = humanFactory.CreateInstance();

    IFactory fiveFactory = new FiveFactory();
    IRace five = fiveFactory.CreateInstance();

    IFactory sixFactory = new SixFactoryExtend();// new SixFactory();
    IRace six = sixFactory.CreateInstance();
}

建造者模式 (Builder)

指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

模式的实现:

//产品角色:包含多个组成部件的复杂对象。
{
    public class Car
    {
        public Car(Engine engine, Light light, Wheels wheels)
        { }

        public string Name { get; set; }
    }
}

{
    public class Engine
    {
        public string Name { get; set; }
    }
}

{
    public class Light
    {
        public string Name { get; set; }
    }
}

{
    public class Wheels
    {
        public string Name { get; set; }
    }
}
//抽象建造者:包含创建产品各个子部件的抽象方法。
{
    /// <summary>
    /// 工人抽象
    /// </summary>
    public abstract class AbstractBuilder
    {

        public abstract void Engine();

        public abstract void Wheels();

        public abstract void Light();

        public abstract Car Car();
    }
}
// 具体建造者:实现了抽象建造者接口。
{
    /// <summary>
    /// 比亚迪工人
    /// </summary>
    public class BuilderBYD : AbstractBuilder
    {
        private Engine _Engine = null;
        private Wheels _Wheels = null;
        private Light _Light = null;

        public override void Engine()
        {
            this._Engine = new Engine()
            {
                Name = "_Engine"
            };

            Console.WriteLine("{0} build Engine", this.GetType().Name);
        }

        public override void Wheels()
        {
            this._Wheels = new Wheels()
            {
                Name = "_Wheels"
            };
            Console.WriteLine("{0} build Wheels", this.GetType().Name);
        }

        public override void Light()
        {
            this._Light = new Light()
            {
                Name = "_Light"
            };
            Console.WriteLine("{0} build Light", this.GetType().Name);
        }

        public override Car Car()
        {
            Console.WriteLine("组装 {0} {1} {2}", this._Engine, this._Light, this._Wheels);
            Console.WriteLine("{0} build 比亚迪*唐", this.GetType().Name);

            return new Car(this._Engine, this._Light, this._Wheels)
            {
                Name = "比亚迪*唐"
            };
        }
    }
}

{
    /// <summary>
    /// 福特工人
    /// </summary>
    public class BuilderFord : AbstractBuilder
    {
        private Engine _Engine = null;
        private Wheels _Wheels = null;
        private Light _Light = null;

        public override void Engine()
        {
            this._Engine = new Engine()
            {
                Name = "_Engine"
            };

            Console.WriteLine("{0} build Engine", this.GetType().Name);
        }

        public override void Wheels()
        {
            this._Wheels = new Wheels()
            {
                Name = "_Wheels"
            };
            Console.WriteLine("{0} build Wheels", this.GetType().Name);
        }

        public override void Light()
        {
            this._Light = new Light()
            {
                Name = "_Light"
            };
            Console.WriteLine("{0} build Light", this.GetType().Name);
        }

        public override Car Car()
        {
            Console.WriteLine("组装 {0} {1} {2}", this._Engine, this._Light, this._Wheels);
            Console.WriteLine("{0} build Mondeo", this.GetType().Name);

            return new Car(this._Engine, this._Light, this._Wheels)
            {
                Name = "Mondeo"
            };
        }
    }
}

{
    /// <summary>
    /// 大众工人
    /// </summary>
    public class BuilderVolkswagen : AbstractBuilder
    {
        private Engine _Engine = null;
        private Wheels _Wheels = null;
        private Light _Light = null;

        public override void Engine()
        {
            this._Engine = new Engine()
            {
                Name = "_Engine"
            };

            Console.WriteLine("{0} build Engine", this.GetType().Name);
        }

        public override void Wheels()
        {
            this._Wheels = new Wheels()
            {
                Name = "_Wheels"
            };
            Console.WriteLine("{0} build Wheels", this.GetType().Name);
        }

        public override void Light()
        {
            this._Light = new Light()
            {
                Name = "_Light"
            };
            Console.WriteLine("{0} build Light", this.GetType().Name);
        }

        public override Car Car()
        {
            Console.WriteLine("组装 {0} {1} {2}", this._Engine, this._Light, this._Wheels);
            Console.WriteLine("{0} build CC", this.GetType().Name);

            return new Car(this._Engine, this._Light, this._Wheels)
            {
                Name = "CC"
            };
        }
    }
}
//指挥者:调用建造者中的方法完成复杂对象的创建。
{
    public class Director
    {
        private AbstractBuilder _AbstractBuilder = null;
        public Director(AbstractBuilder builder)
        {
            this._AbstractBuilder = builder;
        }

        public Car GetCar()
        {
            this._AbstractBuilder.Engine();
            this._AbstractBuilder.Wheels();
            this._AbstractBuilder.Light();

            return this._AbstractBuilder.Car();
        }
    }
}
//客户类
{
    Console.WriteLine("**********************************");
    {
        AbstractBuilder builder = new BuilderFord();
        builder.Engine();
        builder.Wheels();
        builder.Light();
        builder.Car();
    }
    Console.WriteLine("**********************************");
    {
        AbstractBuilder builder = new BuilderBYD();
        builder.Engine();
        builder.Wheels();
        builder.Light();
        builder.Car();
    }
    Console.WriteLine("**********************************");
    {
        AbstractBuilder builder = new BuilderBYD();
        Director director = new Director(builder);
        director.GetCar();
    }
    Console.WriteLine("**********************************");
    {
        AbstractBuilder builder = new BuilderVolkswagen();
        Director director = new Director(builder);
        director.GetCar();
    }
}

代理模式 (Proxy)

为其他对象提供一个代理以控制对这个对象的访问。

模式的实现:

{
    /// <summary>
    /// 第三方存储---保证数据不丢失--可以放进来--可以获取---缓存
    /// </summary>
    public class CustomCache
    {
        private static Dictionary<string, object> CustomCacheDictionary = new Dictionary<string, object>();

        public static void Add(string key, object oValue)
        {
            CustomCacheDictionary.Add(key, oValue);
        }

        public static T GetT<T>(string key)
        {
            return (T)CustomCacheDictionary[key];
        }

        public static bool Exists(string key)
        {
            return CustomCacheDictionary.ContainsKey(key);
        }

    }
}

{
    /// <summary>
    /// 业务接口
    /// </summary>
    public interface ISubject
    {
        /// <summary>
        /// get
        /// </summary>
        /// <returns></returns>
        List<string> GetSomethingLong();

        /// <summary>
        /// do
        /// </summary>
        void DoSomethingLong();
    }
}

{
    public class ProxySubject : ISubject
    {
        private static ISubject _iSubject = null;// new RealSubject();
        private void Init()
        {
            _iSubject = new RealSubject();//把一开始就构造对象  延迟到 调用Init才会初始化
        }

        public void DoSomethingLong()
        {
            try
            {
                object user = CallContext.GetData("CurrentUser");
                if (user == null)
                {
                    throw new Exception("没有权限访问");
                }


                Console.WriteLine("prepare DoSomethingLong");
                if (_iSubject == null)
                {
                    this.Init();
                }

                _iSubject.DoSomethingLong();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                //throw;
            }

        }

        public List<string> GetSomethingLong()
        {
            try
            {
                object user = CallContext.GetData("CurrentUser");
                if (user == null)
                {
                    throw new Exception("没有权限访问");
                }

                Console.WriteLine("prepare GetSomethingLong");
                string key = $"{nameof(ProxySubject)}_{nameof(GetSomethingLong)}";
                List<string> result = new List<string>();
                if (!CustomCache.Exists(key))
                {
                    if (_iSubject == null)
                    {
                        this.Init();
                    }

                    result = _iSubject.GetSomethingLong();
                    CustomCache.Add(key, result);
                }
                else
                {
                    result = CustomCache.GetT<List<string>>(key);
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}

{
    /// <summary>
    /// 一个耗时耗资源的对象方法
    /// 一个第三方封装的类和方法
    /// </summary>
    public class RealSubject : ISubject
    {
        #region MyRegion
        //private RealSubject()
        //{
        //    Thread.Sleep(2000);
        //    long lResult = 0;
        //    for (int i = 0; i < 100000000; i++)
        //    {
        //        lResult += i;
        //    }
        //    Console.WriteLine("RealSubject被构造。。。");
        //}
        //private static RealSubject realSubject = new RealSubject();
        //public static RealSubject CreateInstance()
        //{
        //    return realSubject;
        //}
        #endregion

        public RealSubject()
        {
            Thread.Sleep(2000);
            long lResult = 0;
            for (int i = 0; i < 100000000; i++)
            {
                lResult += i;
            }
            Console.WriteLine("RealSubject被构造。。。");
        }

        /// <summary>
        /// 一个耗时的复杂查询
        /// </summary>
        public List<string> GetSomethingLong()
        {
            //Console.WriteLine("prepare GetSomethingLong");
            //try
            //{
            //}
            //catch (Exception)
            //{
            //    throw;
            //}



            Console.WriteLine("读取大文件信息。。。");
            Thread.Sleep(1000);
            Console.WriteLine("数据库大数据查询。。。");
            Thread.Sleep(1000);
            Console.WriteLine("调用远程接口。。。");
            Thread.Sleep(1000);

            Console.WriteLine("最终合成得到结果。。一堆的商品列表");
            return new List<string>() { "123", "456", "789" };
        }

        /// <summary>
        /// 一个耗时的复杂操作
        /// </summary>
        public void DoSomethingLong()
        {
            //Console.WriteLine("prepare DoSomethingLong");

            Console.WriteLine("下订单。。。");
            Thread.Sleep(1000);
            Console.WriteLine("短信通知。。。");
            Thread.Sleep(1000);
        }
    }
}

{
    {

        ISubject subject = new ProxySubject();
        CallContext.SetData("CurrentUser", "面团儿");
        subject.GetSomethingLong();
    }
    {
        ISubject subject = new ProxySubject();
        subject.GetSomethingLong();
    }
}

适配器模式 (Adapter)

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

模式的实现:

{
    /// <summary>
    /// 
    /// </summary>
    public class CacheHelper
    {
        public void AddRedis<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void DeleteRedis<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void UpdateRedis<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void QueryRedis<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
}

{
    /// <summary>
    /// 数据访问接口
    /// </summary>
    public interface IHelper
    {
        void Add<T>();
        void Delete<T>();
        void Update<T>();
        void Query<T>();
    }
}

{
    public class MysqlHelper : IHelper
    {
        public void Add<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void Delete<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void Update<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void Query<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
}

{
    public class OracleHelper : IHelper
    {
        public void Add<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void Delete<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void Update<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void Query<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
}

{
    /// <summary>
    /// 第三方提供的  openstack  servicestack
    /// 不能修改
    /// </summary>
    public class RedisHelper
    {
        public void AddRedis<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void DeleteRedis<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void UpdateRedis<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void QueryRedis<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
}

{
    /// <summary>
    /// 通过继承 类适配器模式
    /// </summary>
    public class RedisHelperClass : RedisHelper, IHelper
    {
        public void Add<T>()
        {
            base.AddRedis<T>();
        }

        public void Delete<T>()
        {
            base.DeleteRedis<T>();
        }

        public void Update<T>()
        {
            base.UpdateRedis<T>();
        }

        public void Query<T>()
        {
            base.QueryRedis<T>();
        }
    }
}

{
    /// <summary>
    /// 通过组合  对象适配器模式
    /// 
    /// 组合优于继承
    /// </summary>
    public class RedisHelperObject : IHelper
    {
        //private RedisHelper _RedisHelper = new RedisHelper();
        private RedisHelper _RedisHelper = null;
        public RedisHelperObject(RedisHelper redisHelper)
        {
            this._RedisHelper = redisHelper;
        }

        public RedisHelperObject()
        {
            this._RedisHelper = new RedisHelper();
        }

        public void Add<T>()
        {
            this._RedisHelper.AddRedis<T>();
        }

        public void Delete<T>()
        {
            this._RedisHelper.DeleteRedis<T>();
        }

        public void Update<T>()
        {
            this._RedisHelper.UpdateRedis<T>();
        }

        public void Query<T>()
        {
            this._RedisHelper.QueryRedis<T>();
        }
    }
}

{
    public class SqlserverHelper : IHelper
    {
        public void Add<T>()
        {
            Console.WriteLine("This is {0} Add", this.GetType().Name);
        }
        public void Delete<T>()
        {
            Console.WriteLine("This is {0} Delete", this.GetType().Name);
        }
        public void Update<T>()
        {
            Console.WriteLine("This is {0} Update", this.GetType().Name);
        }
        public void Query<T>()
        {
            Console.WriteLine("This is {0} Query", this.GetType().Name);
        }
    }
}

{
    Console.WriteLine("*****************************");
    {
        IHelper helper = new SqlserverHelper();
        helper.Add<Program>();
        helper.Delete<Program>();
        helper.Update<Program>();
        helper.Query<Program>();
    }
    Console.WriteLine("*****************************");
    {
        IHelper helper = new MysqlHelper();
        helper.Add<Program>();
        helper.Delete<Program>();
        helper.Update<Program>();
        helper.Query<Program>();
    }
    Console.WriteLine("*****************************");
    {
        IHelper helper = new OracleHelper();
        helper.Add<Program>();
        helper.Delete<Program>();
        helper.Update<Program>();
        helper.Query<Program>();
    }
    Console.WriteLine("*****************************");
    {
        IHelper helper = new RedisHelperClass(); //new RedisHelper();
        helper.Add<Program>();
        helper.Delete<Program>();
        helper.Update<Program>();
        helper.Query<Program>();
    }
    {
        RedisHelperClass helper = new RedisHelperClass();
        helper.Add<Program>();
    }
    Console.WriteLine("*****************************");
    {
        IHelper helper = new RedisHelperObject(); //new RedisHelper();
        helper.Add<Program>();
        helper.Delete<Program>();
        helper.Update<Program>();
        helper.Query<Program>();
    }
}

桥接模式 (Bridge)

将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

模式的实现:

{
    public interface ISystem
    {
        string System();
        string Version();
    }
}

{
    public class AndroidSystem : ISystem
    {

        public string System()
        {
            return "Android";
        }
        public string Version()
        {
            return "6.0";
        }

    }
}

{
    public class IOSSystem : ISystem
    {

        public string System()
        {
            return "IOS";
        }
        public string Version()
        {
            return "9.4";
        }

    }
}

{
    public class WinphoneSystem : ISystem
    {

        public string System()
        {
            return "Winphone";
        }
        public string Version()
        {
            return "10.0";
        }

    }
}

{
    /// <summary>
    /// 抽象父类
    /// </summary>
    public abstract class BasePhoneBridge
    {
        public int Price { get; set; }
        public ISystem SystemVersion { get; set; }


        ///// <summary>
        ///// 操作系统
        ///// </summary>
        ///// <returns></returns>
        //public abstract string System();
        ///// <summary>
        ///// 系统版本
        ///// </summary>
        ///// <returns></returns>
        //public abstract string Version();
        /// <summary>
        /// 打电话
        /// </summary>
        public abstract void Call();
        /// <summary>
        /// 发短信
        /// </summary>
        public abstract void Text();
    }
}

{
    public class GalaxyBridge : BasePhoneBridge
    {

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }



    }
}

{
    public class iPhoneBridge : BasePhoneBridge
    {
        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }



    }
}

{
    public class LumiaBridge : BasePhoneBridge
    {
        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.SystemVersion.System(), this.SystemVersion.Version());
        }


    }
}

{
    /// <summary>
    /// 抽象父类
    /// </summary>
    public abstract class BasePhone
    {
        public int Price { get; set; }
        /// <summary>
        /// 操作系统
        /// </summary>
        /// <returns></returns>
        public abstract string System();
        /// <summary>
        /// 系统版本
        /// </summary>
        /// <returns></returns>
        public abstract string Version();
        /// <summary>
        /// 打电话
        /// </summary>
        public abstract void Call();
        /// <summary>
        /// 发短信
        /// </summary>
        public abstract void Text();
    }
}

{
    public class Galaxy : BasePhone
    {

        public override string System()
        {
            return "Android";
        }
        public override string Version()
        {
            return "6.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class GalaxyIOS : BasePhone
    {

        public override string System()
        {
            return "IOS";
        }
        public override string Version()
        {
            return "9.3";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class GalaxyWinphone : BasePhone
    {

        public override string System()
        {
            return "Winphone";
        }
        public override string Version()
        {
            return "10.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class iPhone : BasePhone
    {
        public override string System()
        {
            return "IOS";
        }
        public override string Version()
        {
            return "9.3";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    /// <summary>
    /// 使用Android系统的iphone手机
    /// </summary>
    public class iPhoneAndroid : BasePhone
    {
        public override string System()
        {
            return "Android";
        }
        public override string Version()
        {
            return "6.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    /// <summary>
    /// 使用Android系统的iphone手机
    /// </summary>
    public class iPhoneWinphone : BasePhone
    {
        public override string System()
        {
            return "Winphone";
        }
        public override string Version()
        {
            return "10.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class Lumia : BasePhone
    {

        public override string System()
        {
            return "Winphone";
        }
        public override string Version()
        {
            return "10.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class LumiaAndroid : BasePhone
    {

        public override string System()
        {
            return "Android";
        }
        public override string Version()
        {
            return "6.0";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    public class LumiaIOS : BasePhone
    {

        public override string System()
        {
            return "IOS";
        }
        public override string Version()
        {
            return "9.3";
        }

        public override void Call()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Call", this.GetType().Name, this.System(), this.Version());
        }

        public override void Text()
        {
            Console.WriteLine("Use OS {0}.{1}.{2} Text", this.GetType().Name, this.System(), this.Version());
        }


    }
}

{
    Console.WriteLine("******************************");
    {
        BasePhone phone = new iPhone();
        phone.Call();
        phone.Text();
    }
    Console.WriteLine("******************************");
    {
        BasePhone phone = new Galaxy();
        phone.Call();
        phone.Text();
    }
    Console.WriteLine("******************************");
    {
        BasePhone phone = new iPhoneAndroid();
        phone.Call();
        phone.Text();
    }
    Console.WriteLine("******************************");
    {
        BasePhone phone = new GalaxyIOS();
        phone.Call();
        phone.Text();
    }
    ISystem android = new AndroidSystem();
    ISystem ios = new IOSSystem();
    ISystem winphone = new WinphoneSystem();
    Console.WriteLine("******************************");
    {
        BasePhoneBridge phone = new GalaxyBridge();
        phone.SystemVersion = android;
        phone.Call();
        phone.Text();
    }
    {
        BasePhoneBridge phone = new GalaxyBridge();
        phone.SystemVersion = ios;
        phone.Call();
        phone.Text();
    }
    {
        BasePhoneBridge phone = new GalaxyBridge();
        phone.SystemVersion = winphone;
        phone.Call();
        phone.Text();
    }
}

装饰器模式 (Decorator)

指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

模式的实现:

{
    /// <summary>
    /// 学员基类
    /// </summary>
    public abstract class AbstractStudent
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public abstract void Study();
        public void Show()
        {
            Console.WriteLine("This is {0}", this.Name);
        }
    }
}

{
    /// <summary>
    /// 组合+继承
    /// </summary>
    public class BaseDecorator : AbstractStudent
    {
        private AbstractStudent _Student = null;
        public BaseDecorator(AbstractStudent student)
        {
            this._Student = student;
        }
        public override void Study()
        {
            //Console.WriteLine("$$$$$$$$$$$$$$$$$$$$$$");
            this._Student.Study();
            //Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&");
        }
    }
}

{
    /// <summary>
    /// 组合+继承
    /// </summary>
    public class StudentDecoratorAnswer : BaseDecorator
    {
        public StudentDecoratorAnswer(AbstractStudent student)
            : base(student)
        {
        }
        public override void Study()
        {
            base.Study();
            Console.WriteLine("老师课后在线答疑");
        }
    }
}

{
    /// <summary>
    /// 组合+继承
    /// </summary>
    public class StudentDecoratorHomework : BaseDecorator
    {
        public StudentDecoratorHomework(AbstractStudent student)
            : base(student)
        {
        }
        public override void Study()
        {
            base.Study();
            Console.WriteLine("巩固练习,学以致用");
        }
    }
}

{
    /// <summary>
    /// 组合+继承
    /// </summary>
    public class StudentDecoratorPreview : BaseDecorator
    {
        public StudentDecoratorPreview(AbstractStudent student)
            : base(student)
        {
        }
        public override void Study()
        {
            Console.WriteLine("课前完成预习准备");
            base.Study();

            Console.WriteLine("课后做好学习笔记");
        }
    }
}

{
    /// <summary>
    /// 组合+继承
    /// </summary>
    public class StudentDecoratorVideo : BaseDecorator
    {
        public StudentDecoratorVideo(AbstractStudent student)
            : base(student)
        {
        }
        public override void Study()
        {
            base.Study();
            Console.WriteLine("获取视频");
        }
    }
}

{
    /// <summary>
    /// 公开课学员
    /// </summary>
    public class StudentFree : AbstractStudent
    {
        //public int Id { get; set; }
        //public string Name { get; set; }
        public override void Study()
        {
            Console.WriteLine("周一到周六上午十点到十一点跟着Eleven老师直播学习.Net高级开发");

            //Console.WriteLine("获取视频+课件+代码的回看");
        }

        //public void Show()
        //{
        //    Console.WriteLine("This is {0}", this.Name);
        //}
    }
    //开闭原则---对扩展开放  对修改关闭
    //如果有功能扩展,OOP就不能不去修改现有代码,破坏现有的封装--不那么好
    //能不能不修改原有代码,但是也能扩展功能

    //刚才只增加了一个视频代码回看  组合 或者 继承都实现了
    //我希望能增加更多功能,  作业巩固练习  +  老师课后答疑  +   课前预习

    //直接放在一个里面,是写死的;而且的  要求顺序灵活订制;

    //一个业务功能在完成后,希望能够任意的扩展功能,订制顺序,而且不破坏封装

    public class StudentFreeVideo : StudentFree
    {
        public override void Study()
        {
            //Console.WriteLine("课前预习");
            base.Study();
            Console.WriteLine("获取视频");
            //Console.WriteLine("作业巩固练习");
            //Console.WriteLine("老师课后答疑");
        }
    }
    public class StudentCombination
    {
        private AbstractStudent _Student = null;
        public StudentCombination(AbstractStudent student)
        {
            this._Student = student;
        }
        public void Study()
        {
            this._Student.Study();
            Console.WriteLine("获取视频");
        }
    }
}

{
    /// <summary>
    /// vip学员
    /// </summary>
    public class StudentVip : AbstractStudent
    {
        //public int Id { get; set; }
        //public string Name { get; set; }
        public override void Study()
        {
            Console.WriteLine("学习.Net高级开发");
        }
        //public void Show()
        //{
        //    Console.WriteLine("This is {0}", this.Name);
        //}
    }
}

{
    Console.WriteLine("*********************");
    AbstractStudent student = new StudentFree()
    {
        Id = 123,
        Name = "勇往直前"
    };
    //BaseDecorator decorator = new BaseDecorator(student);
    //AbstractStudent decorator = new BaseDecorator(student);//里氏替换原则
    //decorator.Study();
    student = new BaseDecorator(student);//把引用类型变量的引用换个地址
    student = new StudentDecoratorPreview(student);
    student = new StudentDecoratorAnswer(student);
    student = new StudentDecoratorHomework(student);
    student = new StudentDecoratorVideo(student);
    student.Study();
    //真的搞定了BT需求,可以任意的定制功能扩展,要几个  什么顺序,都可以随意来
    //中途加入的小伙伴儿,可以找课堂的小助教获取视频代码
}

外观模式 (Facade)

是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性

模式的实现:

{
    public interface ILogisticsSystem
    {
        bool CheckLogistics(int productId, int cityId);
        void NewLogistics(int productId, int cityId);
    }
}

{
    public class LogisticsSystem : ILogisticsSystem
    {
        public bool CheckLogistics(int productId, int cityId)
        {
            //远程接口
            //本地缓存
            //搜索引擎
            return true;
        }
        public void NewLogistics(int productId, int cityId)
        {
            Console.WriteLine("{0}城市 商品{1}的物流订单", cityId, productId);
        }
    }
}

{
    public interface IOrderSystem
    {
        bool CheckOrder(int userId, int productId);
        void NewOrder(int userId, int productId);
    }
}

{
    public class OrderSystem : IOrderSystem
    {
        public bool CheckOrder(int userId, int productId)
        {
            return true;
        }
        public void NewOrder(int userId, int productId)
        {
            Console.WriteLine("{0}给商品{1}下订单", userId, productId);
        }
    }
}

{
    public interface IStorageSystem
    {
        bool CheckStorage(int productId);
    }
}

{
    public class StorageSystem : IStorageSystem
    {
        public bool CheckStorage(int productId)
        {
            return true;
        }
    }
}

{
    public interface IUserSystem
    {
        bool CheckUser(int id);
    }
}

{
    public class UserSystem : IUserSystem
    {

        public UserSystem(string name)
        { }

        public bool CheckUser(int id)
        {
            return id > 100;
        }
    }
}

{
    /// <summary>
    /// 门面模式 通常是单例的
    /// </summary>
    public class FacadeCenter
    {
        public class IdModel
        {
            public int Userid { get; set; }
            public int productId { get; set; }
            public int cityId { get; set; }
        }

        private static FacadeCenter _FacadeCenter = new FacadeCenter();
        private FacadeCenter()
        { }

        public static FacadeCenter CreateInstance()
        {
            return _FacadeCenter;
        }

        public void NewOrder(int userId, int productId, int cityId)
        {
            IUserSystem iUserSystem = new UserSystem("为什么");
            IStorageSystem iStorageSystem = new StorageSystem();
            ILogisticsSystem iLogisticsSystem = new LogisticsSystem();
            IOrderSystem iOrderSystem = new OrderSystem();

            if (!iUserSystem.CheckUser(userId))
            {
                Console.WriteLine("用户检测失败");
            }
            else if (!iStorageSystem.CheckStorage(productId))
            {
                Console.WriteLine("仓储检测失败");
            }
            else if (!iLogisticsSystem.CheckLogistics(productId, cityId))
            {
                Console.WriteLine("物流检测失败");
                //不能直接去物流增加一个检测失败的数据记录
                //而是通过物流系统的方法去做
            }
            else if (!iOrderSystem.CheckOrder(userId, productId))
            {
                Console.WriteLine("订单检测失败");
            }
            else
            {
                iOrderSystem.NewOrder(userId, productId);
                iLogisticsSystem.NewLogistics(productId, cityId);
            }
        }
    }
}


{
    int userId = 123;
    int productId = 12345;
    int cityId = 1;
    FacadeCenter facadeCenter = FacadeCenter.CreateInstance();// new FacadeCenter();
    facadeCenter.NewOrder(userId, productId, cityId);
}

享元模式 (Flyweight)

运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

模式的实现:

{
    /// <summary>
    /// 字母的抽象类
    /// </summary>
    public abstract class BaseWord
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime CreateTime { get; set; }
        public abstract string Get();
    }
}

{
    /// <summary>
    /// 字母的抽象类
    /// </summary>
    public abstract class BaseWord
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime CreateTime { get; set; }
        public abstract string Get();
    }
}

{
    public class L : BaseWord
    {
        /// <summary>
        /// 一个耗时耗资源的构造函数,
        /// 表明构造对象比较消耗资源
        /// </summary>
        public L()
        {
            long lResult = 0;
            for (int i = 0; i < 1000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(1500);
            Console.WriteLine("{0}被构造。。", this.GetType().Name);
        }
        public override string Get()
        {
            return this.GetType().Name;
        }
    }
}

{
    public class N: BaseWord
    {
        /// <summary>
        /// 一个耗时耗资源的构造函数,
        /// 表明构造对象比较消耗资源
        /// </summary>
        public N()
        {
            long lResult = 0;
            for (int i = 0; i < 1000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(1500);
            Console.WriteLine("{0}被构造。。", this.GetType().Name);
        }
        public override string Get()
        {
            return this.GetType().Name;
        }
    }
}

{
    /// <summary>
    /// 这里是单例
    /// </summary>
    public class S : BaseWord
    {
        /// <summary>
        /// 1 一个耗时耗资源的构造函数,
        /// 表明构造对象比较消耗资源
        /// </summary>
        private S()
        {
            long lResult = 0;
            for (int i = 0; i < 1000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(1500);
            Console.WriteLine("{0}被构造。。", this.GetType().Name);
        }
        /// <summary>
        /// 3
        /// </summary>
        private static S _S = null;
        static S()
        {
            _S = new S();
        }
        /// <summary>
        /// 2 
        /// </summary>
        /// <returns></returns>
        public static S CreateInstance()
        {
            return _S;
        }

        public override string Get()
        {
            return this.GetType().Name;
        }
    }
}

{
    public class V : BaseWord
    {
        /// <summary>
        /// 一个耗时耗资源的构造函数,
        /// 表明构造对象比较消耗资源
        /// </summary>
        public V()
        {
            long lResult = 0;
            for (int i = 0; i < 1000000; i++)
            {
                lResult += i;
            }
            Thread.Sleep(1500);
            Console.WriteLine("{0}被构造。。", this.GetType().Name);
        }
        public override string Get()
        {
            return this.GetType().Name;
        }
    }
}

{
    public class OtherClass
    {
        public string teacherOther = "Eleven";
        public string teacherPlus = "Elev" + "en";
        public static void Show()
        {
            BaseWord e1 = new E();
            BaseWord l = new L();
            BaseWord e2 = new E();
            BaseWord v = new V();
            BaseWord e3 = new E();
            BaseWord n = new N();

            Console.WriteLine("{0}{1}{2}{3}{4}{5}",
                e1.Get(), l.Get(), e2.Get(), v.Get(), e3.Get(), n.Get());
        }
    }
}

{
    /// <summary>
    /// 1 统一
    /// </summary>
    public class FlyweightFactory
    {
        /// <summary>
        /// 准备个容器,数据复用
        /// </summary>
        private static Dictionary<WordType, BaseWord> FlyweightFactoryDictionary = new Dictionary<WordType, BaseWord>();
        private readonly static object FlyweightFactoryLock = new object();
        /// <summary>
        /// 1  5个线程同时执行,字典为空,所以会同时构造5次字母E
        /// 2  最后只打印了一个Eleven,因为其他线程挂掉了--因为字典添加时异常了
        /// 3  2个L属于小概率事件,前2个线程是同时添加E,所以都没失败,所以L有两个,
        ///    但是到了L,又冲突了
        /// 4 异常我怎么没看到?子线程的异常是获取不到的,除非waitall
        /// </summary>
        /// <param name="wordType"></param>
        /// <returns></returns>
        public static BaseWord CreateWord(WordType wordType)
        {
            if (!FlyweightFactoryDictionary.ContainsKey(wordType))
                //是为了优化性能,避免对象已经被初始化后,再次请求还需要等待锁
            {
                lock (FlyweightFactoryLock)//Monitor.Enter,保证方法体只有一个线程可以进入
                {
                    if (!FlyweightFactoryDictionary.ContainsKey(wordType))
                    {
                        BaseWord word = null;
                        switch (wordType)
                        {
                            case WordType.E:
                                word = new E();
                                break;
                            case WordType.L:
                                word = new L();
                                break;
                            case WordType.V:
                                word = new V();
                                break;
                            case WordType.N:
                                word = new N();
                                break;
                            default:
                                throw new Exception("wrong wordtype!");
                        }
                        FlyweightFactoryDictionary.Add(wordType, word);
                    }
                }
            }
            return FlyweightFactoryDictionary[wordType];
        }
    }

    public enum WordType
    {
        E,
        L,
        V,
        N
    }
}

{
    {
        //BaseWord e1 = FlyweightFactory.CreateWord(WordType.E);
        //BaseWord e2 = new E();
        //BaseWord e3 = new E();
        //BaseWord e4 = FlyweightFactory.CreateWord(WordType.E);
        //Console.WriteLine(object.ReferenceEquals(e1, e2));
        //Console.WriteLine(object.ReferenceEquals(e1, e3));
        //Console.WriteLine(object.ReferenceEquals(e1, e4));
        ////e属于引用类型  new个对象等于去内存开辟一块儿空间,变量保存的是个引用,指向该内存     object.ReferenceEquals专门比较引用地址
    }
    {
        //string类型是引用类型
        string teacherOpen = "Eleven";
        string teacherVip = "Eleven";
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,teacherVip)==={object.ReferenceEquals(teacherOpen, teacherVip)}");
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,new OtherClass().teacherOther)==={object.ReferenceEquals(teacherOpen, new OtherClass().teacherOther)}");
        //TT   FF  TF  FT 正确答案是TT
        //string类型在内存分配时,使用了享元模式,所以是T
        //只要是同一个进程,分配Eleven都是同一个内存地址的
        Console.WriteLine("***************************************");
        string teacherFormat = string.Format("Ele{0}", "ven");
        string lastPart = "ven";
        string teacherCombination = "Ele" + lastPart;
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,teacherFormat)...{object.ReferenceEquals(teacherOpen, teacherFormat)}");
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,teacherCombination)...{object.ReferenceEquals(teacherOpen, teacherCombination)}");
        Console.WriteLine($"object.ReferenceEquals(teacherFormat,teacherCombination)...{object.ReferenceEquals(teacherFormat, teacherCombination)}");
        //TTT  FFF TFT....    正确答案 FFF
        //分配Eleven都是同一个内存地址的,但是这两个都不是分配Eleven,而是部分分配,虽然最终结果是Eleven,但是没法重用
        Console.WriteLine("***************************************");
        string teacherPlus = "Ele" + "ven";
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,teacherPlus)...{object.ReferenceEquals(teacherOpen, teacherPlus)}");
        Console.WriteLine($"object.ReferenceEquals(teacherOpen,new OtherClass().teacherPlus)...{object.ReferenceEquals(teacherOpen, new OtherClass().teacherPlus)}");
        Console.WriteLine($"object.ReferenceEquals(teacherPlus,new OtherClass().teacherPlus)...{object.ReferenceEquals(teacherPlus, new OtherClass().teacherPlus)}");
        //TTT  FFF TFT....    正确答案 TTT
        //编译器优化,string teacherPlus = "Ele" + "ven"; 等同于string teacherPlus = "Eleven";
    }
}

组合模式 (Composite)

将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

模式的实现:

{
    /// <summary>
    /// 机构/个人
    /// </summary>
    public abstract class AbstractDomain
    {
        public string Name { get; set; }
        public double Percent { get; set; }
        public abstract void Commission(double total);

        public abstract void AddChild(Domain domainChild);

    }
}

{
    /// <summary>
    /// 机构/个人
    /// </summary>
    public class Domain : AbstractDomain
    {
        private List<Domain> DomainChildList = new List<Domain>();
        public override void AddChild(Domain domainChild)
        {
            this.DomainChildList.Add(domainChild);
        }

        public override void Commission(double total)
        {
            double result = total * this.Percent / 100;
            Console.WriteLine("this {0} 提成 {1}", this.Name, result);

            foreach (var domainChild in DomainChildList)
            {
                domainChild.Commission(result);
            }

        }

    }
}

{
    /// <summary>
    /// 机构/个人
    /// </summary>
    public class DomainLeaf : AbstractDomain
    {
        public override void Commission(double total)
        {
            double result = total * this.Percent / 100;
            Console.WriteLine("this {0} 提成 {1}", this.Name, result);
        }

        public override void AddChild(Domain domainChild)
        {
            throw new Exception("这里不能AddChild");
        }
    }
}

{
    /// <summary>
    /// 递归
    /// </summary>
    public class Recursion
    {
        /// <summary>
        /// 给一个根目录,获取全部的文件夹
        /// </summary>
        /// <param name="rootPath"></param>
        /// <returns></returns>
        public static List<DirectoryInfo> GetDirectoryList(string rootPath)
        {
            List<DirectoryInfo> dirList = new List<DirectoryInfo>();

            DirectoryInfo dirRoot = new DirectoryInfo(rootPath);//根目录
            dirList.Add(dirRoot);

            GetDirectoryListChild(dirList, dirRoot);

            //DirectoryInfo[] dirList1 = dirRoot.GetDirectories();//一级子目录
            //dirList.AddRange(dirList1);

            //foreach (var dir1 in dirList1)
            //{
            //    DirectoryInfo[] dirList2 = dir1.GetDirectories();//二级子目录
            //    dirList.AddRange(dirList2);

            //    foreach (var dir2 in dirList2)
            //    {
            //        DirectoryInfo[] dirList3 = dir2.GetDirectories();//三级子目录
            //        dirList.AddRange(dirList3);
            //    }
            //}

            return dirList;
        }

        /// <summary>
        /// 找出当前文件夹的子文件夹,放入结果容器
        /// </summary>
        /// <param name="dirList">结果容器</param>
        /// <param name="dirParent">当前文件夹</param>
        private static void GetDirectoryListChild(List<DirectoryInfo> dirList, DirectoryInfo dirParent)
        {
            DirectoryInfo[] dirListChild = dirParent.GetDirectories();//一级子目录
            dirList.AddRange(dirListChild);

            foreach (var dir in dirListChild)
            {
                //DirectoryInfo[] dirListChild1 = dir.GetDirectories();//二级子目录
                //dirList.AddRange(dirListChild1);

                GetDirectoryListChild(dirList, dir);
            }
        }
    }

}

{
    double total = 1000000;
    Domain domain = BuildTree();
    domain.Commission(total);

private static Domain BuildTree()
{
    Domain domain = new Domain()
    {
        Name = "能有的提成收入",
        Percent = 10
    };
    #region
    Domain domain1 = new Domain()
    {
        Name = "CEO",
        Percent = 30
    };
    Domain domain2 = new Domain()
    {
        Name = "各部门共有",
        Percent = 70
    };
    Domain domain21 = new Domain()
    {
        Name = "实施",
        Percent = 20
    };
    Domain domain22 = new Domain()
    {
        Name = "测试",
        Percent = 10
    };
    Domain domain23 = new Domain()
    {
        Name = "销售",
        Percent = 30
    };
    Domain domain24 = new Domain()
    {
        Name = "开发",
        Percent = 40
    };
    Domain domain241 = new Domain()
    {
        Name = "经理",
        Percent = 20
    };
    Domain domain242 = new Domain()
    {
        Name = "主管",
        Percent = 15
    };
    Domain domain243 = new Domain()
    {
        Name = "开发团队",
        Percent = 65
    };
    Domain domain2431 = new Domain()
    {
        Name = "项目组1",
        Percent = 50
    };
    Domain domain2432 = new Domain()
    {
        Name = "项目组2",
        Percent = 50
    };
    Domain domain24321 = new Domain()
    {
        Name = "项目经理",
        Percent = 20
    };
    Domain domain24322 = new Domain()
    {
        Name = "开发人员",
        Percent = 80
    };
    Domain domain243221 = new Domain()
    {
        Name = "高级开发人员",
        Percent = 40
    };
    Domain domain243222 = new Domain()
    {
        Name = "中级开发人员",
        Percent = 30
    };
    Domain domain243223 = new Domain()
    {
        Name = "初级开发人员",
        Percent = 20
    };
    Domain domain243224 = new Domain()
    {
        Name = "实习生",
        Percent = 10
    };
    Domain domain2432241 = new Domain()
    {
        Name = "实习生1",
        Percent = 25
    };
    Domain domain2432242 = new Domain()
    {
        Name = "实习生2",
        Percent = 25
    };
    Domain domain2432243 = new Domain()
    {
        Name = "实习生3",
        Percent = 25
    };
    Domain domain2432244 = new Domain()
    {
        Name = "实习生4",
        Percent = 25
    };
    domain243224.AddChild(domain2432241);
    domain243224.AddChild(domain2432242);
    domain243224.AddChild(domain2432243);
    domain243224.AddChild(domain2432244);
    domain24322.AddChild(domain243221);
    domain24322.AddChild(domain243222);
    domain24322.AddChild(domain243223);
    domain24322.AddChild(domain243224);
    domain2432.AddChild(domain24321);
    domain2432.AddChild(domain24322);
    domain243.AddChild(domain2431);
    domain243.AddChild(domain2432);
    domain24.AddChild(domain241);
    domain24.AddChild(domain242);
    domain24.AddChild(domain243);
    domain2.AddChild(domain21);
    domain2.AddChild(domain22);
    domain2.AddChild(domain23);
    domain2.AddChild(domain24);
    domain.AddChild(domain1);
    domain.AddChild(domain2);
    #endregion
    return domain;
}
}

模板方法模式 (Template Method)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模式的实现:

{
    /// <summary>
    /// 银行客户端模拟
    /// </summary>
    public abstract class BaseClient
    {
        /// <summary>
        /// 登陆查询功能
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="password"></param>
        public void Query(int id, string name, string password)
        {
            if (this.CheckUser(id, password))
            {
                double balance = this.QueryBalance(id);
                double interest = this.CalculateInterest(balance);
                this.Show(name, balance, interest);
            }
            else
            {
                Console.WriteLine("账户密码错误");
            }
        }

        /// <summary>
        /// 用户检测
        /// </summary>
        /// <param name="id"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool CheckUser(int id, string password)
        {
            return DateTime.Now < DateTime.Now.AddDays(1);
        }

        /// <summary>
        /// 查询余额
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public double QueryBalance(int id)
        {
            return new Random().Next(10000, 1000000);
        }

        /// <summary>
        /// 获取利率,计算利息
        /// 定存  0.05
        /// 活期  0.03
        /// 再增加一个
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public abstract double CalculateInterest(double balance);

        /// <summary>
        /// 展示下
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="balance"></param>
        /// <param name="interest"></param>
        public virtual void Show(string name, double balance, double interest)
        {
            Console.WriteLine("尊敬的{0}客户,你的账户余额为:{1},利息为{2}",
                name, balance, interest);

            //Console.WriteLine("尊贵的{0}客户,你的账户余额为:{1},利息为{2}",
            //    name, balance, interest);
            //Console.WriteLine("理财有风险,入行需谨慎");
        }
    }
}

{
    /// <summary>
    /// 银行客户端模拟
    /// </summary>
    public class Client
    {
        /// <summary>
        /// 登陆查询功能
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="password"></param>
        public void Query(int id, string name, string password)
        {
            if (this.CheckUser(id, password))
            {
                double balance = this.QueryBalance(id);
                double interest = this.CalculateInterest(balance);
                this.Show(name, balance, interest);
            }
            else
            {
                Console.WriteLine("账户密码错误");
            }
        }

        /// <summary>
        /// 用户检测
        /// </summary>
        /// <param name="id"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool CheckUser(int id, string password)
        {
            if (true)
            { }
            else
            { }
            return DateTime.Now < DateTime.Now.AddDays(1);
        }

        /// <summary>
        /// 查询余额
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public double QueryBalance(int id)
        {
            return new Random().Next(10000, 1000000);
        }

        /// <summary>
        /// 获取利率,计算利息
        /// 定存  0.05
        /// 活期  0.03
        /// 再增加一个
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public double CalculateInterest(double balance)
        {
            return balance * 0.03;
        }


        /// <summary>
        /// 展示下
        /// </summary>
        /// <param name="name"></param>
        /// <param name="balance"></param>
        /// <param name="interest"></param>
        public void Show(string name, double balance, double interest)
        {
            if (true)
            { }
            else
            { }
            Console.WriteLine("尊敬的{0}客户,你的账户余额为:{1},利息为{2}",
                name, balance, interest);
        }
    }
}

{
    /// <summary>
    /// 银行客户端模拟
    /// </summary>
    public class ClientCurrent: BaseClient
    {
       
        /// <summary>
        /// 获取利率,计算利息
        /// 定存  0.05
        /// 活期  0.03
        /// 再增加一个
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public override double CalculateInterest(double balance)
        {
            return balance * 0.03;
        }

    }
}

{
    /// <summary>
    /// 银行客户端模拟
    /// </summary>
    public class ClientRegular : BaseClient
    {
        /// <summary>
        /// 获取利率,计算利息
        /// 定存  0.05
        /// 活期  0.03
        /// 再增加一个
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public override double CalculateInterest(double balance)
        {
            return balance * 0.05;
        }
    }
}

{
    /// <summary>
    /// 银行客户端模拟
    /// </summary>
    public class ClientVip : BaseClient
    {
        /// <summary>
        /// 获取利率,计算利息
        /// 定存  0.05
        /// 活期  0.03
        /// 再增加一个
        /// </summary>
        /// <param name="balance"></param>
        /// <returns></returns>
        public override double CalculateInterest(double balance)
        {
            return balance * 0.07;
        }

        public override void Show(string name, double balance, double interest)
        {
            Console.WriteLine("尊贵的{0}客户,你的账户余额为:{1},利息为{2}",
                name, balance, interest);
            Console.WriteLine("理财有风险,入行需谨慎");
        }
    }
}

{
    /// <summary>
    /// 知识同步:普通方法  虚方法  抽象方法
    /// </summary>
    public class MethodTest
    {
        public static void Show()
        {
            #region Abstract

            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");

            //ParentClass p = new ParentClass();//抽象类不能直接实例化
            {
                Console.WriteLine(" ParentClass abstractTest1 = new ChildClass();");
                ParentClass abstractTest1 = new ChildClass();
                abstractTest1.Show();
            }
            {
                Console.WriteLine(" ChildClass abstractTest2 = new ChildClass();");
                ChildClass abstractTest2 = new ChildClass();
                abstractTest2.Show();
            }
            #endregion

            #region Common
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            {
                Console.WriteLine(" NewTest newTest1 = new NewTest();");
                NewTest newTest1 = new NewTest();
                newTest1.Show();
            }
            {
                Console.WriteLine(" NewTest newTest2 = new NewTestChild();");
                NewTest newTest2 = new NewTestChild();
                //普通方法的调用   编译时决定的    左边决定的
                newTest2.Show();
            }
            {
                Console.WriteLine(" NewTestChild newTest3 = new NewTestChild();");
                NewTestChild newTest3 = new NewTestChild();
                newTest3.Show();
            }
            #endregion
            #region Virtual
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            {
                Console.WriteLine(" VirtualTest virtualTest1 = new VirtualTest();");
                VirtualTest virtualTest1 = new VirtualTest();
                virtualTest1.Show();
            }
            {
                Console.WriteLine(" VirtualTest virtualTest2 = new VirtualTestChild();");
                VirtualTest virtualTest2 = new VirtualTestChild();
                //抽象/虚 方法的调用  运行时决定的    右边决定的
                virtualTest2.Show();
            }
            {
                Console.WriteLine(" VirtualTestChild virtualTest3 = new VirtualTestChild();");
                VirtualTestChild virtualTest3 = new VirtualTestChild();
                virtualTest3.Show();
            }

            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");
            Console.WriteLine("*******************************************");

            #endregion

        }
    }

    #region Abstract
    public abstract class ParentClass
    {
        /// <summary>
        /// 抽象方法
        /// </summary>
        public abstract void Show();
    }

    public class ChildClass : ParentClass
    {
        /// <summary>
        /// virtual
        /// </summary>
        public override void Show()
        {
            Console.WriteLine("This is ChildClass");
        }
    }
    #endregion abstract

    #region New
    public class NewTest
    {
        /// <summary>
        /// common
        /// </summary>
        public void Show()
        {
            Console.WriteLine("This is NewTest");
        }
    }

    public class NewTestChild : NewTest
    {

        /// <summary>
        /// new 要不要都没区别 都会隐藏掉父类方法
        /// 不要new会提示警告
        /// </summary>
        public new void Show()//隐藏
        {
            Console.WriteLine("This is NewTestChild");
        }
    }
    #endregion New

    #region Virtual
    public class VirtualTest
    {
        /// <summary>
        /// virtual  虚方法  必须包含实现 但是可以被覆写
        /// </summary>
        public virtual void Show()
        {
            Console.WriteLine("This is VirtualTest");
        }
    }
    public class VirtualTestChild : VirtualTest
    {
        /// <summary>
        /// 可以覆写,也可以不覆写
        /// </summary>
        public override void Show()
        {
            Console.WriteLine("This is VirtualTestChild");
        }
    }
    #endregion Virtual
}

{
    /// <summary>
    /// 1  抽象方法/虚方法/普通方法
    /// 2  模板方法设计模式,钩子方法
    /// 3  模板方法在框架中的应用
    /// 
    /// 设计模式:面向对象语言开发过程中,会遇到各种场景和问题,解决方案和思路沉淀下来  就是设计模式
    ///           套路
    /// 行为型设计模式:关注对象和行为的分离   
    /// 
    /// 场景出发--解决问题--沉淀总结--推广应用
    /// 
    /// 简单、强大、无所不在,框架搭建必备
    /// 模板方法:定义通用处理流程;实现了通用部分;可变部分留作扩展点
    /// 框架搭建:定义业务处理流程;实现了通用部分;可变部分留作扩展点
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                {
                    Console.WriteLine("****************ClientCurrent****************");
                    BaseClient current = new ClientCurrent();
                    current.Query(234, "不可征服", "622611");
                    Thread.Sleep(100);
                }
                {
                    Console.WriteLine("****************ClientCurrent****************");
                    BaseClient regular = new ClientRegular();
                    regular.Query(345, "安安", "765903");
                    Thread.Sleep(100);
                }
                {
                    Console.WriteLine("****************ClientVip****************");
                    BaseClient regular = new ClientVip();
                    regular.Query(345, "半夏", "432178");
                    Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

策略模式 (Strategy)

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,且算法的变化不会影响使用算法的客户。本模式使得算法的变化可独立于使用它的客户。

模式的实现:

{
    public interface ICaculation
    {
        int Caculation(int iInpuLeft, int iInputRight);
    }
}

{
    public class Devision : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            if (iInputRight == 0) throw new Exception();
            return iInpuLeft / iInputRight;
        }
    }
}

{
    public class Minus : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft - iInputRight;
        }
    }
}

{
    public class Mutiply : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft * iInputRight;
        }
    }
}

{
    public class Plus : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft + iInputRight;
        }
    }
}

{
    public class Remainder : ICaculation
    {
        public int Caculation(int iInpuLeft, int iInputRight)
        {
            return iInpuLeft % iInputRight;
        }
    }
}

{
    /// <summary>
    /// 见过哪些context,---httpcontext dbcontext callcontext
    /// HttpContext,ControllerContext,ActionExecutingContext,ActionExecutedContext,ResultExecutingContext,ResulViewContexttExecutedContext,ExceptionContext,
    /// 上下文环境:是为了保存整个请求过程中,全部的信息--中间结果--最终结果
    /// 行为型设计模式的标配,行为会无止境的到处转移,方法需要参数。执行结果
    /// 
    /// 包一层:没有什么技术问题是包一层不能解决的,如果有,再包一层
    /// 中间层,转移调用,核心意义就在于调用环节可以扩展
    /// </summary>
    public class CaculationContext
    {
        private ICaculation _iCaculation = null;
        private int _iInpuLeft = 0;
        private int _iInputRight = 0;
        public CaculationContext(ICaculation caculation, int iInpuLeft, int iInputRight)
        {
            this._iCaculation = caculation;
            this._iInpuLeft = iInpuLeft;
            this._iInputRight = iInputRight;
        }

        private string Para = "";//可能要调用第三方接口

        /// <summary>
        /// 也许调用算法,需要额外的参数信息
        /// </summary>
        /// <returns></returns>
        public int Action()
        {
            try
            {
                Console.WriteLine("Caculation");
                Console.WriteLine(this.Para);
                return this._iCaculation.Caculation(this._iInpuLeft, this._iInputRight);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }

        }
    }
}

{
    /// <summary>
    /// 面向对象语言开发从来不担心代码多,因为可以封装一下
    /// 工厂只是转移了矛盾,并没有消除矛盾
    /// 代码升级跟下象棋是一样的,高手其实就是看得远,能看到3步4步
    /// 代码的升级是一步一步来的,先升级再解决问题,先解决眼前的问题,再解决下一步的问题
    /// 
    /// 会下象棋小伙伴儿刷个6
    /// </summary>
    public class Factory
    {
        /// <summary>
        /// 不仅把对象创建给屏蔽了,而且映射关系也可以配置文件决定了
        /// </summary>
        /// <param name="operate"></param>
        /// <returns></returns>
        public static ICaculation GetCaculationReflection(string operate)
        {
            string key = $"ICaculation{operate}";
            string dllType = ConfigurationManager.AppSettings[key];
            Assembly assembly = Assembly.Load(dllType.Split(',')[1]);
            Type type = assembly.GetType(dllType.Split(',')[0]);
            return (ICaculation)Activator.CreateInstance(type);
        }
        public static ICaculation GetCaculation(string operate)
        {
            ICaculation iCaculation = null;
            switch (operate)
            {
                case "+":
                    iCaculation = new Plus();
                    break;
                case "-":
                    iCaculation = new Minus();
                    break;
                case "*":
                    iCaculation = new Mutiply();
                    break;
                case "/":
                    iCaculation = new Devision();
                    break;
                default:
                    Console.WriteLine("输入符号异常,重新输入");
                    throw new Exception("输入符号异常,重新输入");
            }
            return iCaculation;
        }
    }
}

{
    /// <summary>
    /// 1 策略模式(Strategy)介绍和优缺点
    /// 2 策略模式和简单工厂的结合
    /// 3 策略模式的应用
    /// 
    /// 设计模式:面向对象语言开发过程中,对各种问题和场景的解决方案的沉淀
    ///           ---是解决问题的套路,
    ///           提出场景--解决问题--总结沉淀--推广应用
    /// 行为型设计模式:关注对象和行为的分离
    /// 设计模式都是为了解决一类问题而存在的,往往在解决一类问题的同时会带来的新的问题,会有对应的解决方案。设计模式不是万能的
    /// 
    /// 程序设计:不关系功能性,关注的非功能性的要求,程序的扩展性--可读性--健壮性
    /// 
    /// 策略模式已经完成了!
    /// 策略模式应对业务处理中,会有多种相似处理方式(算法),然后封装成算法+抽象,此外,调用环节也有扩展要求的,来个context
    /// 好处:算法封装,有抽象可以扩展;
    ///       调用环节转移,可以扩展;
    /// 缺陷:上端必须知道全部算法,而且知道映射关系
    /// 最终我们会解决问题,但是这个不属于策略模式
    /// 
    /// 其实一样的功能,可以多样的实现,
    /// 但是不同的实现,真的可以看出不同的水准
    /// 擅长什么,是很容易的暴露的
    /// 看花容易绣花难,
    /// 如果觉得挺有道理,觉得大有收获的,给老师刷个666,点个赞!
    /// 
    /// 今天代码如果需要拿下去重温一下的,视频想看看的,可以加一下课堂的助教老师!
    /// 如果有啥新的想法,或者工作中的一些疑难问题,可以加老师的微信155-2709-5897
    /// 
    /// 扩展性---抽象---反射---动态
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("下面是一个计算器展示demo:");
                while (true)
                {
                    Console.WriteLine("******************************");
                    Console.WriteLine("******************************");
                    Console.WriteLine("******************************");
                    #region UI 前端逻辑 接受用户输入并验证
                    int iInputLeft = 0;
                    int iInputRight = 0;
                    string operate = "";

                    Console.WriteLine("输入第一个数字(整数):");
                    string sInputLeft = Console.ReadLine();
                    if (!int.TryParse(sInputLeft, out iInputLeft))
                    {
                        Console.WriteLine("输入数字无效,请重新输入");
                        continue;
                    }

                    Console.WriteLine("输入计算符号(+-*/):");
                    operate = Console.ReadLine();
                    string CaculationType = System.Configuration.ConfigurationManager.AppSettings["CaculationType"];
                    if (!CaculationType.Split(',').Contains(operate))
                    {
                        Console.WriteLine("输入计算符号无效,请重新输入");
                        continue;
                    }

                    Console.WriteLine("输入第二个数字(整数):");
                    string sInputRight = Console.ReadLine();
                    if (!int.TryParse(sInputRight, out iInputRight))
                    {
                        Console.WriteLine("输入数字无效,请重新输入");
                        continue;
                    }
                    #endregion

                    #region 后台逻辑 业务逻辑
                    int iResult = 0;
                    //switch (operate)//1 业务逻辑都暴露在上端,封装转移一下  POP--OOP
                    //{
                    //    case "+":
                    //        iResult = iInputLeft + iInputRight;
                    //        break;
                    //    case "-":
                    //        iResult = iInputLeft - iInputRight;
                    //        break;
                    //    case "*":
                    //        iResult = iInputLeft * iInputRight;
                    //        break;
                    //    case "/":
                    //        iResult = iInputLeft / iInputRight;
                    //        break;
                    //    default:
                    //        Console.WriteLine("输入符号异常,重新输入");
                    //        continue;
                    //}
                    ICaculation iCaculation = null;
                    //switch (operate)//从POP到OOP,屏蔽细节,
                    //{
                    //    case "+":
                    //        iCaculation = new Plus();
                    //        break;
                    //    case "-":
                    //        iCaculation = new Minus();
                    //        break;
                    //    case "*":
                    //        iCaculation = new Mutiply();
                    //        break;
                    //    case "/":
                    //        iCaculation = new Devision();
                    //        break;
                    //    default:
                    //        Console.WriteLine("输入符号异常,重新输入");
                    //        continue;
                    //}
                    //3 转移了算法创建以及映射关系,封装了一下
                    //iCaculation = Factory.GetCaculation(operate);
                    iCaculation = Factory.GetCaculationReflection(operate);
                    //1 转移了算法逻辑
                    //iResult = iCaculation.Caculation(iInputLeft, iInputLeft);
                    CaculationContext context = new CaculationContext(iCaculation, iInputLeft, iInputRight);
                    //2 转移了算法的调用逻辑
                    iResult = context.Action();

                    Console.WriteLine("计算为: {0}{1}{2}={3}", iInputLeft, operate, iInputRight, iResult);
                    #endregion
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

命令模式 (Command)

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

模式的实现:

{
    public abstract class BaseCommand
    {
        public Document _Document
        {
            get;
            private set;
        }

        public IReceiver _Receiver
        {
            get;
            private set;
        }

        //public BaseCommand(Document doc)
        //{
        //    this._Document = doc;
        //}

        public void Set(Document doc)
        {
            this._Document = doc;
        }

        public void SetReiceiver(IReceiver receiver)
        {
            this._Receiver = receiver;
        }


        public abstract void Excute();
    }
}

{
    public class Document
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public void Read()
        {
            Console.WriteLine("Read");
        }

        public void Write()
        {
            Console.WriteLine("Write");
        }


    }
}

{
    public class Invoker
    {
        private BaseCommand _BaseCommand = null;//可以换成多个命令的集合

        public Invoker(BaseCommand baseCommand)
        {
            this._BaseCommand = baseCommand;
        }

        public void Excute()
        {
            this._BaseCommand.Excute();
        }

    }
}

{
    public class ReadCommand : BaseCommand
    {

        //public ReadCommand(Document doc)
        //    : base(doc)
        //{

        //}


        public override void Excute()
        {
            //log
            this._Receiver.Read();
            //Console.WriteLine("Read");
        }
    }
}

{
    public class SaveCommand : BaseCommand
    {

        //public WriteCommand(Document doc)
        //    : base(doc)
        //{

        //}


        public override void Excute()
        {
            this._Receiver.Save();
            //Console.WriteLine("Save");
        }
    }
}

{
    public class WriteCommand : BaseCommand
    {

        //public WriteCommand(Document doc)
        //    : base(doc)
        //{

        //}


        public override void Excute()
        {
            this._Receiver.Write();
            //Console.WriteLine("Write");
        }
    }
}

{
    public interface IReceiver
    {
        void Read();

        void Write();

        void Save();
    }

    public class Receiver : IReceiver
    {
        public void Read()
        {
            //log好命令
            Console.WriteLine("Read1");
        }

        public void Write()
        {
            Console.WriteLine("Write1");
        }

        public void Save()
        {
            Console.WriteLine("Save1");
        }
    }
    public class ReceiverNew : IReceiver
    {
        public void Read()
        {
            Console.WriteLine("Read2");
        }

        public void Write()
        {
            Console.WriteLine("Write2");
        }

        public void Save()
        {
            Console.WriteLine("Save2");
        }
    }
}

{
    /// <summary>
    /// 1 命令模式介绍和例子
    /// 2 命令模式实现异步队列
    /// 3 数据恢复、命令撤销
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Document document = new Document();
                document.Read();//直接出票,需要10s计算
                document.Write();

                Console.WriteLine("*************");
                Console.WriteLine("Input r w ");
                while (true)
                {
                    string input = Console.ReadLine();

                    //if (input.Equals("r"))
                    //    document.Read();
                    //else if (input.Equals("w"))
                    //    document.Write();
                    //else
                    //    Console.WriteLine("do noting,reinput");


                    string action = ConfigurationManager.AppSettings[input];
                    //if (action.Equals("read"))
                    //    document.Read();
                    //else if (action.Equals("write"))
                    //    document.Write();
                    //else
                    //    Console.WriteLine("do noting,reinput");

                    BaseCommand command = (BaseCommand)Activator.CreateInstance(action.Split(',')[1], action.Split(',')[0]).Unwrap();
                    //保存了一个买票的命令,然后告诉用户在排队了

                    //后台在运行,给你指定票或者没有票
                    IReceiver receiver = new ReceiverNew();//也可以配置+反射
                    command.SetReiceiver(receiver);
                    command.Set(document);
                    //command.Excute();

                    Invoker invoker = new Invoker(command);
                    invoker.Excute();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

责任链模式 (Chain of Responsibility)

为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

模式的实现:

{
    /// <summary>
    /// 审批者抽象父类
    /// </summary>
    public abstract class AbstractAuditor
    {
        public string Name { get; set; }
        public abstract void Audit(ApplyContext context);

        private AbstractAuditor _NextAuditor = null;
        public void SetNext(AbstractAuditor auditor)
        {
            this._NextAuditor = auditor;
        }

        protected void AuditNext(ApplyContext context)
        {
            if (this._NextAuditor != null)
            {
                this._NextAuditor.Audit(context);
            }
        }
    }
}

{
    /// <summary>
    /// 请假申请上下文
    /// 请假条---Context---上下文---保存请求的各种参数-中间值-结果
    /// 
    /// </summary>
    public class ApplyContext
    {
        public int Id { get; set; }
        public string Name { get; set; }
        /// <summary>
        /// 请假时长
        /// </summary>
        public int Hour { get; set; }
        /// <summary>
        /// 请假描述
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 审批结果,默认是false
        /// </summary>
        public bool AuditResult { get; set; }
        /// <summary>
        /// 审批备注
        /// </summary>
        public string AuditRemark { get; set; }
    }
}

{
    /// <summary>
    /// CEO
    /// </summary>
    public class CEO : AbstractAuditor
    {
        //public string Name { get; set; }
        public override void Audit(ApplyContext context)
        {
            Console.WriteLine("这里是CEO {0} 审批", this.Name);
            if (context.Hour <= 128)
            {
                context.AuditResult = true;
                context.AuditRemark = "enjoy your vacation!";
            }
            else
            {
                base.AuditNext(context);
            }
        }
    }
}

{
    /// <summary>
    /// 主管
    /// </summary>
    public class Charge: AbstractAuditor
    {
        //public string Name { get; set; }
        public override void Audit(ApplyContext context)
        {
            Console.WriteLine("这里是主管 {0} 审批", this.Name);
            if (context.Hour <= 16)
            {
                context.AuditResult = true;
                context.AuditRemark = "enjoy your vacation!";
            }
            else
            {
                //AbstractAuditor manager = new Manager()
                //{
                //    Name = "没音"
                //};
                //manager.Audit(context);
                base.AuditNext(context);
            }
        }
    }
}

{
    /// <summary>
    /// 总监
    /// </summary>
    public class Chif : AbstractAuditor
    {
        //public string Name { get; set; }
        public override void Audit(ApplyContext context)
        {
            Console.WriteLine("这里是总监 {0} 审批", this.Name);
            if (context.Hour <= 64)
            {
                context.AuditResult = true;
                context.AuditRemark = "enjoy your vacation!";
            }
            else
            {
                //...
                base.AuditNext(context);
            }
        }
    }
}

{
    /// <summary>
    /// 经理
    /// </summary>
    public class Manager : AbstractAuditor
    {
        //public string Name { get; set; }
        public override void Audit(ApplyContext context)
        {
            Console.WriteLine("这里是经理 {0} 审批", this.Name);
            if (context.Hour <= 32)
            {
                context.AuditResult = true;
                context.AuditRemark = "enjoy your vacation!";
            }
            else
            {
                //AbstractAuditor chif = new Chif()
                //{
                //    Name = "竹林风"
                //};
                //chif.Audit(context);
                base.AuditNext(context);
            }
        }
    }
}

{
    /// <summary>
    /// 项目经理
    /// 职责:
    /// 1 权限范围内审批通过
    /// 2 超出权限就转交给主管
    /// 
    /// 组织架构变更---下一环节换人---改代码---不稳定--怎么稳定一下---甩锅大法---弄哪里不稳定就丢给别人,自己稳定就行----方法初始化
    /// </summary>
    public class PM : AbstractAuditor
    {
        //private AbstractAuditor _NextAuditor = null;
        //public void SetNext(AbstractAuditor auditor)
        //{
        //    this._NextAuditor = auditor;
        //}

        //public string Name { get; set; }
        public override void Audit(ApplyContext context)
        {
            Console.WriteLine("这里是项目经理 {0} 审批", this.Name);
            if (context.Hour <= 8)
            {
                context.AuditResult = true;
                context.AuditRemark = "enjoy your vacation!";
            }
            else
            {
                //AbstractAuditor charge = new Charge()
                //{
                //    Name = "ywa"
                //};
                //charge.Audit(context);
                //AbstractAuditor manager = new Manager()
                //{
                //    Name = "没音"
                //};
                //manager.Audit(context);
                //if (this._NextAuditor != null)
                //{
                //    this._NextAuditor.Audit(context);
                //}
                base.AuditNext(context);
            }
        }
    }
}

{
    /// <summary>
    /// 1 责任链模式:逻辑封装和转移
    /// 2 框架设计中的各种责任链模式
    /// 3 从开发到架构的思考
    /// 4 延伸AspNetCore管道模型设计
    /// 
    /// 面向对象的23种设计模式---责任链模式---行为型设计模式的巅峰之作
    /// 设计模式:面向对象语言开发过程中,遇到种种场景和问题,提出的解决方案和思路,最终沉淀下来
    ///           ---解决问题的方法
    ///           ---不会过时,即使是新的跨平台框架里面,思想是不变的
    /// 行为型设计模式:关注对象和行为的分离
    /// POP----OOP
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {

                Console.WriteLine("下面模拟一个请假审批流程:");
                //一个请假申请  
                ApplyContext context = new ApplyContext()
                {
                    Id = 1098,
                    Name = "Lyndon",
                    Hour = 100,
                    Description = "参加软谋线下沙龙上海站活动",
                    AuditRemark = "",
                    AuditResult = false
                };

                {
                    ////菜鸟:一看就是代码翻译机,需求怎么交代我们就怎么翻译,完全没有自己的加工
                    ////把全部的业务逻辑都暴露在上端,面向过程式编程
                    //Console.WriteLine("****************************************");
                    ////首先是项目经理审批,找项目经理审批 and so on
                    //Console.WriteLine("这里是项目经理 {0} 审批", "fool");
                    //if (context.Hour <= 8)
                    //{
                    //    context.AuditResult = true;
                    //    context.AuditRemark = "enjoy your vacation!";
                    //}
                    //else
                    //{
                    //    //找主管审批
                    //    Console.WriteLine("这里是主管 {0} 审批", "我也不知道了");
                    //    if (context.Hour <= 16)
                    //    {
                    //        context.AuditResult = true;
                    //        context.AuditRemark = "enjoy your vacation!";
                    //    };
                    //}
                    //。。。
                }
                {
                    ////中级开发:oop思想,考虑对象--请假条+主管+经理---封装业务逻辑,继承复用代码,还有多态   
                    ////也是个代码搬运工,也是个翻译机+OOP思想,因为没有自己的思考----这只是翻译,表面上正确,实际上不可用的代码----不可能越级请假---开发不仅是搬运,还得有思想
                    //转移了审批逻辑
                    //Console.WriteLine("****************************************");
                    //AbstractAuditor pm = new PM()
                    //{
                    //    Name = "鸽子"
                    //};
                    //pm.Audit(context);
                    //if (!context.AuditResult)
                    //{
                    //    AbstractAuditor charge = new Charge()
                    //    {
                    //        Name = "ywa"
                    //    };
                    //    charge.Audit(context);
                    //    if (!context.AuditResult)
                    //    {
                    //        AbstractAuditor manager = new Manager()
                    //        {
                    //            Name = "没音"
                    //        };
                    //        manager.Audit(context);
                    //        if (!context.AuditResult)
                    //        {
                    //            //,,.
                    //        }
                    //    }
                    //}
                }
                {
                    ////高级开发:程序员一思考就进入高级了---申请应该是自动流转,对象的职责要增加
                    ////转移了申请提交逻辑
                    ////假如审批流程变化了---需要修改代码--缺乏前瞻性
                    //Console.WriteLine("****************************************");
                    //AbstractAuditor pm = new PM()
                    //{
                    //    Name = "鸽子"
                    //};
                    //pm.Audit(context);
                }
                {
                    //优秀的高级开发:流程就可以变化了,能更好的应对业务的升级变迁---开闭原则
                    Console.WriteLine("****************************************");
                    AbstractAuditor pm = new PM()
                    {
                        Name = "鸽子"
                    };
                    AbstractAuditor charge = new Charge()
                    {
                        Name = "ywa"
                    };
                    AbstractAuditor manager = new Manager()
                    {
                        Name = "没音"
                    };
                    AbstractAuditor chif = new Chif()
                    {
                        Name = "竹林风"
                    };
                    AbstractAuditor ceo = new CEO()
                    {
                        Name = "PF"
                    };
                    //pm.SetNext(charge);
                    //charge.SetNext(manager);
                    //manager.SetNext(chif);
                    //chif.SetNext(ceo);
                    pm.SetNext(ceo);
                    //担心说代码好复杂---面向对象语言开发,不担心代码多---封装一下---其实也很简单---反射+配置文件--------这块儿不细说,感兴趣的建议加助教老师获取之前讲过的反射课程

                    pm.Audit(context);
                }
                if (context.AuditResult)
                {
                    Console.WriteLine("审批通过啦");
                }
                else
                {
                    Console.WriteLine("这活儿干不下去了,,辞职!!");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

状态模式 (State)

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

模式的实现:

{
    public class Context
    {
        public LightBase CurrentLight { get; set; }

        public void Show()
        {
            this.CurrentLight.Show();
        }

        public void Turn()
        {
            this.CurrentLight.TurnContext(this);
        }
    }
}

{
    public abstract class LightBase
    {
        public LightColor Color { get; set; }

        public void Shine()
        {
            Console.WriteLine("灯亮着");
        }
        public abstract void Show();
        public abstract void Turn();

        public abstract void TurnContext(Context context);
    }
}

{
    public class LightBlue : LightBase
    {
        /// <summary>
        /// 初始化的时候 指定灯的颜色
        /// </summary>
        public LightBlue()
        {
            base.Color = LightColor.Blue;
        }
        public override void Show()
        {
            Console.WriteLine("蓝灯减速");
        }

        public override void Turn()
        {
            this.Color = LightColor.Green;
        }

        public override void TurnContext(Context context)
        {
            context.CurrentLight = new LightGreen();
        }
    }
}

{
    public class LightGreen : LightBase
    {
        /// <summary>
        /// 初始化的时候 指定灯的颜色
        /// </summary>
        public LightGreen()
        {
            base.Color = LightColor.Green;
        }


        public override void Show()
        {
            Console.WriteLine("绿灯行");
        }

        public override void Turn()
        {
            this.Color = LightColor.Yellow;
        }

        public override void TurnContext(Context context)
        {
            context.CurrentLight = new LightYellow();
        }
    }
}

{
    public class LightRed : LightBase
    {
        /// <summary>
        /// 初始化的时候 指定灯的颜色
        /// </summary>
        public LightRed()
        {
            base.Color = LightColor.Red;
        }
        public override void Show()
        {
            Console.WriteLine("红灯停");
        }

        public override void Turn()
        {
            this.Color = LightColor.Blue;
        }

        public override void TurnContext(Context context)
        {
            context.CurrentLight = new LightBlue();
        }
    }
}

{
    public class LightYellow : LightBase
    {
        /// <summary>
        /// 初始化的时候 指定灯的颜色
        /// </summary>
        public LightYellow()
        {
            base.Color = LightColor.Yellow;
        }
        public override void Show()
        {
            Console.WriteLine("黄灯请小心");
        }

        public override void Turn()
        {
            this.Color = LightColor.Red;
        }

        public override void TurnContext(Context context)
        {
            context.CurrentLight = new LightRed();
        }
    }
}

{
    /// <summary>
    /// 交通灯
    /// </summary>
    public class TrafficLight
    {
        /// <summary>
        /// 0 绿灯  1 黄灯  2红灯
        /// </summary>
        public LightColor Color { get; set; }

        public void Show()
        {
            //switch (this.Color)
            //{
            //    case LightColor.Green:
            //        break;
            //    case LightColor.Yellow:
            //        break;
            //    case LightColor.Red:
            //        break;
            //    default:
            //        break;
            //}

            if (this.Color == LightColor.Green)
            {
                Console.WriteLine("绿灯行");
            }
            else if (this.Color == LightColor.Yellow)
            {
                Console.WriteLine("黄灯请小心");
            }
            else if (this.Color == LightColor.Red)
            {
                Console.WriteLine("红灯停");
            }
            else if (this.Color == LightColor.Blue)
            {
                Console.WriteLine("蓝灯减速");
            }
        }

        public void Turn()
        {
            if (this.Color == LightColor.Green)
            {
                this.Color = LightColor.Yellow;
            }
            else if (this.Color == LightColor.Yellow)
            {
                this.Color = LightColor.Red;
            }

            else if (this.Color == LightColor.Red)
            {
                this.Color = LightColor.Blue;
            }
            else if (this.Color == LightColor.Blue)
            {
                this.Color = LightColor.Green;
            }
        }

    }

    public enum LightColor
    {
        Green = 0,
        Yellow = 1,
        Red = 2,
        Blue = 3
    }
}

{
    /// <summary>
    /// 1 状态模式(State)介绍和使用
    /// 2 状态模式好处和实际的应用
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                {
                    TrafficLight light = new TrafficLight()
                    {
                        Color = LightColor.Green
                    };
                    light.Show();
                    light.Turn();
                    light.Show();
                    light.Turn();
                    light.Show();
                    light.Turn();
                }
                Console.WriteLine("******************************");
                {
                    LightBase light = new LightGreen();
                    light.Show();
                    light.Turn();
                    light.Show();
                    light.Turn();

                }
                Console.WriteLine("******************************");
                {
                    LightBase light = new LightGreen();
                    Context context = new Context()
                    {
                        CurrentLight = light
                    };

                    context.Show();
                    context.Turn();
                    context.Show();
                    context.Turn();
                    context.Show();
                    context.Turn();
                    context.Show();
                    context.Turn();

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

观察者模式 (Observer)

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

模式的实现:

{
    public interface IObserver
    {
        void Action();
    }
}

{
    /// <summary>
    /// 事情起源
    /// 大半夜,猫叫一声
    /// 
    /// baby cry
    /// dog wang
    /// father roar
    /// mother whisper
    /// .
    /// .
    /// .
    /// </summary>
    public class Cat
    {
        public void Miao()
        {
            Console.WriteLine("{0} Miao 一声", this.GetType().Name);
            //一系列后续动作

            new Mouse().Run();
            new Dog().Wang("1");
            new Baby().Cry();
            //new Dog().Wang();
            new Father().Roar();
            new Mother().Whisper();
            new Brother().Turn();
            new Neighbor().Awake();
            new Stealer().Hide();
            //new Cricket().Sing();
        }

        public Cat()
        { }
        public Cat(List<IObserver> observerList)
        {
            this._ObserverList = observerList;
        }



        private List<IObserver> _ObserverList = new List<IObserver>();

        public void AddObserver(IObserver observer)
        {
            this._ObserverList.Add(observer);
        }

        public void RemoveObserver(IObserver observer)
        {
            this._ObserverList.Remove(observer);
        }

        public void MiaoObserver()
        {
            Console.WriteLine("{0} MiaoObserver 一声", this.GetType().Name);
            //一系列后续动作
            foreach (var observer in this._ObserverList)
            {
                observer.Action();
            }
        }

        public event Action CatMiaoEvent;
        public void MiaoEvent()
        {
            Console.WriteLine("{0} MiaoEvent 一声", this.GetType().Name);
            if (this.CatMiaoEvent != null)
            {
                CatMiaoEvent.Invoke();
            }
        }

    }
}

{
    public class Baby : IObserver
    {
        public void Cry()
        {
            Console.WriteLine("{0} Cry", this.GetType().Name);
        }


        public void Action()
        {
            this.Cry();
        }
    }
}

{
    public class Brother : IObserver
    {
        public void Turn()
        {
            Console.WriteLine("{0} Turn", this.GetType().Name);
        }


        public void Action()
        {
            this.Turn();
        }
    }
}

{
    public class Cricket : IObserver
    {
        public void Sing()
        {
            Console.WriteLine("{0} Sing", this.GetType().Name);
        }

        public void Action()
        {
            this.Sing();
        }
    }
}

{
    public class Dog : IObserver
    {
        public void Wang(string name)
        {
            Console.WriteLine("{0} Wang", this.GetType().Name);
        }

        public void Action()
        {
            this.Wang("2");
        }
    }
}

{
    public class Father : IObserver
    {
        public void Roar()
        {
            Console.WriteLine("{0} Roar", this.GetType().Name);
        }

        public void Action()
        {
            this.Roar();
        }
    }
}

{
    public class Mother : IObserver
    {
        public void Whisper()
        {
            Console.WriteLine("{0} Whisper", this.GetType().Name);
        }

        public void Action()
        {
            this.Whisper();
        }
    }
}

{
    public class Mouse : IObserver
    {
        public void Run()
        {
            Console.WriteLine("{0} Run", this.GetType().Name);
        }

        public void Action()
        {
            this.Run();
        }
    }
}

{
    public class Neighbor : IObserver
    {
        public void Awake()
        {
            Console.WriteLine("{0} Awake", this.GetType().Name);
        }

        public void Action()
        {
            this.Awake();
        }
    }
}

{
    public class Stealer : IObserver
    {
        public void Hide()
        {
            Console.WriteLine("{0} Hide", this.GetType().Name);
        }

        public void Action()
        {
            this.Hide();
        }
    }
}

{
    /// <summary>
    /// 1 观察者模式Observer
    /// 2 .net的委托事件
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                {
                    Cat cat = new Cat();
                    cat.Miao();

                    Console.WriteLine("*************Observer***************");
                    {
                        Brother brother = new Brother();

                        cat.AddObserver(new Mouse());
                        cat.AddObserver(new Dog());
                        cat.AddObserver(new Cricket());
                        cat.AddObserver(new Baby());
                        cat.AddObserver(new Father());
                        cat.AddObserver(new Mother());
                        cat.AddObserver(brother);
                        cat.AddObserver(new Neighbor());
                        cat.AddObserver(new Stealer());

                        cat.MiaoObserver();

                        cat.RemoveObserver(brother);
                        cat.MiaoObserver();
                    }
                    {
                        Console.WriteLine("*************Event***************");

                        Brother brother = new Brother();

                        cat.CatMiaoEvent += new Mouse().Run;
                        cat.CatMiaoEvent += () => new Dog().Wang("3");
                        cat.CatMiaoEvent += new Cricket().Sing;
                        cat.CatMiaoEvent += new Baby().Cry;
                        cat.CatMiaoEvent += new Father().Roar;
                        cat.CatMiaoEvent += new Mother().Whisper;
                        cat.CatMiaoEvent += brother.Turn;
                        cat.CatMiaoEvent += new Neighbor().Awake;
                        cat.CatMiaoEvent += new Stealer().Hide;
                        if (true)
                        {
                            AddDog(cat);
                        }

                        cat.MiaoEvent();

                        cat.CatMiaoEvent -= brother.Turn;

                        cat.MiaoEvent();
                    }
                }
                {
                    Console.WriteLine("*************Another Cat***************");
                    Cat cat = new Cat();

                    Brother brother = new Brother();

                    cat.AddObserver(new Baby());
                    cat.AddObserver(new Father());
                    cat.AddObserver(new Mother());
                    cat.AddObserver(brother);
                    cat.AddObserver(new Neighbor());

                    cat.MiaoObserver();

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }

        private static void AddDog(Cat cat)
        {

        }

    }
}

中介者模式 (Mediator)

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

模式的实现:

{
    public class BaseMediator
    {
        public string Name { get; set; }
        private List<BaseCharacter> _BaseCharacterList = new List<BaseCharacter>();

        public void AddCharacter(BaseCharacter baseCharacter)
        {
            this._BaseCharacterList.Add(baseCharacter);
        }

        /// <summary>
        /// 群里面发消息的功能
        /// </summary>
        /// <param name="message"></param>
        /// <param name="characterFrom"></param>
        public void SendMessage(string message, BaseCharacter characterFrom)
        {
            Console.WriteLine("{0}Send:{1}", characterFrom.Name, message);
            foreach (var item in this._BaseCharacterList)
            {
                item.GetMessage(message, characterFrom);
            }
        }
    }
}

{
    public class BaseMediator
    {
        public string Name { get; set; }
        private List<BaseCharacter> _BaseCharacterList = new List<BaseCharacter>();

        public void AddCharacter(BaseCharacter baseCharacter)
        {
            this._BaseCharacterList.Add(baseCharacter);
        }

        /// <summary>
        /// 群里面发消息的功能
        /// </summary>
        /// <param name="message"></param>
        /// <param name="characterFrom"></param>
        public void SendMessage(string message, BaseCharacter characterFrom)
        {
            Console.WriteLine("{0}Send:{1}", characterFrom.Name, message);
            foreach (var item in this._BaseCharacterList)
            {
                item.GetMessage(message, characterFrom);
            }
        }
    }
}

{
    /// <summary>
    /// 1 中介者模式(Mediator Pattern)
    /// 2 中介者模式的优缺点和应用
    /// 3 数据库设计的中介者模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                BaseCharacter teacher = new Teacher()
                {
                    Name = "Eleven"
                };

                BaseCharacter master = new Master()
                {
                    Name = "落单的候鸟"
                };

                BaseCharacter student1 = new Student()
                {
                    Name = "yoyo"
                };
                BaseCharacter student2 = new Student()
                {
                    Name = "小昶"
                };
                BaseCharacter student3 = new Student()
                {
                    Name = "木偶"
                };
                BaseCharacter student4 = new Student()
                {
                    Name = "一点半"
                };
                BaseCharacter student5 = new Student()
                {
                    Name = "初出茅庐"
                };
                Console.WriteLine("*********************************");

                teacher.SendMessage("今天晚上八点上课啦,,", master);
                Console.WriteLine("*********************************");
                master.SendMessage("老师,收到,马上通知大家", teacher);
                Console.WriteLine("*********************************");
                master.SendMessage("今天晚上八点上课,大家不要错过哦", student1);
                Console.WriteLine("*********************************");

                //候鸟需要发消息给全部的学员
                master.SendMessage("今天晚上八点上课,大家不要错过哦", student2);
                Console.WriteLine("*********************************");
                master.SendMessage("今天晚上八点上课,大家不要错过哦", student3);
                Console.WriteLine("*********************************");
                master.SendMessage("今天晚上八点上课,大家不要错过哦", student4);
                Console.WriteLine("*********************************");
                Console.WriteLine("*********************************");
                Console.WriteLine("*********************************");

                {
                    BaseMediator mediator = new BaseMediator();
                    mediator.AddCharacter(master);
                    mediator.AddCharacter(student1);

                    mediator.SendMessage("今天晚上八点上课,大家不要错过哦", master);

                    Console.WriteLine("*********************************");

                    mediator.SendMessage("收到,一定准时前来", student4);
                }

                {
                    BaseMediator mediator = new BaseMediator();
                    mediator.AddCharacter(teacher);
                    mediator.AddCharacter(master);
                    mediator.AddCharacter(student1);
                    mediator.AddCharacter(student2);
                    mediator.AddCharacter(student3);
                    mediator.AddCharacter(student4);
                    mediator.AddCharacter(student5);

                    mediator.SendMessage("今天晚上八点上课,大家不要错过哦", master);

                    Console.WriteLine("*********************************");

                    mediator.SendMessage("收到,一定准时前来", student4);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

迭代器模式 (Iterator)

提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

模式的实现:

{
    public interface IIterator<T>
    {
        T Current { get; }

        bool MoveNext();

        void Reset();
    }
}

{
    /// <summary>
    /// 新的集合  实现了IIterator接口
    /// </summary>
    public class KFCMenuIterator : IIterator<Food>
    {
        private Food[] _FoodList = null;

        public KFCMenuIterator(KFCMenu menu)
        {
            this._FoodList = menu.GetFoods();
        }

        private int _Index = -1;
        public Food Current
        {
            get
            {
                return this._FoodList[_Index];
            }
        }

        public bool MoveNext()
        {
            return this._FoodList.Length > ++this._Index;
        }

        public void Reset()
        {
            this._Index = -1;
        }
    }
}

{
    /// <summary>
    /// 新的集合  实现了IIterator接口
    /// </summary>
    public class MacDonaldMenuIterator : IIterator<Food>
    {
        private List<Food> _FoodList = null;

        public MacDonaldMenuIterator(MacDonaldMenu menu)
        {
            this._FoodList = menu.GetFoods();
        }

        private int _Index = -1;
        public Food Current
        {
            get
            {
                return this._FoodList[_Index];
            }
        }

        public bool MoveNext()
        {
            return this._FoodList.Count > ++this._Index;
        }

        public void Reset()
        {
            this._Index = -1;
        }
    }
}

{
    public class KFCMenu
    {
        private Food[] _FoodList = new Food[3];

        public KFCMenu()
        {
            this._FoodList[0] = new Food()
            {
                Id = 1,
                Name = "汉堡包",
                Price = 15
            };
            this._FoodList[1] = new Food()
            {
                Id = 2,
                Name = "可乐",
                Price = 10
            };
            this._FoodList[2] = new Food()
            {
                Id = 3,
                Name = "薯条",
                Price = 8
            };
        }

        public Food[] GetFoods()
        {
            return this._FoodList;
        }

        public IIterator<Food> GetIterator()
        {
            return new KFCMenuIterator(this);
        }
    }
}

{
    public class MacDonaldMenu
    {
        private List<Food> _FoodList = new List<Food>();

        public MacDonaldMenu()
        {
            this._FoodList.Add(new Food()
            {
                Id = 1,
                Name = "鸡肉卷",
                Price = 15
            });
            this._FoodList.Add( new Food()
            {
                Id = 2,
                Name = "红豆派",
                Price = 10
            });
            this._FoodList.Add(new Food()
            {
                Id = 3,
                Name = "薯条",
                Price = 9
            });
        }

        public List<Food> GetFoods()
        {
            return this._FoodList;
        }

        public IIterator<Food> GetIterator()
        {
            return new MacDonaldMenuIterator(this);
        }
    }
}

{
    /// <summary>
    /// 使用foreach的条件是 类型包含public IEnumerator GetEnumerator()
    /// </summary>
    public class Food //: IEnumerable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }

        public IEnumerator GetEnumerator()
        {
            throw new Exception();
            //返回一个迭代器
        }
    }
}

{
    /// <summary>
    /// http://www.cnblogs.com/YamatAmain/p/5016464.html
    /// 
    /// 含有yield的函数说明它是一个生成器,而不是普通的函数。当程序运行到yield这一行时,该函数会返回值,并保存当前域的所有变量状态;等到该函数下一次被调用时,会从上一次中断的地方开始执行,一直遇到下一个yield, 程序返回值, 并在此保存当前状态; 如此反复,直到函数正常执行完成。
    /// 
    /// 迭代器模式是设计模式中行为模式(behavioral pattern)的一个例子,他是一种简化对象间通讯的模式,也是一种非常容易理解和使用的模式。简单来说,迭代器模式使得你能够获取到序列中的所有元素 而不用关心是其类型是array,list,linked list或者是其他什么序列结构。这一点使得能够非常高效的构建数据处理通道(data pipeline)--即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是LINQ的核心模式。


    /// 在.NET中,迭代器模式被IEnumerator和IEnumerable及其对应的泛型接口所封装。如果一个类实现了IEnumerable接 口,那么就能够被迭代;调用GetEnumerator方法将返回IEnumerator接口的实现,它就是迭代器本身。迭代器类似数据库中的游标,他是 数据序列中的一个位置记录。迭代器只能向前移动,同一数据序列中可以有多个迭代器同时对数据进行操作。
    /// </summary>
    public class YieldShow
    {
        public IEnumerable<int> CreateEnumerable()
        {
            try
            {
                Console.WriteLine("{0} CreateEnumerable()方法开始", DateTime.Now);
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine("{0}开始 yield {1}", DateTime.Now, i);
                    yield return i;
                    Console.WriteLine("{0}yield 结束", DateTime.Now);
                    if (i == 4)
                    {
                        yield break;//直接终结迭代  4会出现的,,
                    }
                }
                Console.WriteLine("{0} Yielding最后一个值", DateTime.Now);
                yield return -1;
                Console.WriteLine("{0} CreateEnumerable()方法结束", DateTime.Now);
            }
            finally
            {
                Console.WriteLine("停止迭代!");
            }
        }

        /// <summary>
        /// MoveNext 检查是否存在  并设置current
        /// </summary>
        public void Show()
        {
            IEnumerable<int> iterable = this.CreateEnumerable();//1 不会直接执行
            //IEnumerator iterator = iterable.GetEnumerator();
            IEnumerator<int> iterator = iterable.GetEnumerator();
            Console.WriteLine("开始迭代");
            while (true)
            {
                Console.WriteLine("调用MoveNext方法……");
                Boolean result = iterator.MoveNext();//2 正式开启CreateEnumerable
                Console.WriteLine("MoveNext方法返回的{0}", result);
                if (!result)
                {
                    break;
                }
                Console.WriteLine("获取当前值……");
                Console.WriteLine("获取到的当前值为{0}", iterator.Current);
            }
            Console.ReadKey();
        }
    }
}

{
    /// <summary>
    /// 1 迭代器模式 Iterator
    /// 2 .net里面的迭代器模式  yield return
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                {
                    Console.WriteLine("***********************KFCMenu*********************");
                    KFCMenu menu = new KFCMenu();
                    Food[] foods = menu.GetFoods();
                    for (int i = 0; i < foods.Length; i++)
                    {
                        Console.WriteLine("{0} {1} {2}¥", foods[i].Id, foods[i].Name, foods[i].Price);
                    }

                    IIterator<Food> iterator = menu.GetIterator();
                    while (iterator.MoveNext())
                    {
                        Food food = iterator.Current;
                        Console.WriteLine("{0} {1} {2}¥", food.Id, food.Name, food.Price);
                    }

                }
                {
                    Console.WriteLine("***********************MacDonaldMenu*********************");
                    MacDonaldMenu menu = new MacDonaldMenu();
                    List<Food> foods = menu.GetFoods();
                    for (int i = 0; i < foods.Count; i++)
                    {
                        Console.WriteLine("{0} {1} {2}¥", foods[i].Id, foods[i].Name, foods[i].Price);
                    }

                    IIterator<Food> iterator = menu.GetIterator();
                    while (iterator.MoveNext())
                    {
                        Food food = iterator.Current;
                        Console.WriteLine("{0} {1} {2}¥", food.Id, food.Name, food.Price);
                    }

                }

                {
                    YieldShow show = new YieldShow();
                    show.Show();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

访问者模式 (Visitor)

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。

模式的实现:

{
    public interface IVisitor
    {
        void GetVideoFree(StudentFree studentFree);
        void GetVideoVip(StudentVip studentVip);

        //void GetVideoVVip(StudentVVip studentVVip);
    }
}

{
    /// <summary>
    /// 访问者:完成获取视频的行为
    /// </summary>
    public class VisitorCurrent : IVisitor
    {
        public void GetVideoFree(StudentFree studentFree)
        {
            Console.WriteLine("只能获取当次课的公开课视频代码");
        }

        public void GetVideoVip(StudentVip studentVip)
        {
            Console.WriteLine("免费获取全套的公开课视频代码合集");
        }
    }
}

{
    /// <summary>
    /// 访问者:完成获取视频的行为
    /// </summary>
    public class VisitorPast : IVisitor
    {
        public void GetVideoFree(StudentFree studentFree)
        {
            Console.WriteLine("没有视频只有代码");
        }

        public void GetVideoVip(StudentVip studentVip)
        {
            Console.WriteLine("获取公开课代码合集");
        }
    }
}

{
    /// <summary>
    /// 学生
    /// </summary>
    public abstract class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public long QQ { get; set; }

        public void Study()
        {
            Console.WriteLine("{0}跟着Eleven老师学习.net高级开发", this.Name);
        }

        public abstract void GetVideo();
        public abstract void GetVideoVisitor(IVisitor visitor);
    }
}

{
    public class StudentFree : Student
    {
        public string CourseFree { get; set; }

        /// <summary>
        /// </summary>
        public override void GetVideo()
        {
            Console.WriteLine("只能获取当次课的公开课视频代码");
        }

        public override void GetVideoVisitor(IVisitor visitor)
        {
            visitor.GetVideoFree(this);//this 是当前的实例
        }
    }
}

{
    public class StudentVip : Student
    {
        public string CourseFree { get; set; }
        public string CourseVip { get; set; }

        public override void GetVideo()
        {
            //if()
            //{}
            //else if()
            //{}
            //else{}
            Console.WriteLine("免费获取全套的公开课视频代码合集");
        }

        public override void GetVideoVisitor(IVisitor visitor)
        {
            visitor.GetVideoVip(this);//this 是当前的实例
        }

    }
}

{
    public class StudentVVip : Student
    {
        public string CourseFree { get; set; }
        public string CourseVip { get; set; }

        public override void GetVideo()
        {
            //if()
            //{}
            //else if()
            //{}
            //else{}
            Console.WriteLine("免费获取全套的公开课视频代码合集");
        }

        public override void GetVideoVisitor(IVisitor visitor)
        {
            //visitor.GetVideoVVip(this);//this 是当前的实例
        }

    }
}

{
    /// <summary>
    /// 1 集合的访问和访问者模式Visitor Pattern
    /// 2 倾斜的可扩展性设计
    /// 3 应用场景
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("欢迎来到.net高级班公开课之设计模式特训,今天是Eleven老师为大家带来的访问者模式Visitor");
                List<Student> studentList = new List<Student>()
                {
                    new StudentVip()
                    {
                        Id=638,
                        Name="ME860"
                    },
                    new StudentVip()
                    {
                        Id=586,
                        Name="如果"
                    },
                    new StudentFree()
                    {
                        Id=123,
                        Name="鱼猫"
                    }
                };
                foreach (var student in studentList)
                {
                    Console.WriteLine("*************************");
                    student.Study();
                    
                    student.GetVideo();

                }

                {
                    Console.WriteLine("*************VisitorCurrent************");
                    VisitorCurrent visitor = new VisitorCurrent();
                    foreach (var student in studentList)
                    {
                        Console.WriteLine("*************************");
                        student.Study();
                        student.GetVideoVisitor(visitor);
                    }
                }
                {
                    Console.WriteLine("*************VisitorPast************");
                    VisitorPast visitor = new VisitorPast();
                    foreach (var student in studentList)
                    {
                        Console.WriteLine("*************************");
                        student.Study();
                        student.GetVideoVisitor(visitor);
                    }
                }
                {
                    Console.WriteLine("*************VisitorTemp************");
                    VisitorTemp visitor = new VisitorTemp();
                    foreach (var student in studentList)
                    {
                        Console.WriteLine("*************************");
                        student.Study();
                        student.GetVideoVisitor(visitor);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

备忘录模式 (Memento)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

{
    /// <summary>
    /// 魔兽争霸
    /// </summary>
    public class War3
    {
        public string Race { get; set; }
        public string Hero { get; set; }
        public string Army { get; set; }
        public string Resource { get; set; }

        public void Show()
        {
            Console.WriteLine("********************************");
            Console.WriteLine("     Race:{0}", this.Race);
            Console.WriteLine("     Hero:{0}", this.Hero);
            Console.WriteLine("     Army:{0}", this.Army);
            Console.WriteLine("Resource:{0}", this.Resource);
            Console.WriteLine("********************************");
        }

        //public void Save()
        //{
        //    War3Memento memento = new War3Memento(this.Hero, this.Army, this.Resource);
        //    Caretaker.SaveWar3Memento(memento);
        //}

        //public void Load()
        //{
        //    War3Memento memento = Caretaker.GetWar3Memento();

        //    this.Army = memento.Army;
        //    this.Hero = memento.Hero;
        //    this.Resource = memento.Resource;
        //}

        public void Save(string name)
        {
            War3Memento memento = new War3Memento(this.Hero, this.Army, this.Resource);
            Caretaker.SaveWar3Memento(name, memento);
        }

        public void Load(string name)
        {
            War3Memento memento = Caretaker.GetWar3Memento(name);

            this.Army = memento.Army;
            this.Hero = memento.Hero;
            this.Resource = memento.Resource;
        }


    }
}

{
    /// <summary>
    /// 魔兽争霸备忘
    /// </summary>
    public class War3Memento
    {
        public string Hero { get; private set; }
        public string Army { get; private set; }
        public string Resource { get; private set; }

        public War3Memento(string hero, string army, string resource)
        {
            this.Hero = hero;
            this.Army = army;
            this.Resource = resource;
        }
    }
}

{
    /// <summary>
    /// 第三方保存容器:txt xml db  缓存  内存
    /// </summary>
    public class Caretaker
    {
        //private static War3Memento _War3Memento = null;
        //public static void SaveWar3Memento(War3Memento war3Memento)
        //{
        //    _War3Memento = war3Memento;
        //}

        //public static War3Memento GetWar3Memento()
        //{
        //    return _War3Memento;
        //}


        private static Dictionary<string, War3Memento> _War3MementoDictionary = new Dictionary<string, War3Memento>();
        public static void SaveWar3Memento(string name, War3Memento war3Memento)
        {
            _War3MementoDictionary.Add(name, war3Memento);
        }

        public static War3Memento GetWar3Memento(string name)
        {
            if (_War3MementoDictionary.ContainsKey(name))
                return _War3MementoDictionary[name];
            else
                throw new Exception("wrong name");
        }
    }
}

{
    /// <summary>
    /// 1 undo和redo:备忘模式和命令模式的区别
    /// 2 备忘录模式(Memento Patern),一次恢复和多次恢复
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("欢迎来到.net高级班公开课之设计模式特训,今天是Eleven老师为大家带来的备忘录模式");
                //int i = 12345;
                //i += 100;//动作  命令和反命令

                //List<War3> war3List = new List<War3>();

                War3 war3 = new War3()
                {
                    Race = "Undead",
                    Hero = "Level 1 DK",
                    Army = "5只食尸鬼",
                    Resource = "200G 200W"
                };
                //war3List.Add(war3);

                //war3.Save();
                war3.Save("Start");
                war3.Show();

                Console.WriteLine("*****MF*******");
                //War3 war31 = new War3()
                //{
                //    Race = "Undead",
                //    Hero = "3级DK1级Lich",
                //    Army = "5只蜘蛛2只食尸鬼",
                //    Resourse = "500G 300W"
                //};//全新的对象来备份,太耗资源

                war3.Hero = "3级DK1级Lich";
                war3.Army = "5只蜘蛛2只食尸鬼";
                war3.Resource = "500G 300W";
                //war3.Save();
                war3.Save("MF");
                //war3List.Add(war3);
                war3.Show();

                Console.WriteLine("*****交战*******");
                war3.Hero = "4级DK 3级Lich 1级小强";
                war3.Army = "1只憎恶6只蜘蛛1只雕像";
                war3.Resource = "1000G 1500W";
                war3.Save("交战");
                //war3.Save();

                Console.WriteLine("*****决战*******");
                war3.Hero = "5级DK 4级Lich 3级小强";
                war3.Army = "2只憎恶8只蜘蛛2只雕像";
                war3.Resource = "1000G 1500W";
                war3.Save("决战");
                //war3.Save();

                Console.WriteLine("*****决战后*******");
                war3.Hero = "6级DK 6级Lich 3级小强";
                war3.Army = "1只憎恶2只蜘蛛1只冰龙";
                war3.Resource = "10G 1200W";
                war3.Save("决战后");
                //war3.Save();

                //war3.Load();
                war3.Load("Start");
                war3.Show();
                war3.Load("MF");
                war3.Show();
                war3.Load("交战");
                war3.Show();
                war3.Load("决战");
                war3.Show();
                war3.Load("决战后");
                war3.Show();
                //Console.WriteLine("********月光宝盒**********");
                //war3 = war3List[0];
                //war3.Show();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

解释器模式 (Interpreter)

给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。

模式的实现:

{
    /// <summary>
    /// 上下文
    /// </summary>
    public class Context
    {
        private string _Word = null;
        public Context(string word)
        {
            this._Word = word;
        }

        public void Set(string newWord)
        {
            this._Word = newWord;
        }

        public string Get()
        {
            return this._Word;
        }
    }
}

{
    public abstract class BaseInterpreter
    {
        public abstract void Conversion(Context context);
    }
}

{
    public class AIInterpreter : BaseInterpreter
    {
        private static Dictionary<char, string> _Dictionary = new Dictionary<char, string>();
        static AIInterpreter()
        {
            _Dictionary.Add('a', "1");
            _Dictionary.Add('b', "2");
            _Dictionary.Add('c', "3");
            _Dictionary.Add('d', "4");
            _Dictionary.Add('e', "5");
            _Dictionary.Add('f', "6");
            _Dictionary.Add('g', "7");
            _Dictionary.Add('h', "8");
            _Dictionary.Add('i', "9");
        }

        public override void Conversion(Context context)
        {
            string text = context.Get();
            if (string.IsNullOrEmpty(text))
                return;
            List<string> numberList = new List<string>();
            foreach (var item in text.ToLower().ToArray())
            {
                if (_Dictionary.ContainsKey(item))
                {
                    numberList.Add(_Dictionary[item]);
                }
                else
                {
                    numberList.Add(item.ToString());
                }
            }
            context.Set(string.Concat(numberList));
        }
    }
}

{
    /// <summary>
    /// 
    /// </summary>
    public class JNInterpreter : BaseInterpreter
    {
        private static Dictionary<char, string> _Dictionary = new Dictionary<char, string>();
        static JNInterpreter()
        {
            _Dictionary.Add('j', "a");
            _Dictionary.Add('k', "b");
            _Dictionary.Add('l', "c");
            _Dictionary.Add('m', "d");
            _Dictionary.Add('n', "e");
        }

        public override void Conversion(Context context)
        {
            string text = context.Get();
            if (string.IsNullOrEmpty(text))
                return;
            List<string> numberList = new List<string>();
            foreach (var item in text.ToLower().ToArray())
            {
                if (_Dictionary.ContainsKey(item))
                {
                    numberList.Add(_Dictionary[item]);
                }
                else
                {
                    numberList.Add(item.ToString());
                }
            }
            context.Set(string.Concat(numberList));
        }
    }
}

{
    /// <summary>
    /// 其他的都转成0
    /// </summary>
    public class ZeroInterpreter : BaseInterpreter
    {
        private static Dictionary<char, string> _Dictionary = new Dictionary<char, string>();
        static ZeroInterpreter()
        {
            _Dictionary.Add('1', "1");
            _Dictionary.Add('2', "2");
            _Dictionary.Add('3', "3");
            _Dictionary.Add('4', "4");
            _Dictionary.Add('5', "5");
            _Dictionary.Add('6', "6");
            _Dictionary.Add('7', "7");
            _Dictionary.Add('8', "8");
            _Dictionary.Add('9', "9");
        }

        public override void Conversion(Context context)
        {
            string text = context.Get();
            if (string.IsNullOrEmpty(text))
                return;
            List<string> numberList = new List<string>();
            foreach (var item in text.ToLower().ToArray())
            {
                if (!_Dictionary.ContainsKey(item))
                {
                    numberList.Add("0");
                }
                else
                {
                    numberList.Add(item.ToString());
                }
            }
            context.Set(string.Concat(numberList));
        }
    }
}

{
    /// <summary>
    /// 1 解释器模式InterpreterPattern
    /// 2 优缺点分析和使用场景
    /// 3 web开发模板替换的解释器模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("********************************");
                string teacher = "Eleven";
                Console.WriteLine(ToNumberIf(teacher));
                Console.WriteLine(ToNumberCommon(teacher));
                Console.WriteLine("********************************");
                string student = "Gary";
                Console.WriteLine(ToNumberIf(student));
                Console.WriteLine(ToNumberCommon(student));


                Console.WriteLine(ToNumberCommon("ObjectIsNotFound"));
                Console.WriteLine("********************************");

                {
                    Context context = new Context("ObjectIsNotFound");
                    AIInterpreter interpreter = new AIInterpreter();
                    interpreter.Conversion(context);
                    Console.WriteLine(context.Get());
                }

                {
                    Context context = new Context("ObjectIsNotFound");
                    List<BaseInterpreter> interpreterList = new List<BaseInterpreter>()
                    {
                        new JNInterpreter(),
                        new AIInterpreter(),
                        new ZeroInterpreter()
                    };
                    foreach (var item in interpreterList)
                    {
                        item.Conversion(context);
                    }
                    Console.WriteLine(context.Get());
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }

        /// <summary>
        /// a b c d e f g h i j k l m n....
        /// 1 2 3 4 5 6 7 8 9 0 0 0 0 0....
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private static string ToNumberIf(string text)
        {
            if (text.Equals("Eleven"))
            {
                return "505050";
            }
            else if (text.Equals("Gary"))
            {
                return "7100";
            }
            else
                throw new Exception("wrong text");
        }

        /// <summary>
        /// a b c d e f g h i     j k l m n....
        /// 1 2 3 4 5 6 7 8 9     a b c d e....
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private static string ToNumberCommon(string text)
        {
            if (string.IsNullOrEmpty(text))
                return "";
            List<string> numberList = new List<string>();
            //o t---j n
            //j n---a e
            //a i---1 9
            //other--0

            foreach (var item in text.ToLower().ToArray())
            {
                switch (item)
                {
                    case 'a':
                    case 'j':
                        numberList.Add("1");
                        break;
                    case 'b':
                    case 'k':
                        numberList.Add("2");
                        break;
                    case 'c':
                    case 'l':
                        numberList.Add("3");
                        break;
                    case 'd':
                    case 'm':
                        numberList.Add("4");
                        break;
                    case 'e':
                    case 'n':
                        numberList.Add("5");
                        break;
                    case 'f':
                        numberList.Add("6");
                        break;
                    case 'g':
                        numberList.Add("7");
                        break;
                    case 'h':
                        numberList.Add("8");
                        break;
                    case 'i':
                        numberList.Add("9");
                        break;
                    default:
                        numberList.Add("0");
                        break;
                }
            }
            return string.Concat(numberList);//数组链接成字符串
        }
    }
}