第一章 简单工厂模式
简单工厂:对象实例化的工具类;
工厂模式:工厂接口(一个实例化方法),若干子类通过实现父类实例化方法,实例化相应类别的对象;
抽象工厂模式:工厂接口(多个实例化方法,适用于被实例化的对象有多个类别约束),若干子类通过实现父类实例化方法(多个方法),实例化相应类别的对象;
+public -private #protected
接口表示:<> 和棒棒糖法
继承:实线+空心三角 △
实现:虚线+空心三角 ------------△
关联:实线+箭头 >
依赖:虚线+箭头 ------------>
聚合:菱形+实线+箭头 ◇>
合成:实心菱形+实线+箭头 ◆>
第二章 策略模式
定义了算法家族,分别封装起来,让他们之间可以互相转换,此模式让算法的变化,不会影响到使用算法的客户。
//抽象算法类 public abstract class CashSuper { public abstract double GetResult(double money); } //具体算法类:正常 public class CashNormal: CashSuper { public CashNormal() { } public override double GetResult(double money) { Console.WriteLine("算法A实现"); return money; } } //具体算法类:打折 public class CashRebate : CashSuper { public CashRebate(double discount) { Discount = discount; } public double Discount { get; set; } public override double GetResult(double money) { Console.WriteLine("算法B实现"); return money * Discount; } } //具体算法类:返现 public class CashReturn : CashSuper { public double Interval { get; set; } public double Rebate{ get; set; } public CashReturn(double interval, double rebate) { Interval = interval; Rebate = rebate; } public override double GetResult(double money) { Console.WriteLine("算法C实现"); double result = (money%Interval)*Rebate; return result; } }
感觉策略模式和工厂模式挺像,都是一个接口,若干子类,子类执行一个方法;但是用处不同,工厂模式是实例化对象用的,策略模式是实现相应算法用的;
第三章 单一职责原则
就一个类而言,应该仅有一个引起他变化的原因;
第四章 开放——封闭原则
软件实体(类,模块,函数)。应该可以扩展(开放),但是不可修改(封闭)。
面对需求,对程序的改动是通过增加行的代码,而不是修改现有的代码;
第五章 依赖倒转原则
高层模块不应该依赖低层模块,两个都应该依赖抽象;
抽象不应该依赖细节,细节应该依赖抽象;
举例:业务模块(高层),数据库模块(底层);不能因为数据库从mysql换成sql server,而对原有业务模块而大改特改。
里氏代换原则:子类必须能替换掉他们的父类型;
只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能被真正复用,而子类也能够在父类基础上增加新的行为。65
第六章 装饰模式
动态的给对象添加一些额外职责,就增加功能来说,装饰模式比生成子类更加灵活。
//人 public class Person { public Person() { } public string? Name { get; set; } public Person(string name) { Name = name; } public virtual void Show() { Console.WriteLine("装扮的{0}", Name); } } //服饰 public class Finery : Person { protected Person? componet { get; set; } public void Decorate(Person componet) { this.componet = componet; } public override void Show() { if(componet != null) { componet.Show(); } } } //具体服饰:T型衫 class TShirts : Finery { public override void Show() { Console.WriteLine("T型衫"); base.Show(); } } //具体服饰:大垮裤 class BigTrouser : Finery { public override void Show() { Console.WriteLine("大垮裤"); base.Show(); } } //装扮代码 Person person = new Person("小菜"); Console.WriteLine("第一种装扮:"); TShirts ts= new TShirts(); BigTrouser bt = new BigTrouser(); ts.Decorate(person); bt.Decorate(ts); bt.Show(); Console.WriteLine("第二种装扮:"); bt.Decorate(person); ts.Decorate(bt); ts.Show();
想法:有点像俄罗斯套娃,更有点像穿衣服,只有第一次塞进去的是个人,后边都是塞进去的一个穿了一堆衣服的人;
最后执行show的时候,按装饰顺序执行各个装饰了类的show方法;
使用此模式的时机:向旧的类中添加新代码,新代码通常装饰或者说扩展了旧代码的核心行为;而这些新代码,可以使用某一个功能,也可以全部都,有点像穿衣服,穿一件或者全副武装;
另外注意:装饰模式的顺序很重要,关系到内裤内穿还是外穿;
比如文本过滤和加密,先加密,后过滤,这个顺序是有问题的。应该,先过滤,再加密;
第七章 代理模式
为其他对象提供一种代理,以控制对这个对象的访问;
远程代理:通过代理感觉是在本地访问一样;
虚拟代理:通过代理感觉好像是真实加载出来的一样,其实因为害怕加载太费时间,早已经加载好了,等你用呢。
安全代理:控制对象访问权限,通过代理没有权限访问的东西压根就不会出现。
智能指引:调用真实对象时,代理处理另外一些事情。需要代理,代理才会机智的出现。
//代理接口 public interface GiveGift { void GiveDolls(); } //被访问对象 class Pursuit: GiveGift { SchoolGirl mm; public Pursuit(SchoolGirl mm) { this.mm = mm; } public void GiveDolls() { Console.WriteLine("{0},送你洋娃娃",mm.name); } } class SchoolGirl { public string name { get; set; } } class Proxy : GiveGift { public Proxy(SchoolGirl mm) { gg = new Pursuit(mm); } Pursuit? gg { get; set; } public void GiveDolls() { gg.GiveDolls(); } } //使用代理模式 SchoolGirl mm = new SchoolGirl(); mm.name = "阿娇"; Proxy proxy=new Proxy(mm); proxy.GiveDolls();
第八章 工厂方法 91
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类;
//雷锋 public class LeiFeng { public void DoWell() { Console.WriteLine("做好事..."); } } //大学毕业生:学雷锋 public class Undergraduate : LeiFeng { } //社区工作者:学雷锋 public class Volunteer : LeiFeng { } //雷锋工厂接口 public interface IFactory { LeiFeng CreateLeiFeng(); } //雷锋工厂:毕业生 public class UndergraduateFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Undergraduate(); } } //雷锋工厂:社区工作者 public class VolunteerFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Volunteer(); } } //如果想创建新雷锋。就创建新的雷锋子类和新的雷锋工厂;
第九章 原型模式 102
原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
public class Resume : ICloneable { public string? Name { get; set; } public string? Sex { get; set; } public string? Age { get; set; } public string? School { get; set; } public string? Company { get; set; } public Resume(string? name, string? sex, string? age, string? school, string? company) { Name = name; Sex = sex; Age = age; School = school; Company = company; } public void Display() { Console.WriteLine("个人信息:{0},{1},{2}",Name,Sex,Age); Console.WriteLine("经历:{0},{1}", School, Company); } public object Clone() { return(Object)this.MemberwiseClone(); } } //使用原型模式 Resume a = new Resume("大鹏", "男", "22", "铁道学院", "新展信科技"); Resume b = (Resume)a.Clone(); b.Name = "李文"; b.Sex = "女"; a.Display(); b.Display();
MemberviseClone方法是浅复制,不能能复制引用类型字段;
关于深复制方法有多重实现方式,以后探讨;
第十章 模板方法模式
定义一个操作中的算法的骨架,将一些步骤延迟到子类。模板方法使得子类可以改变一个算法的结构,即可以重新定义该算法的某些特定步骤。
public class TestPaper { public string _Answer1 { get; set; } public string _Answer2 { get; set; } public string _Answer3 { get; set; } public void question1() { Console.WriteLine("1.一个选择题,或者一个算法"); Console.WriteLine("1.答案:{0}", _Answer1); } public void question2() { Console.WriteLine("2.一个选择题,或者一个算法"); Console.WriteLine("2.答案:{0}", _Answer2); } public void question3() { Console.WriteLine("3.一个选择题,或者一个算法"); Console.WriteLine("3.答案:{0}", _Answer3); } public virtual void Answer1(string answer) { _Answer1=answer; } public virtual void Answer2(string answer) { _Answer2 = answer; } public virtual void Answer3(string answer) { _Answer3 = answer; } } public class TestPaperA: TestPaper { public string name { get; set; } public TestPaperA(string name) { this.name = name; Console.WriteLine("【{0}】同学开始答题",name); } public override void Answer1(string answer) { Console.WriteLine("思考一下"); base.Answer1(answer); } public override void Answer2(string answer) { Console.WriteLine("思考一下"); base.Answer2(answer); } public override void Answer3(string answer) { Console.WriteLine("思考一下"); base.Answer3(answer); } } //使用 TestPaper test = new TestPaperA("张三"); test.Answer1("a"); test.question1(); test.Answer2("aa"); test.question2(); test.Answer3("aaa"); test.question3();
第十一章 迪米特法则
如果两个类不必彼此直接通信,那么这两个类就不应答发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法,可以通过第三者转发这个调用;
第十二章 外观模式
为系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口是的这一子系统更加容易使用;
适用时机:通过外观类,给乱七八糟的子系统接口,提供一些统一的对外接口,对接口需求者不需要了解的执行或数据,只需要在外观类内部执行完毕即可;
//子系统1234 public class SubSystemOne { public void MethodOne() { Console.WriteLine("子系统一:方法1"); } } public class SubSystemTwo { public void MethodTwo() { Console.WriteLine("子系统二:方法2"); } } public class SubSystemThree { public void MethodThree() { Console.WriteLine("子系统三:方法3"); } } public class SubSystemFour { public void MethodFour() { Console.WriteLine("子系统四:方法4"); } } //外观类 public class Facade { public SubSystemOne? one { get; set; } public SubSystemTwo? two { get; set; } public SubSystemThree? three { get; set; } public SubSystemFour? four { get; set; } public Facade() { this.one = new SubSystemOne(); this.two = new SubSystemTwo(); this.three = new SubSystemThree(); this.four = new SubSystemFour(); } public void MethodA() { Console.WriteLine("方法组A:----"); one.MethodOne(); two.MethodTwo(); three.MethodThree(); } public void MethodB() { Console.WriteLine("方法组B:---"); one.MethodOne(); two.MethodTwo(); four.MethodFour(); } } //使用 Facade facade = new Facade(); facade.MethodA(); facade.MethodB();
第十三章 建造者模式
将一个复杂对象的构建和他的表示分离,使得同样的构建过程可以构建不同的表示。
//抽象建造者 abstract class PersonBuilder { protected Graphics g; protected Pen p; public PersonBuilder(Graphics g, Pen p) { this.g = g; this.p = p; } public abstract void buildHead(); public abstract void buildBody(); public abstract void buildArmLeft(); public abstract void buildArmRight(); public abstract void buildLegLeft(); public abstract void buildLegRight(); } //具体建造者,瘦人 class PersonThinBuilder : PersonBuilder { public PersonThinBuilder(Graphics g, Pen p) : base(g, p) { } public override void buildArmLeft() { g.DrawLine(p,60,50,40,100); } public override void buildArmRight() { g.DrawLine(p, 70,50,90,100); } public override void buildBody() { g.DrawRectangle(p, 60, 50, 10, 50); } public override void buildHead() { g.DrawEllipse(p,50,20,30,30); } public override void buildLegLeft() { g.DrawLine(p,60,100,45,150); } public override void buildLegRight() { g.DrawLine(p, 70,100,85,150); } } //指挥者:也叫组装者 class PersonDirector { private PersonBuilder pb; public PersonDirector(PersonBuilder pb) { this.pb = pb; } public void CreatePerson() { pb.buildHead(); pb.buildBody(); pb.buildArmLeft(); pb.buildArmRight(); pb.buildLegLeft(); pb.buildLegRight(); } } // Pen p = new Pen(Color.Yellow); PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(),p); PersonDirector pdthin = new PersonDirector(ptb); pdthin.CreatePerson();
第十四章 观察者模式 149
又叫发布订阅模式;
定义了一对多的依赖关系,让多个观察者对象同时监听某个主题对象。在主题对象状态发生变化时,会通知相应的所有观察者,是他们能够自动更新自己
//通知者接口 public interface Subject { void Attach(Observer observer); void Detach(Observer observer); void Notify(); public string? SubjectState { get; set; } } //具体通知者 class Boss : Subject { //同事列表 public IList<Observer> observers=new List<Observer>(); public string? action { get; set; } public string? SubjectState { get; set; } //增加 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 { //同事列表 public IList<Observer> observers = new List<Observer>(); public string? action { get; set; } public string? SubjectState { get; set; } //增加 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(); } } } //抽象观察者 public abstract class Observer { public string name { get; set; } public Subject sub { get; set; } 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); } } class NBAObserver : Observer { public NBAObserver(string name, Secretary sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0},{1},关闭NBA球赛,继续工作!", sub.SubjectState, name); } } ///测试代码 Boss boss = new Boss(); boss.Attach(new StockObserver("x", boss)); boss.Attach(new StockObserver("y", boss)); boss.Attach(new StockObserver("z", boss)); boss.SubjectState = "老板来了,"; boss.Notify();
事件委托实现
观察者和通知者互相不知道,由客户端决定通知谁。去掉了抽象观察类。
delegate void EventHandler(); //通知者接口 public interface Subject { void Notify(); public string? SubjectState { get; set; } } //具体通知者 class Boss : Subject { public event EventHandler Update; public string? SubjectState { get; set; } public string? action { get; set; } //通知 public void Notify() { Update(); } } class Secretary : Subject { //同事列表 public event EventHandler Update; public string? SubjectState { get; set; } public string? action { get; set; } //通知 public void Notify() { Update(); } } //具体观察者 class StockObserver { public string name { get; set; } public Subject sub { get; set; } public StockObserver(string name, Subject sub) { this.name = name; this.sub=sub; } public void CloseStock() { Console.WriteLine("{0},{1},关闭股票继续工作!",sub.SubjectState,name); } } class NBAObserver { public string name { get; set; } public Subject sub { get; set; } public NBAObserver(string name, Subject sub) { this.name = name; this.sub = sub; } public void CloseNBA() { Console.WriteLine("{0},{1},关闭NBA球赛,继续工作!", sub.SubjectState, name); } } 、、、测试代码 Boss boss = new Boss(); StockObserver so1 = new StockObserver("李四", boss); NBAObserver so2 = new NBAObserver("张三", boss); boss.Update += new EventHandler(so1.CloseStock); boss.Update += new EventHandler(so2.CloseNBA); boss.SubjectState = "我回来了"; boss.Notify();
23种设计模式【C#代码举例】(下):https://developer.aliyun.com/article/1556292