设计模式范例代码

/* 1. 简单工厂模式 */
public class Operation
{
    private double _numberA = 0;
    private double _numberB = 0;
    public double NumberA { get { return this._numberA; } set { this._numberA = value; } }
    public double NumberB { get { return this._numberB; } set { this._numberB = value; } }
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}
class OperationAdd : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA + this.NumberB;
        return result;
    }
}
class OperationSub : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA - this.NumberB;
        return result;
    }
}
class OperationMul : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA * this.NumberB;
        return result;
    }
}
class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (this.NumberB == 0)
            throw new Exception("除数不能为零。");
        result = this.NumberA / this.NumberB;
        return result;
    }
}

public class OperationFactory
{
    public static Operation createOperate(string operate)
    {
        Operation oper = null;
        switch (operate)
        {
            case "+":
                oper = new OperationAdd();
                break;
            case "-":
                oper = new OperationSub();
                break;
            case "*":
                oper = new OperationMul();
                break;
            case "/":
                oper = new OperationDiv();
                break;
        }
        return oper;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Operation oper;
        oper = OperationFactory.createOperate("+");
        oper.NumberA = 1;
        oper.NumberB = 2;
        double result = oper.GetResult();

        Console.WriteLine(result);
        Console.ReadLine();
    }
}

执行结果:3

/*
 * 2.1 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间的可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
 * 模式实现的最简代码 */
abstract class Strategy
{
    //算法方法
    public abstract void AlgorithmInterface();
}

//具体算法A
class ConcreteStrategyA : Strategy
{
    //算法A实现方法
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法A实现");
    }
}
//具体算法B
class ConcreteStrategyB : Strategy
{
    //算法B实现方法
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法B实现");
    }
}
//具体算法C
class ConcreteStrategyC : Strategy
{
    //算法C实现方法
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法C实现");
    }
}
class Context
{
    Strategy strategy;
    //初始化时,传入具体的策略对象
    public Context(Strategy strategy)
    {
        this.strategy = strategy;
    }
    //根据具体策略的方法,调用其算法的方法
    public void ContextInterface()
    {
        this.strategy.AlgorithmInterface();
    }
}

class Program
{
    static void Main(string[] args)
    {
        //由于实例化不同的策略,所以最终在调用context.ContextInterface()时,所获得的结果就不尽相同
        Context context;
        context = new Context(new ConcreteStrategyA());
        context.ContextInterface();

        context = new Context(new ConcreteStrategyB());
        context.ContextInterface();

        context = new Context(new ConcreteStrategyC());
        context.ContextInterface();

        Console.Read();
    }
}
执行结果:
算法A实现
算法B实现
算法C实现

/*
 * 2.2 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间的可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
 * 模式实现的示例代码(其中套用了简单工厂模式)*/

abstract class CashSuper
{
    //现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
    public abstract double acceptCash(double money);
}
//正常收费子类
class CashNormal : CashSuper
{
    //正常收费,原价返回
    public override double acceptCash(double money)
    {
        return money;
    }
}
//打折收费子类
class CashRebate : CashSuper
{
    private double moneyRebate = 1d;
    public CashRebate(string moneyRebate)
    {
        //打折收费,初始化时,必须输入折扣率,如八折,就是0.8
        this.moneyRebate = double.Parse(moneyRebate);
    }
    public override double acceptCash(double money)
    {
        return money * moneyRebate;
    }
}
//返利收费子类
class CashReturn : CashSuper
{
    private double moneyCondition = 0.0d;
    private double moneyReturn = 0.0d;
    public CashReturn(string moneyCondition, string moneyReturn)
    {
        //返利收费,初始化时必须输入返利条件和返利值,比如满300返100,则moneyCondition为300,moneyReturn为100
        this.moneyCondition = double.Parse(moneyCondition);
        this.moneyReturn = double.Parse(moneyReturn);
    }
    public override double acceptCash(double money)
    {
        //若大于返利条件,则需要减去返利值
        double result = money;
        if (money >= moneyCondition)
            result = money - Math.Floor(money / moneyCondition) * moneyReturn;

        return result;
    }
}

class CashContext
{
    private CashSuper cs = null; //声明一个CashSuper对象
    public CashContext(string type) //注意参数不是具体的收费策略对象,而是一个字符串,表示收费类型
    {
        switch (type)
        {
            case "正常收费":
                CashNormal cs0 = new CashNormal(); //将实例化具体策略的过程由客户端转移到Context类中。简单工厂的应用
                cs = cs0;
                break;
            case "满300返100":
                CashReturn cr1 = new CashReturn("300", "100");
                cs = cr1;
                break;
            case "打8折":
                CashRebate cr2 = new CashRebate("0.8");
                cs = cr2;
                break;
        }
    }
    public double GetResult(double money)
    {
        //根据收费策略的不同,获得计算结果
        return cs.acceptCash(money);
    }
}

class Program
{
    static void Main(string[] args)
    {
        double total = 0.0d; //合计
        string selectedItemStr = "满300返100"; //策略代号
        string price = "600"; //单价
        string num = "3"; //数量

        CashContext csuper = new CashContext(selectedItemStr);
        double totalPrices = 0d;
        totalPrices = csuper.GetResult(Convert.ToDouble(price) * Convert.ToDouble(num));
        total = total + totalPrices;

        Console.WriteLine(total);
    }
}

执行结果:1200

/*
 * 3.1 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
 * 模式简单示例 */
abstract class Component
{
    public abstract void Operation();
}

class ConcreteComponent : Component
{
    public override void Operation()
    {
        Console.WriteLine("具体对象的操作");
    }
}

abstract class Decorator : Component
{
    protected Component component;
    public void SetComponent(Component component)
    {
        this.component = component;
    }
    public override void Operation()
    {
        if (component != null)
        {
            component.Operation();
        }
    }
}
class ConcreteDecoratorA : Decorator
{
    private string addedState; //本类的独有功能,以区别于ConcreteDecoratorB
    public override void Operation()
    {
        //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
        base.Operation();
        this.addedState = "New State";
        Console.WriteLine("具体装饰对象A的操作");
    }
}
class ConcreteDecoratorB : Decorator
{
    public override void Operation()
    {
        //首先运行Component的Operation(),再执行本类的功能,如AddedBehavior(),相当于对原Component进行了装饰
        base.Operation();
        AddedBehavior();
        Console.WriteLine("具体装饰对象B的操作");
    }
    private void AddedBehavior() //本类独有的方法,以区别于ConcreteDecoratorA
    { }
}

class Program
{
    static void Main(string[] args)
    {
        ConcreteComponent c = new ConcreteComponent();
        ConcreteDecoratorA d1 = new ConcreteDecoratorA();
        ConcreteDecoratorB d2 = new ConcreteDecoratorB();

        //装饰的方法是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c
        //再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()
        d1.SetComponent(c);
        d2.SetComponent(d1);
        d2.Operation();

        Console.Read();
    }
}
执行结果:
具体对象的操作
具体装饰对象A的操作
具体装饰对象B的操作

/*
 * 3.2 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
 * 模式实现的示例代码 */
class Person
{
    private string name;
    public Person() { }
    public Person(string name)
    {
        this.name = name;
    }
    public virtual void Show()
    {
        Console.WriteLine("装扮的{0}", name);
    }
}
//服饰类
class Finery : Person
{
    protected Person component;
    //打扮
    public void Decorate(Person component)
    {
        this.component = component;
    }
    public override void Show()
    {
        if (this.component != null) this.component.Show();
    }
}
class TShirt : Finery
{
    public override void Show() { Console.Write("大T恤 "); base.Show(); }
}
class BigTrouser : Finery
{
    public override void Show() { Console.Write("垮裤 "); base.Show(); }
}
class Sneakers : Finery
{
    public override void Show() { Console.Write("破球鞋 "); base.Show(); }
}
class Suit : Finery
{
    public override void Show() { Console.Write("西装 "); base.Show(); }
}
class Tie : Finery
{
    public override void Show() { Console.Write("领带 "); base.Show(); }
}
class LeatherShoes : Finery
{
    public override void Show() { Console.Write("皮鞋 "); base.Show(); }
}

class Program
{
    static void Main(string[] args)
    {
        Person xc = new Person("小菜");
        Console.WriteLine("\n第一种装扮:");

        Sneakers pqx = new Sneakers();
        BigTrouser kk = new BigTrouser();
        TShirt dtx = new TShirt();

        pqx.Decorate(xc);
        kk.Decorate(pqx);
        dtx.Decorate(kk);
        dtx.Show();


        Console.WriteLine("\n第二种装扮:");
        LeatherShoes px = new LeatherShoes();
        Tie ld = new Tie();
        Suit xz = new Suit();

        px.Decorate(xc);
        ld.Decorate(px);
        xz.Decorate(ld);
        xz.Show();

        Console.Read();
    }
}
执行结果:
第一种装扮:
大T恤 垮裤 破球鞋 装扮的小菜

第二种装扮:
西装 领带 皮鞋 装扮的小菜

/*
 * 4.1 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问
 * 模式实现的示例代码 */

class SchollGirl
{
    private string name;
    public string Name { get { return this.name; } set { this.name = value; } }
}

//代理接口
interface IGiveGift
{
    void GiveDolls();
    void GiveFlowers();
    void GiveChocolate();
}

//追求者类(让‘追求者’去实现‘送礼物’的接口)
class Pursuit : IGiveGift
{
    SchollGirl mm;
    public Pursuit(SchollGirl mm)
    {
        this.mm = mm;
    }

    public void GiveDolls()
    {
        Console.WriteLine(mm.Name + "送你洋娃娃");
    }

    public void GiveFlowers()
    {
        Console.WriteLine(mm.Name + "送你鲜花");
    }

    public void GiveChocolate()
    {
        Console.WriteLine(mm.Name + "送你巧克力");
    }
}

//代理类 让“代理”也去实现“送礼物”的接口
class Proxy : IGiveGift
{
    Pursuit gg;
    public Proxy(SchollGirl mm)
    {
        this.gg = new Pursuit(mm);
    }
    public void GiveDolls()
    {
        //在实现类中调用“追求者”类中的方法
        gg.GiveDolls();
    }

    public void GiveFlowers()
    {
        gg.GiveFlowers();
    }

    public void GiveChocolate()
    {
        gg.GiveChocolate();
    }
}


class Program
{
    static void Main(string[] args)
    {
        SchollGirl jiaojiao = new SchollGirl();
        jiaojiao.Name = "李娇娇";

        Proxy daili = new Proxy(jiaojiao);

        daili.GiveDolls();
        daili.GiveFlowers();
        daili.GiveChocolate();

        Console.Read();
    }
}
执行结果:
李娇娇送你洋娃娃
李娇娇送你鲜花
李娇娇送你巧克力

/*
 * 4.2 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问
 * 模式实现的示例代码 */
abstract class Subject
{
    public abstract void Request();
}

class RealSubject : Subject
{
    public override void Request()
    {
        Console.WriteLine("真实的请求");
    }
}

class Proxy : Subject
{
    RealSubject realSubject;
    public override void Request()
    {
        if (this.realSubject == null)
        {
            this.realSubject = new RealSubject();
        }
        realSubject.Request();
    }
}


class Program
{
    static void Main(string[] args)
    {
        Proxy proxy = new Proxy();
        proxy.Request();

        Console.Read();
    }
}
执行结果:真实的请求

/*
 * 5.1 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
 * 模式实现的示例代码 */
public class Operation
{
    private double _numberA = 0;
    private double _numberB = 0;
    public double NumberA { get { return this._numberA; } set { this._numberA = value; } }
    public double NumberB { get { return this._numberB; } set { this._numberB = value; } }
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}
class OperationAdd : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA + this.NumberB;
        return result;
    }
}
class OperationSub : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA - this.NumberB;
        return result;
    }
}
class OperationMul : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = this.NumberA * this.NumberB;
        return result;
    }
}
class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (this.NumberB == 0)
            throw new Exception("除数不能为零。");
        result = this.NumberA / this.NumberB;
        return result;
    }
}
interface IFactory
{
    Operation CreateOperation();
}

class AddFatory : IFactory //加法工厂类
{
    public Operation CreateOperation()
    {
        return new OperationAdd();
    }
}
class SubFactory : IFactory //减法工厂类
{
    public Operation CreateOperation()
    {
        return new OperationSub();
    }
}
class MulFactory : IFactory //乘法工厂类
{
    public Operation CreateOperation()
    {
        return new OperationMul();
    }
}
class DivFactory : IFactory //除法工厂类
{
    public Operation CreateOperation()
    {
        return new OperationDiv();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IFactory operFactory = new AddFatory();
        Operation oper = operFactory.CreateOperation();
        oper.NumberA = 1;
        oper.NumberB = 2;
        double result = oper.GetResult();

        Console.WriteLine(result);
        Console.Read();
    }
}

执行结果:3

/*
 * 5.2 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
 * 模式实现的示例代码 */

//雷锋类
class LeiFeng
{
    public void Sweep()
    {
        Console.WriteLine("扫地");
    }
    public void Wash()
    {
        Console.WriteLine("洗衣");
    }
    public void BuyRice()
    {
        Console.WriteLine("买米");
    }
}
//学雷锋的大学生类
class Undergraduate : LeiFeng
{ }

//社区志愿者类
class Volunteer : LeiFeng
{ }

interface IFactory
{
    LeiFeng CreateLeiFeng();
}
class UndergraduateFactory : IFactory
{
    public LeiFeng CreateLeiFeng()
    {
        return new Undergraduate();
    }
}
class VolunteerFactory : IFactory
{
    public LeiFeng CreateLeiFeng()
    {
        return new Volunteer();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IFactory factory = new UndergraduateFactory();
        LeiFeng student = factory.CreateLeiFeng();

        student.BuyRice();
        student.Sweep();
        student.Wash();
    }
}

执行结果:
买米
扫地
洗衣

/*
 * 6.1 原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
 * 模式实现的示例代码 */

abstract class Prototype
{
    private string id;
    public Prototype(string id)
    {
        this.id = id;
    }
    public string Id { get { return this.id; } }
    public abstract Prototype Clone(); //抽象类关键就是有这样一个Clone方法
}
class ConcretePrototype1 : Prototype
{
    public ConcretePrototype1(string id)
        : base(id)
    { }
    public override Prototype Clone()
    {
        //创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。
        //如果字段是值类型的,则对该字段执行逐位复制。
        //如果字段是引用类型,则复制引用但不复制引用的对象;
        //因此,原始对象及其副本引用同一对象
        return (Prototype)this.MemberwiseClone();
    }
}

class Program
{
    static void Main(string[] args)
    {
        ConcretePrototype1 p1 = new ConcretePrototype1("I");
        //克隆类 ConcretePrototype1的对象p1就能得到新的实例c1
        ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
        Console.WriteLine("Cloned:{0}", c1.Id);

        Console.Read();
    }
}

执行结果:Cloned:I

/*
 * 6.2 原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
 * 模式实现的示例代码(浅复制) */
class Resume : ICloneable
{
    private string name;
    private string sex;
    private string age;
    private string timeArea;
    private string company;

    public Resume(string name)
    {
        this.name = name;
    }
    //设置个人信息
    public void SetPersonalInfo(string sex, string age)
    {
        this.sex = sex;
        this.age = age;
    }
    //设置工作经历
    public void SetWorkExperience(string timeArea, string company)
    {
        this.timeArea = timeArea;
        this.company = company;
    }
    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", this.timeArea, this.company);
    }

    public object Clone() //实现接口的方法,用来克隆对象
    {
        return (Object)this.MemberwiseClone();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("", "29");
        a.SetWorkExperience("1998-2000", "XXX公司");

        //只需要调用Clone方法就可以实现新简历的生成,并且可以再修改新简历的细节
        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("1998-2006", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("", "24");

        a.Display();
        b.Display();
        c.Display();
    }
}

执行结果:
大鸟 男 29
工作经历:1998-2000 XXX公司
大鸟 男 29
工作经历:1998-2006 YY企业
大鸟 男 24
工作经历:1998-2000 XXX公司

/*
 * 6.3 原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
 * 模式实现的示例代码(深复制) */

//工作经历类
class WorkExperience : ICloneable
{
    private string workDate;
    public string WorkDate { get { return this.workDate; } set { this.workDate = value; } }
    private string company;
    public string Company { get { return this.company; } set { this.company = value; } }
    public object Clone()
    {
        return (Object)this.MemberwiseClone(); //“工作经历”类实现克隆的方法
    }
}

//简历
class Resume : ICloneable
{
    private string name;
    private string sex;
    private string age;
    private WorkExperience work;

    public Resume(string name)
    {
        this.name = name;
        work = new WorkExperience();
    }
    private Resume(WorkExperience work) //提供Clone方法调用的私有构造函数,以便克隆"工作经历"的数据
    {
        this.work = (WorkExperience)work.Clone();
    }
    //设置个人信息
    public void SetPersonalInfo(string sex, string age)
    {
        this.sex = sex;
        this.age = age;
    }
    //设置工作经历
    public void SetWorkExperience(string workDate, string company)
    {
        work.WorkDate = workDate;
        work.Company = company;
    }
    //显示
    public void Display()
    {
        Console.WriteLine("{0} {1} {2}", name, sex, age);
        Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
    }

    public object Clone()
    {
        //调用私有的构造方法,让“工作经历”克隆完成,然后再给这个“简历”对象的相关字段赋值,
        //最终返回一个深复制的简历对象
        Resume obj = new Resume(this.work);
        obj.name = this.name;
        obj.sex = this.sex;
        obj.age = this.age;
        return obj;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Resume a = new Resume("大鸟");
        a.SetPersonalInfo("", "29");
        a.SetWorkExperience("1998-2000", "XX公司");

        //只需要调用Clone方法就可以实现新简历的生成,并且可以再修改新简历的细节
        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("1998-2006", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("", "24");
        c.SetWorkExperience("1998-2003", "ZZ企业");

        a.Display();
        b.Display();
        c.Display();
    }
}
执行结果:
大鸟 男 29
工作经历:1998-2000 XX公司
大鸟 男 29
工作经历:1998-2006 YY企业
大鸟 男 24
工作经历:1998-2003 ZZ企业

/*
 * 7.1 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
 * 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 */
abstract class AbstractClass
{
    //一些抽象行为,放到子类去实现
    public abstract void PrimitiveOperation1();
    public abstract void PrimitiveOperation2();
    //模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们都推迟到子类实现
    public void TemplateMethod()
    {
        PrimitiveOperation1();
        PrimitiveOperation2();
        Console.WriteLine("");
    }
}
class ConcreteClassA : AbstractClass
{
    public override void PrimitiveOperation1()
    {
        Console.WriteLine("具体类A的方法1实现"); //与ConcreteClassB不同的方法实现
    }

    public override void PrimitiveOperation2()
    {
        Console.WriteLine("具体类A的方法2实现");
    }
}

class ConcreteClassB : AbstractClass
{
    public override void PrimitiveOperation1()
    {
        Console.WriteLine("具体类B的方法1实现"); //与ConcreteClassA不同的方法实现
    }

    public override void PrimitiveOperation2()
    {
        Console.WriteLine("具体类B的方法2实现");
    }
}

class Program
{
    static void Main(string[] args)
    {
        AbstractClass c;

        c = new ConcreteClassA();
        c.TemplateMethod();

        c = new ConcreteClassB();
        c.TemplateMethod();

        Console.Read();
    }
}

执行结果:
具体类A的方法1实现
具体类A的方法2实现

具体类B的方法1实现
具体类B的方法2实现

/*
 * 7.2 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
 * 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 */

//金庸小说考题试卷
class TestPaper
{
    public void TestQuestion1()
    {
        Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维");
        Console.WriteLine("答案:" + Answer1());
    }
    public void TestQuestion2()
    {
        Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");
        Console.WriteLine("答案:" + Answer2());
    }
    public void TestQuestion3()
    {
        Console.WriteLine(" 蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.让他们喝大量的生牛奶 d.以上全不对");
        Console.WriteLine("答案:" + Answer3());
    }
    //此方法的目的就是给继承的子类重写,因为这里每个人的答案都是不同的
    protected virtual string Answer1() { return ""; }
    protected virtual string Answer2() { return ""; }
    protected virtual string Answer3() { return ""; }
}

//学生甲抄的试卷
class TestPaperA : TestPaper
{
    protected override string Answer1()
    {
        return "b";
    }
    protected override string Answer2()
    {
        return "c";
    }
    protected override string Answer3()
    {
        return "a";
    }
}

//学生乙抄的试卷
class TestPaperB : TestPaper
{
    protected override string Answer1()
    {
        return "c";
    }
    protected override string Answer2()
    {
        return "a";
    }
    protected override string Answer3()
    {
        return "a";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("学生甲抄的试卷:");
        TestPaper studentA = new TestPaperA();
        studentA.TestQuestion1();
        studentA.TestQuestion2();
        studentA.TestQuestion3();

        Console.WriteLine();

        Console.WriteLine("学生乙抄的试卷:");
        TestPaper studentB = new TestPaperA();
        studentB.TestQuestion1();
        studentB.TestQuestion2();
        studentB.TestQuestion3();

        Console.Read();
    }
}

执行结果:
学生甲抄的试卷:
杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c
高速合金钢 d.碳素纤维
答案:b
杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝
c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:c
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司
匹林 b.牛黄解毒片 c.让他们喝大量的生牛奶 d.以上全不对
答案:a

学生乙抄的试卷:
杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c
高速合金钢 d.碳素纤维
答案:b
杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝
c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:c
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司
匹林 b.牛黄解毒片 c.让他们喝大量的生牛奶 d.以上全不对
答案:a

/*
 * 8.1 外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此接口定义了一个高层接口,
 * 这个接口使得这一系列子系统更加容易使用。 */
class SubSystemOne
{
    public void MethodOne()
    {
        Console.WriteLine(" 子系统方法一");
    }
}
class SubSystemTwo
{
    public void MethodTwo()
    {
        Console.WriteLine(" 子系统方法二");
    }
}
class SubSystemThree
{
    public void MethodThree()
    {
        Console.WriteLine(" 子系统方法三");
    }
}
class SubSystemFour
{
    public void MethodFour()
    {
        Console.WriteLine(" 子系统方法四");
    }
}

//外观类,它需要了解所有的子系统的方法或属性,进行组合,以备外界调用
class Facade
{
    SubSystemOne one;
    SubSystemTwo two;
    SubSystemThree three;
    SubSystemFour four;

    public Facade()
    {
        one = new SubSystemOne();
        two = new SubSystemTwo();
        three = new SubSystemThree();
        four = new SubSystemFour();
    }

    public void MethodA()
    {
        Console.WriteLine("\n方法组A() ---- ");
        one.MethodOne();
        two.MethodTwo();
        four.MethodFour();
    }
    public void MethodB()
    {
        Console.WriteLine("\n方法组B() ---- ");
        two.MethodTwo();
        three.MethodThree();
    }
}
class Program
{
    static void Main(string[] args)
    {
        //由于Facade的作用,客户端可以根本不知三个子系统类的存在
        Facade facade = new Facade();

        facade.MethodA();
        facade.MethodB();

        Console.Read();
    }
}

执行结果:
方法组A() ----
 子系统方法一
 子系统方法二
 子系统方法四

方法组B() ----
 子系统方法二
 子系统方法三

/*
 * 8.2 外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此接口定义了一个高层接口,
 * 这个接口使得这一系列子系统更加容易使用。 */

//股票1
class Stock1
{
    public void Sell()
    {
        Console.WriteLine(" 股票1卖出");
    }
    public void Buy()
    {
        Console.WriteLine(" 股票1买入");
    }
}
//股票2
class Stock2
{
    public void Sell()
    {
        Console.WriteLine(" 股票2卖出");
    }
    public void Buy()
    {
        Console.WriteLine(" 股票2买入");
    }
}
//股票3
class Stock3
{
    public void Sell()
    {
        Console.WriteLine(" 股票3卖出");
    }
    public void Buy()
    {
        Console.WriteLine(" 股票3买入");
    }
}

//国债1
class NationalDebt1
{
    public void Sell()
    {
        Console.WriteLine(" 国债1卖出");
    }
    public void Buy()
    {
        Console.WriteLine(" 国债1买入");
    }
}

//房地产1
class Realty1
{
    public void Sell()
    {
        Console.WriteLine(" 房地产1卖出");
    }
    public void Buy()
    {
        Console.WriteLine(" 房地产1买入");
    }
}

//基金类,它需要了解所有的股票或其他投资方式的方法或属性,进行组合,以备外界调用
class Fund
{
    Stock1 gu1;
    Stock2 gu2;
    Stock3 gu3;
    NationalDebt1 nd1;
    Realty1 rt1;

    public Fund()
    {
        gu1 = new Stock1();
        gu2 = new Stock2();
        gu3 = new Stock3();
        nd1 = new NationalDebt1();
        rt1 = new Realty1();
    }
    public void BuyFund()
    {
        gu1.Buy();
        gu2.Buy();
        gu3.Buy();
        nd1.Buy();
        rt1.Buy();
    }
    public void SellFund()
    {
        gu1.Sell();
        gu2.Sell();
        gu3.Sell();
        nd1.Sell();
        rt1.Sell();
    }
}
class Program
{
    static void Main(string[] args)
    {
        //此时用户不需要了解股票,甚至可以对股票一无所知,买了基金就回家睡觉,一段时间后再赎回就可以大把数钱。
        //参与股票的具体买卖都有基金公司完成。客户端代码非常简洁明了。
        Fund jijin = new Fund();
        //基金购买
        jijin.BuyFund();
        Console.WriteLine();
        //基金赎回
        jijin.SellFund();

        Console.Read();
    }
}

执行结果:
股票1买入
 股票2买入
 股票3买入
 国债1买入
 房地产1买入

 股票1卖出
 股票2卖出
 股票3卖出
 国债1卖出
 房地产1卖出


/*
 * 9. 建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
 */

//产品类
class Product
{
    IList<string> parts = new List<string>();

    //添加产品部件
    public void Add(string part)
    {
        parts.Add(part);
    }
    public void Show()
    {
        Console.WriteLine("\n产品 创建 ---- ");
        foreach (string part in parts) //列举所有产品部件
        {
            Console.WriteLine(part);
        }
    }
}
//抽象建造者
abstract class Builder
{
    public abstract void BuilderPartA();
    public abstract void BuilderPartB();
    public abstract Product GetResult();
}

//具体建造者
class ConcreteBuilder1 : Builder
{
    private Product product = new Product();
    //建造具体的两个部件,是部件A和部件B
    public override void BuilderPartA()
    {
        product.Add("部件A");
    }

    public override void BuilderPartB()
    {
        product.Add("部件B");
    }

    public override Product GetResult()
    {
        return product;
    }
}
//具体建造者
class ConcreteBuilder2 : Builder
{
    private Product product = new Product();
    //建造具体的两个部件,是部件X和部件Y
    public override void BuilderPartA()
    {
        product.Add("部件X");
    }

    public override void BuilderPartB()
    {
        product.Add("部件Y");
    }

    public override Product GetResult()
    {
        return product;
    }
}

//指挥者类
class Director
{
    public void Construct(Builder builder)
    {
        builder.BuilderPartA(); //用来指挥建造过程
        builder.BuilderPartB();
    }
}

class Program
{
    static void Main(string[] args)
    {
        //客户端代码,客户不知道具体的建造过程
        Director director = new Director();
        Builder b1 = new ConcreteBuilder1();
        Builder b2 = new ConcreteBuilder2();

        director.Construct(b1);
        Product p1 = b1.GetResult(); //指挥者用ConcreteBuilder1的方法来建造产品
        p1.Show();

        director.Construct(b2);
        Product p2 = b2.GetResult(); //指挥者用ConcreteBuilder2的方法来建造产品
        p2.Show();

        Console.Read();
    }
}

执行结果:
产品 创建 ----
部件A
部件B

产品 创建 ----
部件X
部件Y

/*
 * 10.1 观察者模式(Publish/Subscribe):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
 * 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 */

//抽象主题
abstract class Subject
{
    private IList<Observer> observers = new List<Observer>();

    //增加观察者
    public void Attach(Observer observer) { observers.Add(observer); }
    //移除观察者
    public void Detach(Observer observer) { observers.Remove(observer); }
    //通知
    public void Notify() { foreach (Observer o in observers) o.Update(); }

}

//抽象观察者
abstract class Observer
{
    public abstract void Update();
}

//具体主题、或具体通知者
class ConcreteSubject : Subject
{
    private string subjectState;
    //具体被观察者状态
    public string SubjectState { get { return this.subjectState; } set { this.subjectState = value; } }
}

//具体观察者
class ConcreteObserver : Observer
{
    private string name;
    private string observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject, string name)
    {
        this.subject = subject;
        this.name = name;
    }
    public override void Update()
    {
        observerState = subject.SubjectState;
        Console.WriteLine("观察者{0}的新状态是{1}", name, observerState);
    }
    public ConcreteSubject Subject { get { return this.subject; } set { this.subject = value; } }
}

class Program
{
    static void Main(string[] args)
    {
        ConcreteSubject s = new ConcreteSubject();

        s.Attach(new ConcreteObserver(s, "X"));
        s.Attach(new ConcreteObserver(s, "Y"));
        s.Attach(new ConcreteObserver(s, "Z"));

        s.SubjectState = "ABC";
        s.Notify();

        Console.Read();
    }
}
执行结果:
观察者X的新状态是ABC
观察者Y的新状态是ABC
观察者Z的新状态是ABC

/*
 * 10.2 观察者模式(Publish/Subscribe):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
 * 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 */

//抽象观察者
abstract class Observer
{
    protected string name;
    protected Subject sub;
    public Observer(string name, Subject sub)
    {
        this.name = name;
        this.sub = sub;
    }
    public abstract void Update();
}

//看股票的同事
class StockObserver : Observer
{
    public StockObserver(string name, Subject sub) : base(name, sub) { }
    public override void Update()
    {
        Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
    }
}

//看NBA的同事
class NBAObserver : Observer
{
    public NBAObserver(string name, Subject sub) : base(name, sub) { }
    public override void Update()
    {
        Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
    }
}


//通知者接口
interface Subject
{
    void Attach(Observer observer);
    void Detach(Observer observer);
    void Notify();
    string SubjectState { get; set; }
}

//老板类
class Boss : Subject
{
    private IList<Observer> observers = new List<Observer>();
    private string action;

    public string SubjectState { get { return this.action; } set { this.action = value; } } //老板状态
    public void Attach(Observer observer) //增加
    {
        observers.Add(observer); //针对抽象编程,减少了与具体类的耦合
    }
    public void Detach(Observer observer) //减少
    {
        observers.Remove(observer); //针对抽象编程,减少了与具体类的耦合
    }
    public void Notify() //通知
    {
        foreach (Observer o in observers) o.Update();
    }
}

//前台秘书类
class Secretary : Subject
{
    private IList<Observer> observers = new List<Observer>(); //同事列表
    private string action;
    public string SubjectState { get { return this.action; } set { this.action = value; } } //前台状态
    public void Attach(Observer observer) //增加
    {
        observers.Add(observer); //针对抽象编程,减少了与具体类的耦合
    }
    public void Detach(Observer observer) //减少
    {
        observers.Remove(observer); //针对抽象编程,减少了与具体类的耦合
    }
    public void Notify() //通知
    {
        foreach (Observer o in observers) o.Update();
    }
}
class Program
{
    static void Main(string[] args)
    {
        Boss huhansan = new Boss(); //老板胡汉三

        StockObserver tongshi1 = new StockObserver("张三", huhansan); //看股票的同事
        NBAObserver tongshi2 = new NBAObserver("李四", huhansan); //看NBA的同事

        huhansan.Attach(tongshi1);
        huhansan.Attach(tongshi2);
        huhansan.Detach(tongshi1); //张三其实是没有被老板通知到,所以减去

        huhansan.SubjectState = "我胡汉三回来了!"; //老板回来
        huhansan.Notify(); //发出通知

    }
}
执行结果:
我胡汉三回来了! 李四 关闭NBA直播,继续工作!

/*
 * 10.3 观察者模式(Publish/Subscribe):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
 * 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
 * 委托实现版 */

//看股票的同事
class StockObserver
{
    protected string name;
    protected Subject sub;
    public StockObserver(string name, Subject sub)
    {
        this.name = name;
        this.sub = sub;
    }
    //关闭股票行情
    public void CloseStockMarket()
    {
        Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
    }
}

//看NBA的同事
class NBAObserver
{
    protected string name;
    protected Subject sub;
    public NBAObserver(string name, Subject sub)
    {
        this.name = name;
        this.sub = sub;
    }
    //关闭NBA直播
    public void CloseNBADirectSeeding()
    {
        Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
    }
}
//通知者接口
interface Subject
{
    void Notify();
    string SubjectState { get; set; }
}

delegate void EventHandler(); //声明一个委托

//老板类
class Boss : Subject
{
    public event EventHandler Update; //声明一事件Update,类型为委托EventHandler
    private string action;

    public string SubjectState { get { return this.action; } set { this.action = value; } } //老板状态
    public void Notify() //通知
    {
        Update(); //在访问“通知”方法时,调用“更新”
    }
}
//前台秘书类
class Secretary : Subject
{
    public event EventHandler Update; //声明一事件Update,类型为委托EventHandler
    private string action;
    public string SubjectState { get { return this.action; } set { this.action = value; } } //前台状态
    public void Notify() //通知
    {
        Update(); //在访问“通知”方法时,调用“更新”
    }
}
class Program
{
    static void Main(string[] args)
    {
        Boss huhansan = new Boss(); //老板胡汉三

        StockObserver tongshi1 = new StockObserver("张三", huhansan); //看股票的同事
        NBAObserver tongshi2 = new NBAObserver("李四", huhansan); //看NBA的同事

        huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);
        huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);

        huhansan.SubjectState = "我胡汉三回来了!"; //老板回来
        huhansan.Notify(); //发出通知

    }
}
执行结果:
我胡汉三回来了! 张三 关闭股票行情,继续工作!
我胡汉三回来了! 李四 关闭NBA直播,继续工作!

/*
 * 11.1 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
 * 纯粹的抽象工厂模式 */
class Department
{
    private int _id;
    private string _deptName;
    public int ID { get { return this._id; } set { this._id = value; } }
    private string DeptName { get { return this._deptName; } set { this._deptName = value; } }
}

interface IDepartment
{
    void Insert(Department department);
    Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在SQL Server中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
        return null;
    }
}
class AccessDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在Access中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在Access中根据ID得到Department表一条记录");
        return null;
    }
}
class User
{
    private int _id;
    private string _name;
    public int ID { get { return this._id; } set { this._id = value; } }
    public string Name { get { return this._name; } set { this._name = value; } }
}
interface IUser
{
    void Insert(User user);
    User GetUser(int id);
}
class SqlserverUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在SQL Server中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
        return null;
    }
}
class AccessUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在Access中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在Access中根据ID得到User表一条记录");
        return null;
    }
}
interface IFactory
{
    IUser CreateUser();
    IDepartment CreateDepartment();
}
class SqlServerFactory : IFactory
{
    public IUser CreateUser()
    {
        return new SqlserverUser();
    }

    public IDepartment CreateDepartment()
    {
        return new SqlserverDepartment();
    }
}
class AccessFactory : IFactory
{
    public IUser CreateUser()
    {
        return new AccessUser();
    }

    public IDepartment CreateDepartment()
    {
        return new AccessDepartment();
    }
}

class Program
{
    static void Main(string[] args)
    {
        User user = new User();
        Department dept = new Department();
        IFactory factory = new AccessFactory();

        IUser iu = factory.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);

        IDepartment id = factory.CreateDepartment();
        id.Insert(dept);
        id.GetDepartment(1);

        Console.Read();
    }
}
执行结果:
在Access中给User表增加一条记录
在Access中根据ID得到User表一条记录
在Access中给Department表增加一条记录
在Access中根据ID得到Department表一条记录

/*
 * 11.2 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
 * 用简单工厂改进后的抽象工厂 */
class Department
{
    private int _id;
    private string _deptName;
    public int ID { get { return this._id; } set { this._id = value; } }
    private string DeptName { get { return this._deptName; } set { this._deptName = value; } }
}

interface IDepartment
{
    void Insert(Department department);
    Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在SQL Server中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
        return null;
    }
}
class AccessDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在Access中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在Access中根据ID得到Department表一条记录");
        return null;
    }
}
class User
{
    private int _id;
    private string _name;
    public int ID { get { return this._id; } set { this._id = value; } }
    public string Name { get { return this._name; } set { this._name = value; } }
}
interface IUser
{
    void Insert(User user);
    User GetUser(int id);
}
class SqlserverUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在SQL Server中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
        return null;
    }
}
class AccessUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在Access中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在Access中根据ID得到User表一条记录");
        return null;
    }
}
interface IFactory
{
    IUser CreateUser();
    IDepartment CreateDepartment();
}
class SqlServerFactory : IFactory
{
    public IUser CreateUser()
    {
        return new SqlserverUser();
    }

    public IDepartment CreateDepartment()
    {
        return new SqlserverDepartment();
    }
}
class AccessFactory : IFactory
{
    public IUser CreateUser()
    {
        return new AccessUser();
    }

    public IDepartment CreateDepartment()
    {
        return new AccessDepartment();
    }
}
class DataAccess
{
    private static readonly string db = "Sqlserver"; //数据库名称,可替换成Access
    //private static readonly string db = "Access";

    public static IUser CreateUser()
    {
        IUser result = null;
        switch (db) //由于db的事先设置,所以此处可以根据选择实例化出相应的对象
        {
            case "Sqlserver":
                result = new SqlserverUser();
                break;
            case "Access":
                result = new AccessUser();
                break;
        }
        return result;
    }
    public static IDepartment CreateDepartment()
    {
        IDepartment result = null;
        switch (db)
        {
            case "Sqlserver":
                result = new SqlserverDepartment();
                break;
            case "Access":
                result = new AccessDepartment();
                break;
        }
        return result;
    }
}
class Program
{
    static void Main(string[] args)
    {
        User user = new User();
        Department dept = new Department();

        //直接得到实际的数据库访问实例,而不存在任何依赖
        IUser iu = DataAccess.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);

        IDepartment id = DataAccess.CreateDepartment();
        id.Insert(dept);
        id.GetDepartment(1);

        Console.Read();
    }
}
执行结果:
在SQL Server中给User表增加一条记录
在SQL Server中根据ID得到User表一条记录
在SQL Server中给Department表增加一条记录
在SQL Server中根据ID得到Department表一条记录

/*
 * 11.3 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
 * 加入反射改进后的抽象工厂
 */

class Department
{
    private int _id;
    private string _deptName;
    public int ID { get { return this._id; } set { this._id = value; } }
    private string DeptName { get { return this._deptName; } set { this._deptName = value; } }
}

interface IDepartment
{
    void Insert(Department department);
    Department GetDepartment(int id);
}
class SqlserverDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在SQL Server中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
        return null;
    }
}
class AccessDepartment : IDepartment
{
    public void Insert(Department department)
    {
        Console.WriteLine("在Access中给Department表增加一条记录");
    }

    public Department GetDepartment(int id)
    {
        Console.WriteLine("在Access中根据ID得到Department表一条记录");
        return null;
    }
}
class User
{
    private int _id;
    private string _name;
    public int ID { get { return this._id; } set { this._id = value; } }
    public string Name { get { return this._name; } set { this._name = value; } }
}
interface IUser
{
    void Insert(User user);
    User GetUser(int id);
}
class SqlserverUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在SQL Server中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
        return null;
    }
}
class AccessUser : IUser
{
    public void Insert(User user)
    {
        Console.WriteLine("在Access中给User表增加一条记录");
    }

    public User GetUser(int id)
    {
        Console.WriteLine("在Access中根据ID得到User表一条记录");
        return null;
    }
}
interface IFactory
{
    IUser CreateUser();
    IDepartment CreateDepartment();
}
class SqlServerFactory : IFactory
{
    public IUser CreateUser()
    {
        return new SqlserverUser();
    }

    public IDepartment CreateDepartment()
    {
        return new SqlserverDepartment();
    }
}
class AccessFactory : IFactory
{
    public IUser CreateUser()
    {
        return new AccessUser();
    }

    public IDepartment CreateDepartment()
    {
        return new AccessDepartment();
    }
}
class DataAccess
{
    private static readonly string AssemblyName = "ConsoleApplication2"; //程序集名称
    private static readonly string db = "Sqlserver"; //数据库名称,可替换成Access

    public static IUser CreateUser()
    {
        //string className = AssemblyName + "." + db + "User";
        string className = db + "User";
        return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
    }
    public static IDepartment CreateDepartment()
    {
        //string className = AssemblyName + "." + db + "Department";
        string className = db + "Department";
        return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
    }
}
class Program
{
    static void Main(string[] args)
    {
        User user = new User();
        Department dept = new Department();

        //直接得到实际的数据库访问实例,而不存在任何依赖
        IUser iu = DataAccess.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);

        IDepartment id = DataAccess.CreateDepartment();
        id.Insert(dept);
        id.GetDepartment(1);

        Console.Read();
    }
}
执行结果:
在SQL Server中给User表增加一条记录
在SQL Server中根据ID得到User表一条记录
在SQL Server中给Department表增加一条记录
在SQL Server中根据ID得到Department表一条记录

/*
 * 12.1 状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 */
class Context
{
    private State state;
    public Context(State state)
    {
        this.state = state; //定义Context的初始状态
    }
    public State State //可读写的状态属性,用于读取当前状态和设置新状态
    {
        get { return this.state; }
        set
        {
            state = value;
            Console.WriteLine("当前状态:" + state.GetType().Name);
        }
    }
    public void Request()
    {
        state.Handle(this); //对请求做处理,并设置下一状态
    }
}

abstract class State
{
    public abstract void Handle(Context context);
}
class ConcreteStateA : State
{
    public override void Handle(Context context)
    {
        //设置ConcreteStateA的下一状态是ConcreteStateB
        context.State = new ConcreteStateB();
    }
}
class ConcreteStateB : State
{
    public override void Handle(Context context)
    {
        //设置ConcreteStateB的下一状态是ConcreteStateA
        context.State = new ConcreteStateA();
    }
}
class Program
{
    static void Main(string[] args)
    {
        Context c = new Context(new ConcreteStateA()); //设置Context的初始状态为ConcreteStateA
        c.Request(); c.Request(); c.Request(); c.Request(); //不断的请求,同时更改状态
        Console.Read();
    }
}
执行结果
当前状态:ConcreteStateB
当前状态:ConcreteStateA
当前状态:ConcreteStateB
当前状态:ConcreteStateA

/*
 * 12.2 状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 */
//抽象状态
public abstract class State
{
    public abstract void WriteProgram(Work w);
}
//上午工作状态
public class ForenoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 12) Console.WriteLine("当前时间:{0}点,上午工作,精神百倍", w.Hour);
        else
        {
            w.SetState(new NoonState()); //超过12点,则转入中午工作状态
            w.WriteProgram();
        }
    }
}
//中午工作状态
public class NoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 13) Console.WriteLine("当前时间:{0}点,饿了,午饭;犯困,午休。", w.Hour);
        else
        {
            w.SetState(new AfternoonState()); //超过13点,则转入下午工作状态
            w.WriteProgram();
        }

    }
}
//下午和傍晚工作状态
public class AfternoonState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.Hour < 17) Console.WriteLine("当前时间:{0}点,下午状态还不错,继续努力", w.Hour);
        else
        {
            w.SetState(new EveningState()); //超过17点,则转入傍晚工作状态
            w.WriteProgram();
        }
    }
}
//晚间工作状态
public class EveningState : State
{
    public override void WriteProgram(Work w)
    {
        if (w.TaskFinished)
        {
            w.SetState(new RestState()); //如果完成任务,则转入下班状态
            w.WriteProgram();
        }
        else
        {
            if (w.Hour < 21) Console.WriteLine("当前时间:{0}点,加班哦,疲累之极", w.Hour);
            else
            {
                w.SetState(new SleepingState()); //超过21点,则转入睡眠工作状态
                w.WriteProgram();
            }
        }
    }
}
//睡眠状态
public class SleepingState : State
{
    public override void WriteProgram(Work w)
    {
        Console.WriteLine("当前时间:{0}点,不行了,睡着了。", w.Hour);
    }
}
//下班休息状态
public class RestState : State
{
    public override void WriteProgram(Work w)
    {
        Console.WriteLine("当前时间:{0}点,下班回家了", w.Hour);
    }
}

//工作类
public class Work
{
    private State current;
    private double hour;
    private bool finish = false;
    public Work()
    {
        //工作初始化为上午工作状态,即上午9点开始上班
        current = new ForenoonState();
    }
    //"钟点"属性,状态转换的依据
    public double Hour { get { return this.hour; } set { this.hour = value; } }
    //"任务完成"属性,是否能下班的依据
    public bool TaskFinished { get { return this.finish; } set { this.finish = value; } }
    public void SetState(State s) { current = s; }
    public void WriteProgram() { current.WriteProgram(this); }
}

class Program
{
    static void Main(string[] args)
    {
        Work emergencyProjects = new Work();
        emergencyProjects.Hour = 9;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 10;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 12;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 13;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 14;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 17;

        emergencyProjects.TaskFinished = false;

        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 19;
        emergencyProjects.WriteProgram();
        emergencyProjects.Hour = 22;
        emergencyProjects.WriteProgram();

        Console.Read();
    }
}
执行结果:
当前时间:9点,上午工作,精神百倍
当前时间:10点,上午工作,精神百倍
当前时间:12点,饿了,午饭;犯困,午休。
当前时间:13点,下午状态还不错,继续努力
当前时间:14点,下午状态还不错,继续努力
当前时间:17点,加班哦,疲累之极
当前时间:19点,加班哦,疲累之极
当前时间:22点,不行了,睡着了。

/*
 * 13.1 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 */
class Target
{
    public virtual void Request()
    {
        Console.WriteLine("普通请求!");
    }
}
//需要适配的类
class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("特殊请求!");
    }
}
class Adapter : Target
{
    private Adaptee adaptee = new Adaptee(); //建立一个私有的Adaptee对象
    public override void Request()
    {
        //这样就可以把表面上调用Request()方法变成实际调用SpecificRequest()
        adaptee.SpecificRequest();
    }
}
class Program
{
    static void Main(string[] args)
    {
        Target target = new Adapter();
        target.Request();
        Console.Read(); //对客户端来说,调用的就是Target的Request()
    }
}
执行结果:特殊请求!

/*
 * 13.2 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 */

//球员
abstract class Player
{
    protected string name;
    public Player(string name)
    {
        this.name = name;
    }
    public abstract void Attack();//进攻和防守方法
    public abstract void Defense();
}

//前锋
class Forwards : Player
{
    public Forwards(string name) : base(name) { }
    public override void Attack()
    {
        Console.WriteLine("前锋 {0} 进攻", name);
    }

    public override void Defense()
    {
        Console.WriteLine("前锋 {0} 防守", name);
    }
}
//中锋
class Center : Player
{
    public Center(string name) : base(name) { }
    public override void Attack()
    {
        Console.WriteLine("中锋 {0} 进攻", name);
    }

    public override void Defense()
    {
        Console.WriteLine("中锋 {0} 防守", name);
    }
}
//后卫
class Grards : Player
{
    public Grards(string name) : base(name) { }
    public override void Attack()
    {
        Console.WriteLine("后卫 {0} 进攻", name);
    }

    public override void Defense()
    {
        Console.WriteLine("后卫 {0} 防守", name);
    }
}
//外籍中锋
class ForeignCenter
{
    private string name;
    //外籍中锋类球员的姓名故意用属性而不是构造方法,来区别与前三个球员类的不同
    public string Name { get { return name; } set { name = value; } }
    public void 进攻() //表明‘外籍中锋’只懂得中文‘进攻’
    {
        Console.WriteLine("外籍中锋 {0} 进攻", name);
    }
    public void 防守() //表明‘外籍中锋’只懂得中文‘防守’
    {
        Console.WriteLine("外检中锋 {0} 防守", name);
    }
}
//翻译者
class Translator : Player
{
    //声明并实例化一个内部‘外籍中锋’对象,表明翻译者与外籍球员有关联
    private ForeignCenter wjzf = new ForeignCenter();
    public Translator(string name)
        : base(name)
    {
        wjzf.Name = name;
    }
    public override void Attack() //翻译者将‘Attack’翻译为‘进攻’告诉外籍中锋
    {
        wjzf.进攻();
    }

    public override void Defense() //翻译者将‘Defense’翻译为‘防守’告诉外籍中锋
    {
        wjzf.防守();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Player b = new Forwards("巴蒂尔");
        b.Attack();
        Player m = new Grards("麦克格雷迪");
        m.Attack();

        //翻译者告诉姚明,教练要求你既要‘进攻’又要‘防守’
        Player ym = new Translator("姚明");
        ym.Attack();
        ym.Defense();
    }
}

执行结果:
前锋 巴蒂尔 进攻
后卫 麦克格雷迪 进攻
外籍中锋 姚明 进攻
外检中锋 姚明 防守


/*
 * 14.1 备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 */

//发起人
class Originator
{
    private string state;
    //需要保存的属性,可能有多个
    public string State { get { return this.state; } set { this.state = value; } }
    //创建备忘录,将当前需要保存的信息导入并实例化出一个Memento对象
    public Memento CreateMemento()
    {
        return (new Memento(this.state));
    }
    //恢复备忘录,将Memento导入并将相关数据恢复
    public void SetMemento(Memento memento)
    {
        this.state = memento.State;
    }
    //显示数据
    public void Show()
    {
        Console.WriteLine("State=" + this.state);
    }
}

class Memento
{
    private string state;
    //构造方法,将相关数据导入
    public Memento(string state)
    {
        this.state = state;
    }
    //需要保存的数据属性,可以是多个
    public string State
    {
        get { return this.state; }
    }
}
//管理者类
class Caretaker
{
    //得到或设置备忘录
    private Memento memento;
    public Memento Memento
    {
        get { return this.memento; }
        set { this.memento = value; }
    }
}
class Program
{
    static void Main(string[] args)
    {
        Originator o = new Originator();
        //Originator初始状态,状态属性为‘On’
        o.State = "On";
        o.Show();

        Caretaker c = new Caretaker();
        //保存状态时,由于有了很好的封装,可以隐藏Originator的实现细节
        c.Memento = o.CreateMemento();

        o.State = "Off"; //Originator改变了状态属性为‘Off’
        o.Show();

        o.SetMemento(c.Memento);
        o.Show();
        Console.Read();
    }
}
执行结果:
State=On
State=Off
State=On

/*
 * 14.2 备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 */
class GameRole
{
    private int vit; //生命力
    private int atk; //攻击力
    private int def; //防御力
    public int Vitality { get { return vit; } set { vit = value; } }
    public int Attack { get { return atk; } set { atk = value; } }
    public int Defense { get { return def; } set { def = value; } }

    //保存角色状态
    //新增“保存角色状态”方法,将游戏角色的三个状态值通过实例化“角色状态存储箱”返回
    public RoleStateMemento SaveState()
    {
        return (new RoleStateMemento(vit, atk, def));
    }
    //恢复角色状态
    //新增“恢复角色状态”方法,可将外部的“角色状态存储箱”中状态值恢复给游戏角色
    public void RecoveryState(RoleStateMemento memento)
    {
        this.vit = memento.Vitality;
        this.atk = memento.Attack;
        this.def = memento.Defense;
    }

    //状态显示
    public void StateDisplay()
    {
        Console.WriteLine("角色当前状态:");
        Console.WriteLine("体力:{0}", this.vit);
        Console.WriteLine("攻击力:{0}", this.atk);
        Console.WriteLine("防御力:{0}", this.def);
        Console.WriteLine("");
    }
    //获得初始状态
    public void GetInitState()
    {
        //数据通常来自本机磁盘或远程数据库
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }
    //战斗
    public void Fight()
    {
        this.vit = 0; //在与Boss大战后的游戏数据损耗为零
        this.atk = 0;
        this.def = 0;
    }
}

class RoleStateMemento
{
    private int vit;
    private int atk;
    private int def;
    public RoleStateMemento(int vit, int atk, int def)
    {
        this.vit = vit; //将生命力、攻击力、防御力存入状态存储箱对象中
        this.atk = atk;
        this.def = def;
    }
    public int Vitality { get { return vit; } set { vit = value; } } //生命力
    public int Attack { get { return atk; } set { atk = value; } } //攻击力
    public int Defense { get { return def; } set { def = value; } } //防御力
}

//角色状态管理者类
class RoleStateCaretaker
{
    private RoleStateMemento memento;
    public RoleStateMemento Memento { get { return memento; } set { memento = value; } }
}

class Program
{
    static void Main(string[] args)
    {
        GameRole lixiaoyao = new GameRole();
        lixiaoyao.GetInitState(); //游戏角色初始状态,三项指标数据都是100
        lixiaoyao.StateDisplay();

        //保存进度
        //保存进度时,由于封装在Memento中,因此我们并不知道保存了哪些具体的角色数据
        RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
        stateAdmin.Memento = lixiaoyao.SaveState();

        //大战Boss时,损耗严重
        //开始打Boss,三项指标数据都下降很多,非常糟糕,GameOver了
        lixiaoyao.Fight();
        lixiaoyao.StateDisplay();

        //不行,恢复保存的状态,重新来过
        lixiaoyao.RecoveryState(stateAdmin.Memento);
        lixiaoyao.StateDisplay();

        Console.Read();
    }
}
执行结果:
角色当前状态:
体力:100
攻击力:100
防御力:100

角色当前状态:
体力:0
攻击力:0
防御力:0

角色当前状态:
体力:100
攻击力:100
防御力:100

/*
 * 15.1 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 */
abstract class Component
{
    protected string name;

    public Component(string name)
    {
        this.name = name;
    }

    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
}

class Composite : Component
{
    private List<Component> children = new List<Component>();

    public Composite(string name)
        : base(name)
    { }

    public override void Add(Component c)
    {
        children.Add(c);
    }

    public override void Remove(Component c)
    {
        children.Remove(c);
    }

    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);

        foreach (Component component in children)
        {
            component.Display(depth + 2);
        }
    }
}

class Leaf : Component
{
    public Leaf(string name) : base(name) { }

    public override void Add(Component c)
    {
        Console.WriteLine("Cannot add to a leaf");
    }

    public override void Remove(Component c)
    {
        Console.WriteLine("Cannot remove from a leaf");
    }

    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Composite root = new Composite("root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));

        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));

        root.Add(comp);

        Composite comp2 = new Composite("Composite XY");
        comp2.Add(new Leaf("Leaf XYA"));
        comp2.Add(new Leaf("Leaf XYB"));

        comp.Add(comp2);

        root.Add(new Leaf("Leaf C"));

        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);

        root.Display(1);

        Console.Read();
    }
}

执行结果:
-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
-----Composite XY
-------Leaf XYA
-------Leaf XYB
---Leaf C

/*
 * 15.2 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 */
abstract class Company
{
    protected string name;
    public Company(string name)
    {
        this.name = name;
    }

    public abstract void Add(Company c);//增加
    public abstract void Remove(Company c);//移除
    public abstract void Display(int depth);//显示
    public abstract void LineOfDuty();//履行职责

}

class ConcreteCompany : Company
{
    private List<Company> children = new List<Company>();

    public ConcreteCompany(string name) : base(name) { }

    public override void Add(Company c) { children.Add(c); }

    public override void Remove(Company c) { children.Remove(c); }

    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);

        foreach (Company component in children)
        {
            component.Display(depth + 2);
        }
    }

    //履行职责
    public override void LineOfDuty()
    {
        foreach (Company component in children) component.LineOfDuty();
    }

}

//人力资源部
class HRDepartment : Company
{
    public HRDepartment(string name) : base(name) { }

    public override void Add(Company c) { }

    public override void Remove(Company c) { }

    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }


    public override void LineOfDuty()
    {
        Console.WriteLine("{0} 员工招聘培训管理", name);
    }
}

//财务部
class FinanceDepartment : Company
{
    public FinanceDepartment(string name) : base(name) { }

    public override void Add(Company c) { }

    public override void Remove(Company c) { }

    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }
    public override void LineOfDuty()
    {
        Console.WriteLine("{0} 公司财务收支管理", name);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ConcreteCompany root = new ConcreteCompany("北京总公司");
        root.Add(new HRDepartment("总公司人力资源部"));
        root.Add(new FinanceDepartment("总公司财务部"));

        ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
        comp.Add(new HRDepartment("华东分公司人力资源部"));
        comp.Add(new FinanceDepartment("华东分公司财务部"));
        root.Add(comp);

        ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
        comp1.Add(new HRDepartment("南京办事处人力资源部"));
        comp1.Add(new FinanceDepartment("南京办事处财务部"));
        comp.Add(comp1);

        ConcreteCompany comp2 = new ConcreteCompany("杭州办事处");
        comp2.Add(new HRDepartment("杭州办事处人力资源部"));
        comp2.Add(new FinanceDepartment("杭州办事处财务部"));
        comp.Add(comp2);

        Console.WriteLine("\n结构图:");
        root.Display(1);
        Console.WriteLine("\n职责:");
        root.LineOfDuty();

        Console.Read();
    }
}

执行结果:
结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部

职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理

/*
 * 16.1 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而有不暴露该对象的内部表示 */
abstract class Aggregate
{
    public abstract Iterator CreateIterator();
}

class ConcreteAggregate : Aggregate
{
    private IList<object> items = new List<object>();
    public override Iterator CreateIterator()
    {
        return new ConcreteIterator(this);
    }
    public int Count { get { return items.Count; } }

    public object this[int index]
    {
        get { return items[index]; }
        set { items.Insert(index, value); }
    }
}

abstract class Iterator
{
    public abstract object First();
    public abstract object Next();
    public abstract bool IsDone();
    public abstract object CurrentItem();
}

class ConcreteIterator : Iterator
{
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate aggregate)
    {
        this.aggregate = aggregate;
    }
    public override object First()
    {
        return aggregate[0];
    }
    public override object Next()
    {
        object ret = null;
        current++;

        if (current < aggregate.Count)
        {
            ret = aggregate[current];
        }

        return ret;
    }
    public override object CurrentItem()
    {
        return aggregate[current];
    }
    public override bool IsDone()
    {
        return current >= aggregate.Count ? true : false;
    }
}
class ConcreteIteratorDesc : Iterator
{
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIteratorDesc(ConcreteAggregate aggregate)
    {
        this.aggregate = aggregate;
        current = aggregate.Count - 1;
    }
    public override object First()
    {
        return aggregate[aggregate.Count - 1];
    }
    public override object Next()
    {
        object ret = null;
        current--;
        if (current >= 0)
        {
            ret = aggregate[current];
        }
        return ret;
    }
    public override object CurrentItem()
    {
        return aggregate[current];
    }
    public override bool IsDone()
    {
        return current < 0 ? true : false;
    }
}

class Program
{
    static void Main(string[] args)
    {
        ConcreteAggregate a = new ConcreteAggregate();

        a[0] = "大鸟"; a[1] = "小菜"; a[2] = "行李"; a[3] = "老外"; a[4] = "公交内部员工"; a[5] = "小偷";

        Iterator i = new ConcreteIterator(a);
        //Iterator i = new ConcreteIteratorDesc(a);
        object item = i.First();
        while (!i.IsDone())
        {
            Console.WriteLine("{0} 请买车票!", i.CurrentItem());
            i.Next();
        }

        Console.Read();
    }
}

执行结果:
大鸟 请买车票!
小菜 请买车票!
行李 请买车票!
老外 请买车票!
公交内部员工 请买车票!
小偷 请买车票!

/*
 * 16.2 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而有不暴露该对象的内部表示 */
class Program
{
    static void Main(string[] args)
    {
        IList<string> a = new List<string>();
        a.Add("大鸟");
        a.Add("小菜");
        a.Add("行李");
        a.Add("老外");
        a.Add("公交内部员工");
        a.Add("小偷");

        foreach (string item in a)
        {
            Console.WriteLine("{0} 请买车票!", item);
        }

        IEnumerator<string> e = a.GetEnumerator();
        while (e.MoveNext())
        {
            Console.WriteLine("{0} 请买车票!", e.Current);

        }
        Console.Read();
    }
}

执行结果:
大鸟 请买车票!
小菜 请买车票!
行李 请买车票!
老外 请买车票!
公交内部员工 请买车票!
小偷 请买车票!
大鸟 请买车票!
小菜 请买车票!
行李 请买车票!
老外 请买车票!
公交内部员工 请买车票!
小偷 请买车票!

/*
 * 17. 单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点 */
class Singleton
{
    private static Singleton instance;
    private static readonly object syncRoot = new object();
    private Singleton() { }

    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            lock (syncRoot)
            {
                if (instance == null) instance = new Singleton();
            }
        }
        return instance;
    }
}

//public sealed class Singleton
//{
//    private static readonly Singleton instance = new Singleton();
//    private Singleton() { }
//    public static Singleton GetInstance()
//    {
//        return instance;
//    }
//}

class Program
{
    static void Main(string[] args)
    {
        Singleton s1 = Singleton.GetInstance();
        Singleton s2 = Singleton.GetInstance();

        if (s1 == s2) Console.WriteLine("Objects are the same instance");

        Console.Read();
    }
}

执行结果:
Objects are the same instance

/*
 * 18.1 桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化 */
class Abstraction
{
    protected Implementor implementor;
    public void SetImplementor(Implementor implementor)
    {
        this.implementor = implementor;
    }
    public virtual void Operation()
    {
        implementor.Operation();
    }
}
class RefinedAbstraction : Abstraction
{
    public override void Operation()
    {
        implementor.Operation();
    }
}
abstract class Implementor
{
    public abstract void Operation();
}
class ConcreteImplementorA : Implementor
{
    public override void Operation()
    {
        Console.WriteLine("具体实现A的方法执行");
    }
}
class ConcreteImplementorB : Implementor
{
    public override void Operation()
    {
        Console.WriteLine("具体实现B的方法执行");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Abstraction ab = new RefinedAbstraction();

        ab.SetImplementor(new ConcreteImplementorA());
        ab.Operation();

        ab.SetImplementor(new ConcreteImplementorB());
        ab.Operation();

        Console.Read();
    }
}

执行结果:
具体实现A的方法执行
具体实现B的方法执行

/*
 * 18.2 桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化 */
//手机品牌
abstract class HandsetBrand
{
    protected HandsetSoft soft;
    //设置手机软件
    public void SetHandsetSoft(HandsetSoft soft) { this.soft = soft; }
    //运行
    public abstract void Run();
}

//手机品牌N
class HandsetBrandN : HandsetBrand
{
    public override void Run() { soft.Run(); }
}

//手机品牌M
class HandsetBrandM : HandsetBrand
{
    public override void Run() { soft.Run(); }
}

//手机品牌S
class HandsetBrandS : HandsetBrand
{
    public override void Run() { soft.Run(); }
}

//手机软件
abstract class HandsetSoft
{
    public abstract void Run();
}

//手机游戏
class HandsetGame : HandsetSoft
{
    public override void Run() { Console.WriteLine("运行手机游戏"); }
}

//手机通讯录
class HandsetAddressList : HandsetSoft
{
    public override void Run() { Console.WriteLine("运行手机通讯录"); }
}

//手机MP3播放
class HandsetMP3 : HandsetSoft
{
    public override void Run() { Console.WriteLine("运行手机MP3播放"); }
}
class Program
{
    static void Main(string[] args)
    {
        HandsetBrand ab;
        ab = new HandsetBrandN();

        ab.SetHandsetSoft(new HandsetGame());
        ab.Run();

        ab.SetHandsetSoft(new HandsetAddressList());
        ab.Run();

        ab = new HandsetBrandM();

        ab.SetHandsetSoft(new HandsetGame());
        ab.Run();

        ab.SetHandsetSoft(new HandsetAddressList());
        ab.Run();

        Console.Read();
    }
}

执行结果:
运行手机游戏
运行手机通讯录
运行手机游戏
运行手机通讯录

/*
 * 19.1 命令模式(Command):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作 */
abstract class Command
{
    protected Receiver receiver;
    public Command(Receiver receiver)
    {
        this.receiver = receiver;
    }
    abstract public void Execute();
}
class ConcreteCommand : Command
{
    public ConcreteCommand(Receiver receiver) : base(receiver) { }
    public override void Execute()
    {
        receiver.Action();
    }
}
class Receiver
{
    public void Action()
    {
        Console.WriteLine("执行请求!");
    }
}

class Invoker
{
    private Command command;

    public void SetCommand(Command command)
    {
        this.command = command;
    }
    public void ExecuteCommand()
    {
        command.Execute();
    }
}
class Program
{
    static void Main(string[] args)
    {
        Receiver r = new Receiver();
        Command c = new ConcreteCommand(r);
        Invoker i = new Invoker();

        // Set and execute command 
        i.SetCommand(c);
        i.ExecuteCommand();

        Console.Read();
    }
}

执行结果:执行请求!

/*
 * 19.2 命令模式(Bridge):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作 */

//服务员
public class Waiter
{
    private IList<Command> orders = new List<Command>();

    //设置订单
    public void SetOrder(Command command)
    {
        if (command.ToString() == "命令模式.BakeChickenWingCommand")
        {
            Console.WriteLine("服务员:鸡翅没有了,请点别的烧烤。");
        }
        else
        {
            orders.Add(command);
            Console.WriteLine("增加订单:" + command.ToString() + "  时间:" + DateTime.Now.ToString());
        }
    }

    //取消订单
    public void CancelOrder(Command command)
    {
        orders.Remove(command);
        Console.WriteLine("取消订单:" + command.ToString() + "  时间:" + DateTime.Now.ToString());
    }

    //通知全部执行
    public void Notify()
    {
        foreach (Command cmd in orders) cmd.ExcuteCommand();
    }
}

//抽象命令
public abstract class Command
{
    protected Barbecuer receiver;
    public Command(Barbecuer receiver)
    {
        this.receiver = receiver;
    }
    //执行命令
    abstract public void ExcuteCommand();
}

//烤羊肉串命令
class BakeMuttonCommand : Command
{
    public BakeMuttonCommand(Barbecuer receiver) : base(receiver) { }
    public override void ExcuteCommand()
    {
        receiver.BakeMutton();
    }
}

//烤鸡翅命令
class BakeChickenWingCommand : Command
{
    public BakeChickenWingCommand(Barbecuer receiver) : base(receiver) { }
    public override void ExcuteCommand()
    {
        receiver.BakeChickenWing();
    }
}

//烤肉串者
public class Barbecuer
{
    public void BakeMutton()
    {
        Console.WriteLine("烤羊肉串!");
    }
    public void BakeChickenWing()
    {
        Console.WriteLine("烤鸡翅!");
    }
}
class Program
{
    static void Main(string[] args)
    {
        //开店前的准备
        Barbecuer boy = new Barbecuer();
        Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
        Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
        Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
        Waiter girl = new Waiter();

        //开门营业 顾客点菜
        girl.SetOrder(bakeMuttonCommand1);
        girl.SetOrder(bakeMuttonCommand2);
        girl.SetOrder(bakeChickenWingCommand1);

        //点菜完闭,通知厨房
        girl.Notify();

        Console.Read();
    }
}

执行结果:
增加订单:BakeMuttonCommand  时间:2015/9/2 13:38:43
增加订单:BakeMuttonCommand  时间:2015/9/2 13:38:43
增加订单:BakeChickenWingCommand  时间:2015/9/2 13:38:43
烤羊肉串!
烤羊肉串!
烤鸡翅!

/*
 * 20.1 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 */

abstract class Handler
{
    protected Handler successor;
    public void SetSuccessor(Handler successor)
    {
        this.successor = successor;
    }
    public abstract void HandleRequest(int request);
}
class ConcreteHandler1 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 0 && request < 10)
        {
            Console.WriteLine("{0}  处理请求  {1}",
              this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}
class ConcreteHandler2 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 10 && request < 20)
        {
            Console.WriteLine("{0}  处理请求  {1}",
              this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}
class ConcreteHandler3 : Handler
{
    public override void HandleRequest(int request)
    {
        if (request >= 20 && request < 30)
        {
            Console.WriteLine("{0}  处理请求  {1}",
              this.GetType().Name, request);
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);

        int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };

        foreach (int request in requests)
        {
            h1.HandleRequest(request);
        }

        Console.Read();
    }
}

执行结果:
ConcreteHandler1  处理请求  2
ConcreteHandler1  处理请求  5
ConcreteHandler2  处理请求  14
ConcreteHandler3  处理请求  22
ConcreteHandler2  处理请求  18
ConcreteHandler1  处理请求  3
ConcreteHandler3  处理请求  27
ConcreteHandler3  处理请求  20

/*
 * 20.2 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 */

//管理者
abstract class Manager
{
    protected string name;
    //管理者的上级
    protected Manager superior;
    public Manager(string name) { this.name = name; }
    //设置管理者的上级
    public void SetSuperior(Manager superior) { this.superior = superior; }
    //申请请求
    abstract public void RequestApplications(Request request);
}

//经理
class CommonManager : Manager
{
    public CommonManager(string name) : base(name) { }
    public override void RequestApplications(Request request)
    {
        if (request.RequestType == "请假" && request.Number <= 2)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else
        {
            if (superior != null) superior.RequestApplications(request);
        }
    }
}

//总监
class Majordomo : Manager
{
    public Majordomo(string name) : base(name) { }
    public override void RequestApplications(Request request)
    {
        if (request.RequestType == "请假" && request.Number <= 5)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else
        {
            if (superior != null) superior.RequestApplications(request);
        }
    }
}

//总经理
class GeneralManager : Manager
{
    public GeneralManager(string name) : base(name) { }
    public override void RequestApplications(Request request)
    {
        if (request.RequestType == "请假")
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number <= 500)
        {
            Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
        }
        else if (request.RequestType == "加薪" && request.Number > 500)
        {
            Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number);
        }
    }
}

//申请
class Request
{
    //申请类别
    private string requestType;
    public string RequestType { get { return requestType; } set { requestType = value; } }

    //申请内容
    private string requestContent;
    public string RequestContent { get { return requestContent; } set { requestContent = value; } }

    //数量
    private int number;
    public int Number { get { return number; } set { number = value; } }
}

class Program
{
    static void Main(string[] args)
    {
        CommonManager jinli = new CommonManager("金利");
        Majordomo zongjian = new Majordomo("宗剑");
        GeneralManager zhongjingli = new GeneralManager("钟精励");
        jinli.SetSuperior(zongjian);
        zongjian.SetSuperior(zhongjingli);

        Request request = new Request();
        request.RequestType = "请假";
        request.RequestContent = "小菜请假";
        request.Number = 1;
        jinli.RequestApplications(request);

        Request request2 = new Request();
        request2.RequestType = "请假";
        request2.RequestContent = "小菜请假";
        request2.Number = 4;
        jinli.RequestApplications(request2);

        Request request3 = new Request();
        request3.RequestType = "加薪";
        request3.RequestContent = "小菜请求加薪";
        request3.Number = 500;
        jinli.RequestApplications(request3);

        Request request4 = new Request();
        request4.RequestType = "加薪";
        request4.RequestContent = "小菜请求加薪";
        request4.Number = 1000;
        jinli.RequestApplications(request4);

        Console.Read();
    }
}

执行结果:
金利:小菜请假 数量1 被批准
宗剑:小菜请假 数量4 被批准
钟精励:小菜请求加薪 数量500 被批准
钟精励:小菜请求加薪 数量1000 再说吧

/*
 * 21.1 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互 */
abstract class Mediator
{
    public abstract void Send(string message, Colleague colleague);
}

class ConcreteMediator : Mediator
{
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public ConcreteColleague1 Colleague1 { set { colleague1 = value; } }

    public ConcreteColleague2 Colleague2 { set { colleague2 = value; } }

    public override void Send(string message, Colleague colleague)
    {
        if (colleague == colleague1) colleague2.Notify(message);
        else colleague1.Notify(message);
    }
}

abstract class Colleague
{
    protected Mediator mediator;
    public Colleague(Mediator mediator) { this.mediator = mediator; }
}

class ConcreteColleague1 : Colleague
{
    public ConcreteColleague1(Mediator mediator) : base(mediator) { }
    public void Send(string message)
    {
        mediator.Send(message, this);
    }
    public void Notify(string message)
    {
        Console.WriteLine("同事1得到信息:" + message);
    }
}
class ConcreteColleague2 : Colleague
{
    public ConcreteColleague2(Mediator mediator) : base(mediator) { }
    public void Send(string message)
    {
        mediator.Send(message, this);
    }
    public void Notify(string message)
    {
        Console.WriteLine("同事2得到信息:" + message);
    }
}
class Program
{
    static void Main(string[] args)
    {
        ConcreteMediator m = new ConcreteMediator();

        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);

        m.Colleague1 = c1;
        m.Colleague2 = c2;

        c1.Send("吃过饭了吗?");
        c2.Send("没有呢,你打算请客?");

        Console.Read();
    }
}

执行结果:
同事2得到信息:吃过饭了吗?
同事1得到信息:没有呢,你打算请客?

using System;
using System.Collections.Generic;
using System.Text;

/*
 * 21.2 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互 */

//联合国机构
abstract class UnitedNations
{
    /// <summary>
    /// 声明
    /// </summary>
    /// <param name="message">声明信息</param>
    /// <param name="colleague">声明国家</param>
    public abstract void Declare(string message, Country colleague);
}

//联合国安全理事会
class UnitedNationsSecurityCouncil : UnitedNations
{
    private USA colleague1;
    private Iraq colleague2;

    public USA Colleague1 { set { colleague1 = value; } }

    public Iraq Colleague2 { set { colleague2 = value; } }

    public override void Declare(string message, Country colleague)
    {
        if (colleague == colleague1) colleague2.GetMessage(message);
        else colleague1.GetMessage(message);
    }
}
//国家
abstract class Country
{
    protected UnitedNations mediator;
    public Country(UnitedNations mediator) { this.mediator = mediator; }
}

//美国
class USA : Country
{
    public USA(UnitedNations mediator) : base(mediator) { }
    //声明
    public void Declare(string message)
    {
        mediator.Declare(message, this);
    }
    //获得消息
    public void GetMessage(string message)
    {
        Console.WriteLine("美国获得对方信息:" + message);
    }
}
//伊拉克
class Iraq : Country
{
    public Iraq(UnitedNations mediator) : base(mediator) { }
    //声明
    public void Declare(string message)
    {
        mediator.Declare(message, this);
    }
    //获得消息
    public void GetMessage(string message)
    {
        Console.WriteLine("伊拉克获得对方信息:" + message);
    }
}
class Program
{
    static void Main(string[] args)
    {
        UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();

        USA c1 = new USA(UNSC);
        Iraq c2 = new Iraq(UNSC);

        UNSC.Colleague1 = c1;
        UNSC.Colleague2 = c2;

        c1.Declare("不准研制核武器,否则要发动战争!");
        c2.Declare("我们没有核武器,也不怕侵略。");

        Console.Read();
    }
}

执行结果:
伊拉克获得对方信息:不准研制核武器,否则要发动战争!
美国获得对方信息:我们没有核武器,也不怕侵略。

/*
 * 22.1 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象 */
class FlyweightFactory
{
    private Hashtable flyweights = new Hashtable();
    public FlyweightFactory()
    {
        flyweights.Add("X", new ConcreteFlyweight());
        flyweights.Add("Y", new ConcreteFlyweight());
        flyweights.Add("Z", new ConcreteFlyweight());
    }
    public Flyweight GetFlyweight(string key)
    {
        return ((Flyweight)flyweights[key]);
    }
}
abstract class Flyweight
{
    public abstract void Operation(int extrinsicstate);
}

class ConcreteFlyweight : Flyweight
{
    public override void Operation(int extrinsicstate)
    {
        Console.WriteLine("具体Flyweight:" + extrinsicstate);
    }
}

class UnsharedConcreteFlyweight : Flyweight
{
    public override void Operation(int extrinsicstate)
    {
        Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
    }
}
class Program
{
    static void Main(string[] args)
    {
        int extrinsicstate = 22;

        FlyweightFactory f = new FlyweightFactory();

        Flyweight fx = f.GetFlyweight("X");
        fx.Operation(--extrinsicstate);

        Flyweight fy = f.GetFlyweight("Y");
        fy.Operation(--extrinsicstate);

        Flyweight fz = f.GetFlyweight("Z");
        fz.Operation(--extrinsicstate);

        UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();

        uf.Operation(--extrinsicstate);

        Console.Read();
    }
}

执行结果:
具体Flyweight:21
具体Flyweight:20
具体Flyweight:19
不共享的具体Flyweight:18

/*
 * 22.2 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象 */

//用户
public class User
{
    private string name;
    public User(string name) { this.name = name; }
    public string Name { get { return name; } }
}
//网站工厂
class WebSiteFactory
{
    private Hashtable flyweights = new Hashtable();

    //获得网站分类
    public WebSite GetWebSiteCategory(string key)
    {
        if (!flyweights.ContainsKey(key)) flyweights.Add(key, new ConcreteWebSite(key));
        return ((WebSite)flyweights[key]);
    }
    //获得网站分类总数
    public int GetWebSiteCount() { return flyweights.Count; }
}
//网站
abstract class WebSite
{
    public abstract void Use(User user);
}

//具体的网站
class ConcreteWebSite : WebSite
{
    private string name = "";
    public ConcreteWebSite(string name) { this.name = name; }
    public override void Use(User user)
    {
        Console.WriteLine("网站分类:" + name + " 用户:" + user.Name);
    }
}
class Program
{
    static void Main(string[] args)
    {
        WebSiteFactory f = new WebSiteFactory();

        WebSite fx = f.GetWebSiteCategory("产品展示");
        fx.Use(new User("小菜"));

        WebSite fy = f.GetWebSiteCategory("产品展示");
        fy.Use(new User("大鸟"));

        WebSite fz = f.GetWebSiteCategory("产品展示");
        fz.Use(new User("娇娇"));

        WebSite fl = f.GetWebSiteCategory("博客");
        fl.Use(new User("老顽童"));

        WebSite fm = f.GetWebSiteCategory("博客");
        fm.Use(new User("桃谷六仙"));

        WebSite fn = f.GetWebSiteCategory("博客");
        fn.Use(new User("南海鳄神"));

        Console.WriteLine("得到网站分类总数为 {0}", f.GetWebSiteCount());

        //string titleA = "大话设计模式";
        //string titleB = "大话设计模式";

        //Console.WriteLine(Object.ReferenceEquals(titleA, titleB));
        Console.Read();
    }
}

执行结果:
网站分类:产品展示 用户:小菜
网站分类:产品展示 用户:大鸟
网站分类:产品展示 用户:娇娇
网站分类:博客 用户:老顽童
网站分类:博客 用户:桃谷六仙
网站分类:博客 用户:南海鳄神
得到网站分类总数为 2

/*
 * 23.1 解释器模式(interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子 */
class Context
{
    private string input;
    public string Input { get { return input; } set { input = value; } }

    private string output;
    public string Output { get { return output; } set { output = value; } }
}
abstract class AbstractExpression
{
    public abstract void Interpret(Context context);
}
class TerminalExpression : AbstractExpression
{
    public override void Interpret(Context context)
    {
        Console.WriteLine("终端解释器");
    }
}
class NonterminalExpression : AbstractExpression
{
    public override void Interpret(Context context)
    {
        Console.WriteLine("非终端解释器");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Context context = new Context();
        IList<AbstractExpression> list = new List<AbstractExpression>();
        list.Add(new TerminalExpression());
        list.Add(new NonterminalExpression());
        list.Add(new TerminalExpression());
        list.Add(new TerminalExpression());

        foreach (AbstractExpression exp in list) exp.Interpret(context);
        Console.Read();
    }
}

执行结果:
终端解释器
非终端解释器
终端解释器
终端解释器

/*
 * 23.2 解释器模式(interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子 */
class PlayContext
{
    //演奏文本
    private string text;
    public string PlayText { get { return text; } set { text = value; } }
}
//表达式
abstract class Expression
{
    //解释器
    public void Interpret(PlayContext context)
    {
        if (context.PlayText.Length == 0) return;
        else
        {
            string playKey = context.PlayText.Substring(0, 1);
            context.PlayText = context.PlayText.Substring(2);
            double playValue = Convert.ToDouble(context.PlayText.Substring(0, context.PlayText.IndexOf(" ")));
            context.PlayText = context.PlayText.Substring(context.PlayText.IndexOf(" ") + 1);

            Excute(playKey, playValue);
        }
    }
    //执行
    public abstract void Excute(string key, double value);
}

//音符
class Note : Expression
{
    public override void Excute(string key, double value)
    {
        string note = "";
        switch (key)
        {
            case "C":
                note = "1";
                break;
            case "D":
                note = "2";
                break;
            case "E":
                note = "3";
                break;
            case "F":
                note = "4";
                break;
            case "G":
                note = "5";
                break;
            case "A":
                note = "6";
                break;
            case "B":
                note = "7";
                break;

        }
        Console.Write("{0} ", note);
    }
}

//音阶
class Scale : Expression
{
    public override void Excute(string key, double value)
    {
        string scale = "";
        switch (Convert.ToInt32(value))
        {
            case 1:
                scale = "低音";
                break;
            case 2:
                scale = "中音";
                break;
            case 3:
                scale = "高音";
                break;
        }
        Console.Write("{0} ", scale);
    }
}

//音速
class Speed : Expression
{
    public override void Excute(string key, double value)
    {
        string speed;
        if (value < 500) speed = "快速";
        else if (value >= 1000) speed = "慢速";
        else speed = "中速";

        Console.Write("{0} ", speed);
    }
}

class Program
{
    static void Main(string[] args)
    {
        PlayContext context = new PlayContext();
        //音乐-上海滩
        Console.WriteLine("上海滩:");
        //context.演奏文本 = "T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 D 0.5 E 0.5 G 3 D 0.5 E 0.5 O 1 A 3 A 0.5 O 2 C 0.5 D 1.5 E 0.5 D 0.5 O 1 B 0.5 A 0.5 O 2 C 0.5 O 1 G 3 P 0.5 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 D 0.5 E 0.5 G 3 D 0.5 E 0.5 O 1 A 3 A 0.5 O 2 C 0.5 D 1.5 E 0.5 D 0.5 O 1 B 0.5 A 0.5 G 0.5 O 2 C 3 P 0.5 O 3 C 0.5 C 0.5 O 2 A 0.5 O 3 C 2 P 0.5 O 2 A 0.5 O 3 C 0.5 O 2 A 0.5 G 2.5 G 0.5 E 0.5 A 1.5 G 0.5 C 1 D 0.25 C 0.25 D 0.5 E 2.5 E 0.5 E 0.5 D 0.5 E 2.5 O 3 C 0.5 C 0.5 O 2 B 0.5 A 3 E 0.5 E 0.5 D 1.5 E 0.5 O 3 C 0.5 O 2 B 0.5 A 0.5 E 0.5 G 2 P 0.5 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 D 0.5 E 0.5 G 3 D 0.5 E 0.5 O 1 A 3 A 0.5 O 2 C 0.5 D 1.5 E 0.5 D 0.5 O 1 B 0.5 A 0.5 G 0.5 O 2 C 3 ";
        context.PlayText = "T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ";
        //音乐-隐形的翅膀
        //Console.WriteLine("隐形的翅膀:"); 
        //context.演奏文本 = "T 1000 O 1 G 0.5 O 2 C 0.5 E 1.5 G 0.5 E 1 D 0.5 C 0.5 C 0.5 C 0.5 C 0.5 O 1 A 0.25 G 0.25 G 1 G 0.5 O 2 C 0.5 E 1.5 G 0.5 G 0.5 G 0.5 A 0.5 G 0.5 G 0.5 D 0.25 E 0.25 D 0.5 C 0.25 D 0.25 D 1 A 0.5 G 0.5 E 1.5 G 0.5 G 0.5 G 0.5 A 0.5 G 0.5 E 0.5 D 0.5 C 0.5 C 0.25 D 0.25 O 1 A 1 G 0.5 A 0.5 O 2 C 1.5 D 0.25 E 0.25 D 1 E 0.5 C 0.5 C 3 O 1 G 0.5 O 2 C 0.5 E 1.5 G 0.5 E 1 D 0.5 C 0.5 C 0.5 C 0.5 C 0.5 O 1 A 0.25 G 0.25 G 1 G 0.5 O 2 C 0.5 E 1.5 G 0.5 G 0.5 G 0.5 A 0.5 G 0.5 G 0.5 D 0.25 E 0.25 D 0.5 C 0.25 D 0.25 D 1 A 0.5 G 0.5 E 1.5 G 0.5 G 0.5 G 0.5 A 0.5 G 0.5 E 0.5 D 0.5 C 0.5 C 0.25 D 0.25 O 1 A 1 G 0.5 A 0.5 O 2 C 1.5 D 0.25 E 0.25 D 1 E 0.5 C 0.5 C 3 E 0.5 G 0.5 O 3 C 1.5 O 2 B 0.25 O 3 C 0.25 O 2 B 1 A 0.5 G 0.5 A 0.5 O 3 C 0.5 O 2 E 0.5 D 0.5 C 1 C 0.5 C 0.5 C 0.5 O 3 C 1 O 2 G 0.25 A 0.25 G 0.5 D 0.25 E 0.25 D 0.5 C 0.25 D 0.25 D 3 E 0.5 G 0.5 O 3 C 1.5 O 2 B 0.25 O 3 C 0.25 O 2 B 1 A 0.5 G 0.5 A 0.5 O 3 C 0.5 O 2 E 0.5 D 0.5 C 1 C 0.5 C 0.5 C 0.5 O 3 C 1 O 2 G 0.25 A 0.25 G 0.5 D 0.25 E 0.25 D 0.5 C 0.5 C 3 ";
        Expression expression = null;
        try
        {
            while (context.PlayText.Length > 0)
            {
                string str = context.PlayText.Substring(0, 1);
                switch (str)
                {
                    case "O":
                        expression = new Scale();
                        break;
                    case "T":
                        expression = new Speed();
                        break;
                    case "C":
                    case "D":
                    case "E":
                    case "F":
                    case "G":
                    case "A":
                    case "B":
                    case "P":
                        expression = new Note();
                        break;

                }
                expression.Interpret(context);

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

        Console.Read();
    }
}

执行结果:
上海滩:
中速 中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2

/*
 * 24.1 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作 */
abstract class Visitor
{
    public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
    public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
}
class ConcreteVisitor1 : Visitor
{
    public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
    {
        Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
    }
    public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
    {
        Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
    }
}

class ConcreteVisitor2 : Visitor
{
    public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
    {
        Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
    }
    public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
    {
        Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
    }
}

abstract class Element
{
    public abstract void Accept(Visitor visitor);
}

class ConcreteElementA : Element
{
    public override void Accept(Visitor visitor)
    {
        visitor.VisitConcreteElementA(this);
    }
    public void OperationA() { }
}

class ConcreteElementB : Element
{
    public override void Accept(Visitor visitor)
    {
        visitor.VisitConcreteElementB(this);
    }
    public void OperationB() { }
}

class ObjectStructure
{
    private IList<Element> elements = new List<Element>();
    public void Attach(Element element)
    {
        elements.Add(element);
    }
    public void Detach(Element element)
    {
        elements.Remove(element);
    }
    public void Accept(Visitor visitor)
    {
        foreach (Element e in elements) e.Accept(visitor);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ObjectStructure o = new ObjectStructure();
        o.Attach(new ConcreteElementA());
        o.Attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        o.Accept(v1);
        o.Accept(v2);

        Console.Read();
    }
}

执行结果:
ConcreteElementA被ConcreteVisitor1访问
ConcreteElementB被ConcreteVisitor1访问
ConcreteElementA被ConcreteVisitor2访问
ConcreteElementB被ConcreteVisitor2访问

/*
 * 24.2 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作 */

//状态
abstract class Action
{
    //得到男人结论或反应
    public abstract void GetManConclusion(Man concreteElementA);
    //得到女人结论或反应
    public abstract void GetWomanConclusion(Woman concreteElementB);
}


//成功
class Success : Action
{
    public override void GetManConclusion(Man concreteElementA)
    {
        Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人。", concreteElementA.GetType().Name, this.GetType().Name);
    }

    public override void GetWomanConclusion(Woman concreteElementB)
    {
        Console.WriteLine("{0}{1}时,背后大多有一个不成功的男人。", concreteElementB.GetType().Name, this.GetType().Name);
    }
}
//失败
class Failing : Action
{
    public override void GetManConclusion(Man concreteElementA)
    {
        Console.WriteLine("{0}{1}时,闷头喝酒,谁也不用劝。", concreteElementA.GetType().Name, this.GetType().Name);
    }

    public override void GetWomanConclusion(Woman concreteElementB)
    {
        Console.WriteLine("{0}{1}时,眼泪汪汪,谁也劝不了。", concreteElementB.GetType().Name, this.GetType().Name);
    }
}
//恋爱
class Amativeness : Action
{
    public override void GetManConclusion(Man concreteElementA)
    {
        Console.WriteLine("{0}{1}时,凡事不懂也要装懂。", concreteElementA.GetType().Name, this.GetType().Name);
    }

    public override void GetWomanConclusion(Woman concreteElementB)
    {
        Console.WriteLine("{0}{1}时,遇事懂也装作不懂", concreteElementB.GetType().Name, this.GetType().Name);
    }
}
//结婚
class Marriage : Action
{
    public override void GetManConclusion(Man concreteElementA)
    {
        Console.WriteLine("{0}{1}时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。", concreteElementA.GetType().Name, this.GetType().Name);
    }

    public override void GetWomanConclusion(Woman concreteElementB)
    {
        Console.WriteLine("{0}{1}时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。", concreteElementB.GetType().Name, this.GetType().Name);
    }
}

//
abstract class Person
{
    //接受
    public abstract void Accept(Action visitor);
}

//男人
class Man : Person
{
    public override void Accept(Action visitor)
    {
        visitor.GetManConclusion(this);
    }
}
//女人
class Woman : Person
{
    public override void Accept(Action visitor)
    {
        visitor.GetWomanConclusion(this);
    }
}
//对象结构
class ObjectStructure
{
    private IList<Person> elements = new List<Person>();

    //增加
    public void Attach(Person element)
    {
        elements.Add(element);
    }
    //移除
    public void Detach(Person element)
    {
        elements.Remove(element);
    }
    //查看显示
    public void Display(Action visitor)
    {
        foreach (Person e in elements)
        {
            e.Accept(visitor);
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        ObjectStructure o = new ObjectStructure();
        o.Attach(new Man());
        o.Attach(new Woman());

        Success v1 = new Success();
        o.Display(v1);

        Failing v2 = new Failing();
        o.Display(v2);

        Amativeness v3 = new Amativeness();
        o.Display(v3);

        Marriage v4 = new Marriage();
        o.Display(v4);

        Console.Read();
    }
}

执行结果:
ManSuccess时,背后多半有一个伟大的女人。
WomanSuccess时,背后大多有一个不成功的男人。
ManFailing时,闷头喝酒,谁也不用劝。
WomanFailing时,眼泪汪汪,谁也劝不了。
ManAmativeness时,凡事不懂也要装懂。
WomanAmativeness时,遇事懂也装作不懂
ManMarriage时,感慨道:恋爱游戏终结时,‘有妻徒刑’遥无期。
WomanMarriage时,欣慰曰:爱情长跑路漫漫,婚姻保险保平安。

 

转载于:https://www.cnblogs.com/Ceri/p/7859211.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值