第1章 代碼無錯就是優? [簡單工廠模式] (已看)算法
第2章 商場促銷 [策略模式] (已看)編程
第3章 拍攝UFO [單一職責原則] (已看)ide
第4章 考研求職兩不誤 [開放-封閉原則] (已看)函數
第5章 會修電腦不會修收音機? [依賴倒轉原則] (已看)ui
第6章 穿什麼有這麼重要? [裝飾模式] (已看)this
第7章 爲別人作嫁衣 [代理模式] (已看)spa
第8章 雷鋒依然在人間 [工廠方法模式] (已看)翻譯
第10章 考題抄錯會作也白搭 [模板方法模式] (已看)代理
第11章 無熟人難辦事? [迪米特法則] (已看)
第12章 牛市股票還會虧錢? [外觀模式] (已看)
第13章 好菜每回味不一樣 [建造者模式] (已看)
第14章 老闆回來,我不知道 [觀察者模式] (已看)
第15章 就不能不換DB模式 [抽象工廠模式] (已看)
第16章 無盡加班什麼時候休 [狀態模式] (已看)
第17章 在NBA我須要翻譯 [適配器模式] (已看)
第18章 若是再回到從前 [備忘錄模式] (已看)
第19章 分公司=一部門 [組合模式] (已看)
第20章 想走?能夠!先買票 [迭代器模式] (已看)
第21章 有些類也須要計劃生育 [單例模式] (已看)
第22章 手機軟件什麼時候統一 [橋接模式] (已看)
第23章 烤羊肉串引來的思考 [命令模式] (已看)
第24章 加薪非要老總批? [職責鏈模式] (已看)
第25章 世界須要和平 [中介者模式] (已看)
第26章 項目多也別傻作 [享元模式] (已看)
第27章 其實你不懂老闆的心 [解釋器模式] (已看)
第28章 男人和女人 [訪問者模式] (已看)
第29章 OOTV杯超級模式大賽 [模式總結] (已看)
第1章 代碼無錯就是優? [簡單工廠模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { Operation opAdd = OperationFactory.CreateOperate("+"); opAdd.NumberA = 1; opAdd.NumberB = 2; Console.WriteLine(opAdd.GetResult()); Operation opSub = OperationFactory.CreateOperate("-"); opSub.NumberA = 1; opSub.NumberB = 2; Console.WriteLine(opSub.GetResult()); } } public abstract class Operation { private double numberA = 0; private double numberB = 0; public double NumberA { get { return numberA; } set { numberA = value; } } public double NumberB { get { return numberB; } set { numberB = value; } } public virtual double GetResult() { double result = 0; return result; } } public class OperationAdd : Operation { public override double GetResult() { return NumberA + NumberB; } } public class OperationSub : Operation { public override double GetResult() { return NumberA - NumberB; } } public class OperationFactory { public static Operation CreateOperate(string operate) { Operation oper = null; switch (operate) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; } return oper; } } }
聚合表示一種弱的'擁有'關係,體現的是A對象能夠包含B對象,但B對象不是A對象的一部分
合成(Composition,也有翻譯成'組合'的)是一種強的'擁有'關係,體現了嚴格的部分和總體的關係,部分和總體的生命週期同樣
第2章 商場促銷 [策略模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { int condition = 2; CashContext cashContext = null; switch (condition) { case 1: cashContext = new CashContext(new CashNormal()); break; case 2: cashContext = new CashContext(new CashDiscount(0.8)); break; } Console.WriteLine(cashContext.getResult(100)); } } public class CashContext { private CashSuper cashSuper = null; public CashContext(CashSuper cashSuper) { this.cashSuper = cashSuper; } public double getResult(double money) { return cashSuper.acceptCash(money); } } public abstract class CashSuper { public abstract double acceptCash(double money); } public class CashNormal : CashSuper { public override double acceptCash(double money) { return money; } } public class CashDiscount : CashSuper { private double discount; public CashDiscount(double discount) { this.discount = discount; } public override double acceptCash(double money) { return money * discount; } } }
[策略模式(Strategy)它定義了算法家族,分別封裝起來,讓它們之間能夠互相替換,此模式讓算法的變化,不會影響到使用算法的客戶]
面向對象的編程,並非類越多越好,類的劃分是爲了封裝,但分類的基礎是抽象,具備相同屬性和功能的對象的抽象集合纔是類.
第3章 拍攝UFO [單一職責原則]
[單一職責原則(SRP)]就一個類而言,應該僅有一個引發它變化的緣由.
若是一個類承擔的職責過多,就等於把這些職責耦合在一塊兒,一個職責的變化可能會削弱或者抑制這個類完成其餘職責的能力.
這種耦合會致使脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞
軟件設計真正要作的許多內容,就是發現職責並把那些職責相互分離.
若是你可以想到多於一個動機去改變一個類,那麼這個類就具備多於一個的職責
第4章 考研求職兩不誤 [開放-封閉原則]
[開放-封閉原則]是說軟件實體(類,模塊,函數等等)應該能夠擴展,可是不可修改
不管模塊是多麼的'封閉',都會存在一些沒法對之封閉的變化.既然不可能徹底封閉,設計人員必須對於他設計的模塊應該對哪一種變化封閉作出選擇。
他必須先猜想出最有可能發生的變化種類,而後構造抽象來隔離那些變化.
等到變化發生時當即採起行動
在咱們最初編寫代碼時,假設變化不會發生.當變化發生時,咱們就建立抽象來隔離之後發生的同類變化
面對需求,對程序的改動是經過增長新代碼進行的,而不是更改現有的代碼
咱們但願的是在開發工做展開不久就知道可能發生的變化.查明可能發生的變化所等待的時間越長,要建立正確的抽象就越困難
開放-封閉原則是面向對象設計的核心所在.遵循這個原則能夠帶來面向對象技術所聲稱的巨大好處,也就是可維護,可擴展,可複用,靈活性好.
開發人員應該僅對程序中呈現出頻繁變化的那些部分作出抽象,然而,對於應用程序中的每一個部分都刻意地進行抽象一樣不是一個好主意》
拒毫不成熟的抽象和抽象自己同樣重要
第5章 會修電腦不會修收音機? [依賴倒轉原則]
[依賴倒置原則]A.高層模塊不該該依賴低層模塊.兩個都應該依賴抽象.B.抽象不該該依賴細節.細節應該依賴抽象.
針對接口編程,不要對實現編程.
[里氏代換原則]子類型必須可以替換掉它們的父類型
一個軟件實體若是使用的是一個父類的話,那麼必定適用於其子類,並且它察覺不出父類對象和子類對象的區別.
也就是說,在軟件裏面,把父類都替換成它的子類,程序的行爲沒有變化
只有當子類能夠替換掉父類,軟件單位的功能不受到影響時,父類才能真正被複用,而子類也可以在父類的基礎上增長新的行爲
因爲子類型的可替換性才使得使用父類類型的模塊在無需修改的狀況下就能夠擴展
依賴倒轉其實能夠說是面向對象設計的標誌,用哪一種語言來編寫程序不重要,若是編寫時考慮的都是如何針對抽象編程而不是針對細節編程,
即程序中全部的依賴關係都是終止於抽象類或者接口,那就是面向對象的設計,反之那就是過程化的設計了.
第6章 穿什麼有這麼重要? [裝飾模式]
using System; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); } } public abstract class Component { public abstract void Operation(); } public class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("具體對象的操做"); } } public abstract class Decorator : Component { public Component component; public void SetComponent(Component component) { this.component = component; } public override void Operation() { if (component != null) { component.Operation(); } } } public class ConcreteDecoratorA : Decorator { private string addedState; public override void Operation() { base.Operation(); addedState = "New State"; Console.WriteLine("具體裝飾對象A的操做"); } } public class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); AddedBehavior(); Console.WriteLine("具體裝飾對象B的操做"); } private void AddedBehavior() { } } }
[裝飾模式(Decorator)]動態地給一個對象添加一些額外的職責,就增長功能來講,裝飾模式比生成子類更爲靈活
第7章 爲別人作嫁衣 [代理模式]
using System; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { Proxy proxy = new Proxy(); proxy.Request(); } } public abstract class Subject { public abstract void Request(); } public class RealSubject : Subject { public override void Request() { Console.WriteLine("真實的請求"); } } public class Proxy : Subject { private RealSubject realSubject; public override void Request() { if (realSubject == null) { realSubject = new RealSubject(); } realSubject.Request(); } } }
[代理模式(Proxy)]爲其餘對象提供一種代理以控制對這個對象的訪問
第8章 雷鋒依然在人間 [工廠方法模式]
using System; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { IFactory factory = new AddFactory(); Operation operation = factory.CreateOperation(); operation.NumberA = 1; operation.NumberB = 2; Console.WriteLine(operation.GetResult()); } } public abstract class Operation { private double numberA = 0; private double numberB = 0; public double NumberA { get { return numberA; } set { numberA = value; } } public double NumberB { get { return numberB; } set { numberB = value; } } public virtual double GetResult() { double result = 0; return result; } } public class OperationAdd : Operation { public override double GetResult() { return NumberA + NumberB; } } public class OperationSub : Operation { public override double GetResult() { return NumberA - NumberB; } } public interface IFactory { Operation CreateOperation(); } public class AddFactory : IFactory { public Operation CreateOperation() { return new OperationAdd(); } } public class SubFactory : IFactory { public Operation CreateOperation() { return new OperationSub(); } } }
[工廠方法模式(Factory Method)]定義一個用於建立對象的接口,讓子類決定實例化哪個類.工廠方法使一個類的實例化延遲到其子類.
第9章 簡歷複印 [原型模式]
using System; using System.Net.Security; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { ConcretePrototype1 p1 = new ConcretePrototype1("I"); ConcretePrototype1 c1 = (ConcretePrototype1) p1.Clone(); Console.WriteLine("Cloned: {0}",c1.Id); } } public abstract class Prototype { private string id; public Prototype(string id) { this.id = id; } public string Id { get { return id; } } public abstract Prototype Clone(); } public class ConcretePrototype1 : Prototype { public ConcretePrototype1(string id) : base(id) { } public override Prototype Clone() { return (Prototype)this.MemberwiseClone(); } } public class ConcretePrototype2 : Prototype { public ConcretePrototype2(string id) : base(id) { } public override Prototype Clone() { return (Prototype)this.MemberwiseClone(); } } }
[原型模式(Prototype)]用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象
第10章 考題抄錯會作也白搭 [模板方法模式]
using System; using System.Diagnostics.CodeAnalysis; namespace Test2 { class Program { static void Main(string[] args) { AbstractClass c; c = new ConcreteClassA(); c.TemplateMethod(); c = new ConcreteClassB(); c.TemplateMethod(); } } public abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine(""); } } public class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具體類A方法1的實現"); } public override void PrimitiveOperation2() { Console.WriteLine("具體類A方法2的實現"); } } public class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具體類B方法1的實現"); } public override void PrimitiveOperation2() { Console.WriteLine("具體類B方法2的實現"); } } }
[模板方法模式]定義一個操做中的算法的骨架,而將一些步驟延遲到子類中.模板方法使得子類能夠不改變一個算法的結構既可重定義該算法的某些特定步驟.
第11章 無熟人難辦事? [迪米特法則]
[迪米特法則(LoD)]若是兩個類沒必要彼此直接通訊,那麼這兩個類就不該當發生直接的做用.若是其中一個類須要調用另外一個類的某一個方法的話,能夠經過第三者轉發這個調用.
在類的結構設計上,每個類都應當儘可能下降成員的訪問權限.
迪米特法則其根本思想,是強調了類之間的鬆耦合.
類之間的耦合越弱,越有利於複用,一個處在弱耦合的類被修改,不會對有關係的類形成波及.
第12章 牛市股票還會虧錢? [外觀模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { Facade facade = new Facade(); facade.MethodA(); facade.MethodB(); } } public class SubSystemOne { public void MethodOne() { Console.WriteLine("子系統方法一"); } } public class SubSystemTwo { public void MethodTwo() { Console.WriteLine("子系統方法二"); } } public class SubSystemThree { public void MethodThree() { Console.WriteLine("子系統方法三"); } } public class SubSystemFour { public void MethodFour() { Console.WriteLine("子系統方法四"); } } public class Facade { private SubSystemOne one; private SubSystemTwo two; private SubSystemThree three; private 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(); } } }
[外觀模式(Facade)]爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用
首先,在設計初期階段,應該要有意識的將不一樣的兩個層分離.
其次,在開發階段,子系統每每由於不斷的重構演化而變得愈來愈複雜,增長外觀Facade能夠提供一個簡單的接口,減小它們之間的依賴.
第三,在維護一個遺留的大型系統時,可能這個系統已經很是難以維護和擴展了,爲新系統開發一個外觀Facade類,來提供設計粗糙或高度複雜的遺留代碼的比較清晰簡單的接口,
讓新系統與Facade對象交互,Facade與遺留代碼交互全部複雜的工做.
第13章 好菜每回味不一樣 [建造者模式]
using System; using System.Collections.Generic; namespace Test2 { 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(); p1.Show(); director.Construct(b2); Product p2 = b2.GetResult(); p2.Show(); } } public class Product { private 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); } } } public abstract class Builder { public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product GetResult(); } public class ConcreteBuilder1 : Builder { private Product product = new Product(); public override void BuildPartA() { product.Add("部件A"); } public override void BuildPartB() { product.Add("部件B"); } public override Product GetResult() { return product; } } public class ConcreteBuilder2 : Builder { private Product product = new Product(); public override void BuildPartA() { product.Add("部件X"); } public override void BuildPartB() { product.Add("部件Y"); } public override Product GetResult() { return product; } } public class Director { public void Construct(Builder builder) { builder.BuildPartA(); builder.BuildPartB(); } } }
[建造者模式(Builder)]將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示
第14章 老闆回來,我不知道 [觀察者模式]
using System; using System.Collections.Generic; namespace Test2 { 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 = "123"; s.Notify(); s.SubjectState = "ABC"; s.Notify(); } } public 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(); } } } public class ConcreteSubject : Subject { private string subjectState; public string SubjectState { get { return subjectState;} set { subjectState = value; } } } public abstract class Observer { public abstract void Update(); } public 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 subject; } set { subject = value; } } } }
[觀察者模式]定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象.這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身
將一個系統分割成一系列相互協做的類有一個很很差的反作用,那就是須要維護相關對象間的一致性.咱們不但願爲了維持一致性而使各種緊密耦合,這樣會給維護,擴展和重用都帶來不便
觀察者模式所作的工做其實就是在解除耦合.讓耦合的雙方都依賴於抽象,而不是依賴於具體.從而使得各自的變化都不會影響另外一邊的變化.
第15章 就不能不換DB模式 [抽象工廠模式]
using System; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { User user = new User(); Department department = new Department(); IFactory factory = new AccessFactory(); IUser iuser = factory.CreateUser(); iuser.Insert(user); iuser.GetUser(1); IDepartment idepartment = factory.CreateDepartment(); idepartment.Insert(department); idepartment.GetDepartment(1); } } public class User { public int ID { get; set; } } public class Department { public int ID { get; set; } } public interface IUser { void Insert(User user); User GetUser(int id); } public 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; } } public class AccessUser : IUser { public void Insert(User user) { Console.WriteLine("在Acces中給User表增長一條記錄"); } public User GetUser(int id) { Console.WriteLine("在Access中根據ID獲得User表的一條記錄"); return null; } } public interface IDepartment { void Insert(Department department); Department GetDepartment(int id); } public 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; } } public class AccessDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在Acces中給Department表增長一條記錄"); } public Department GetDepartment(int id) { Console.WriteLine("在Access中根據ID獲得Department表的一條記錄"); return null; } } public interface IFactory { IUser CreateUser(); IDepartment CreateDepartment(); } public class SqlServerFactory : IFactory { public IUser CreateUser() { return new SqlServerUser(); } public IDepartment CreateDepartment() { return new SqlServerDepartment(); } } public class AccessFactory : IFactory { public IUser CreateUser() { return new AccessUser(); } public IDepartment CreateDepartment() { return new AccessDepartment(); } } }
[抽象工廠模式(Abstract Factory)]提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類
第16章 無盡加班什麼時候休 [狀態模式]
using System; using System.Collections.Generic; namespace Test2 { class Program { static void Main(string[] args) { Work work = new Work(); work.Hour = 9; work.WriteProgram(); work.Hour = 10; work.WriteProgram(); work.Hour = 12; work.WriteProgram(); work.Hour = 13; work.WriteProgram(); work.Hour = 14; work.WriteProgram(); work.Hour = 17; work.TaskFinished = false; work.WriteProgram(); work.Hour = 19; work.WriteProgram(); work.Hour = 22; work.WriteProgram(); } } 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()); 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()); 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()); 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()); 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() { current = new ForenoonState(); } public double Hour { get { return hour; } set { hour = value; } } public bool TaskFinished { get { return finish; } set { finish = value; } } public void SetState(State s) { current = s; } public void WriteProgram() { current.WriteProgram(this); } } }
[狀態模式(State)]當一個對象的內在狀態改變時容許改變其行爲,這個對象看起來像是改變了其類
狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式過於複雜時的狀況.
把狀態的判斷邏輯轉移到表示不一樣狀態的一系列類當中,能夠把複雜的判斷邏輯簡化
第17章 在NBA我須要翻譯 [適配器模式]
using System; using System.Collections.Generic; namespace Test2 { class Program { static void Main(string[] args) { Target target = new Target(); target.Request(); Target adapter = new Adapter(); adapter.Request(); } } public class Target { public virtual void Request() { Console.WriteLine("普通請求!"); } } public class Adaptee { public void SepcificRequest() { Console.WriteLine("特殊請求!"); } } public class Adapter : Target { private Adaptee adaptee = new Adaptee(); public override void Request() { adaptee.SepcificRequest(); } } }
[適配器模式(Adapter)]將一個類的接口轉換成客戶但願的另一個接口.Adapter模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做
第18章 若是再回到從前 [備忘錄模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { Originator o = new Originator(); o.State = "On"; o.Show(); Caretaker c = new Caretaker(); c.Memento = o.CreateMemento(); o.State = "Off"; o.Show(); o.SetMemento(c.Memento); o.Show(); } } public class Originator { private string state; public string State { get { return state; } set { state = value; } } public Memento CreateMemento() { return new Memento(state); } public void SetMemento(Memento memento) { state = memento.State; } public void Show() { Console.WriteLine("State="+ state); } } public class Memento { private string state; public Memento(string state) { this.state = state; } public string State { get { return state; } } } public class Caretaker { private Memento memento; public Memento Memento { get { return memento; } set { memento = value; } } } }
[備忘錄(Memento)]在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態.這樣之後就可將該對象恢復到原先保存的狀態.
第19章 分公司=一部門 [組合模式]
using System; using System.Collections.Generic; namespace Test2 { 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")); Composite comp2 = new Composite("Composite XX"); comp2.Add(new Leaf("Leaf XXA")); comp2.Add(new Leaf("Leaf XXB")); comp.Add(comp2); root.Add(comp); root.Add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); root.Display(1); } } public 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); } public class Leaf : Component { public Leaf(string name) : base(name) { } public override void Add(Component c) { Console.WriteLine("Can't add to a leaf"); } public override void Remove(Component c) { Console.WriteLine("Can't remove from a leaf"); } public override void Display(int depth) { Console.WriteLine(new string('-',depth) + name); } } public 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); } } } }
[組合模式(Composite)]將對象組合成樹形結構以表示'部分-總體'的層次結構.組合模式使得用戶對單個對象和組合對象的使用具備一致性
第20章 想走?能夠!先買票 [迭代器模式]
using System; using System.Collections.Generic; namespace ConsoleApplication1 { public class Program { public 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); object item = i.First(); while (!i.IsDone()) { Console.WriteLine("{0} 請買車票!",i.CurrentItem()); i.Next(); } } } public abstract class Iterator { public abstract object First(); public abstract object Next(); public abstract bool IsDone(); public abstract object CurrentItem(); } public abstract class Aggregate { public abstract Iterator CreateIterator(); } public 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 bool IsDone() { return current >= aggregate.Count ? true : false; } public override object CurrentItem() { return aggregate[current]; } } public class ConcreteAggregate : Aggregate { public 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); } } } }
[迭代器模式(Iterator)]提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示
第21章 有些類也須要計劃生育 [單例模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { Singleton s1 = Singleton.GetInstance(); Singleton s2 = Singleton.GetInstance(); if (s1 == s2) { Console.WriteLine("兩個對象是相同的實例"); } } } public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton GetInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } }
[單例模式(Singleton)]保證一個類僅有一個實例,並提供一個訪問它的全局訪問點
一般咱們可讓一個全局變量使得一個對象被訪問,但它不能防止你實例化多個對象.一個最好的辦法就是,
讓類自身負責保存它的惟一實例.這個類能夠保證沒有其餘實例能夠被建立,而且它能夠提供一個訪問該實例的方法
第22章 手機軟件什麼時候統一 [橋接模式]
using System; namespace Test2 { class Program { static void Main(string[] args) { Abstraction ab = new RefinedAbstraction(); ab.SetImplementor(new ConcreteImplementorA()); ab.Operation(); ab.SetImplementor(new ConcreteImplementorB()); ab.Operation(); } } public abstract class Implementor { public abstract void Operation(); } public class ConcreteImplementorA : Implementor { public override void Operation() { Console.WriteLine("具體實現A的方法執行"); } } public class ConcreteImplementorB : Implementor { public override void Operation() { Console.WriteLine("具體實現B的方法執行"); } } public class Abstraction { protected Implementor implementor; public void SetImplementor(Implementor implementor) { this.implementor = implementor; } public virtual void Operation() { implementor.Operation(); } } public class RefinedAbstraction : Abstraction { public override void Operation() { implementor.Operation(); } } }
[橋接模式(Bridge)]將抽象部分與它的實現部分分離,使它們均可以獨立地變化
什麼叫抽象與它的實現分離,這並非說,讓抽象類與其派生類分離,由於這沒有任何意義.
實現指的是抽象類和它的派生類用來實現本身的對象
[合成/聚合複用原則(CARP)]儘可能使用合成/聚合,儘可能不要使用類繼承
聚合表示一種弱的"擁有"關係,體現的是A對象能夠包含B對象,但B對象不是A對象的一部分;合成則是一種強的"擁有「關係,
體現了嚴格的部分和總體的關係,部分和總體的生命週期同樣.
合成/聚合複用原則的好處是:優先使用對象的合成/聚合將有助於你保持每一個類被封裝,並被集中在單個任務上.
這樣類和類繼承層次會保持較小規模,而且不太可能增加爲不可控制的龐然大物
對象的繼承關係是在編譯時就定義好了,因此沒法在運行時改變從父類繼承的實現.
子類的實現與它的父類有很是緊密的依賴關係,以致於父類實現中的任何變化必然會致使子類發生變化.
當你須要複用子類時,若是繼承下來的實現不適合解決新的問題,則父類必須重寫或被其餘更適合的類替換.
這種依賴關係限制了靈活性並最終限制了複用性
第23章 烤羊肉串引來的思考 [命令模式]
using System; using System.Collections.Generic; namespace ConsoleApplication1 { public class Program { public static void Main(string[] args) { Receiver r = new Receiver(); Command c = new ConcreteCommand(r); Invoker i = new Invoker(); i.SetCommand(c); i.ExecuteCommand(); } } public abstract class Command { protected Receiver receiver; public Command(Receiver receiver) { this.receiver = receiver; } public abstract void Execute(); } public class ConcreteCommand : Command { public ConcreteCommand(Receiver receiver) : base(receiver) { } public override void Execute() { receiver.Action(); } } public class Receiver { public void Action() { Console.WriteLine("執行請求!"); } } public class Invoker { private Command command; public void SetCommand(Command command) { this.command = command; } public void ExecuteCommand() { command.Execute(); } } }
[命令模式(Command)]將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操做
敏捷開發原則告訴咱們,不要爲代碼添加基於猜想的,實際不須要的功能.若是不清楚一個系統是否須要命令模式,通常就不要着急去實現它,
事實上,在須要的時候經過重構實現這個模式並不困難,只有在真正須要如撤銷/恢復操做等功能時,把原來的代碼重構爲命令模式纔有意義
第24章 加薪非要老總批? [職責鏈模式]
using System; namespace Test2 { 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, 15, 14, 22, 18, 3, 27, 20}; foreach (int request in requests) { h1.HandleRequest(request); } } } public abstract class Handler { protected Handler successor; public void SetSuccessor(Handler successor) { this.successor = successor; } public abstract void HandleRequest(int request); } public 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); } } } public 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); } } } public 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); } } } }
[職責鏈模式(Chain of Responsibility)]使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係
將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止.
當客戶提交一個請求時,請求是沿鏈傳遞直至有一個ConcreteHandler對象負責處理它
接收者和發送者都沒有對方的明確信息,且鏈中的對象本身也並不知道鏈的結構.結果是職責鏈可簡化對象的相互鏈接,
它們僅須要保持一個指向其後繼者的引用,而不需保持它全部的候選接受者的引用
隨時地增長或修改處理一個請求的結構.加強了給對象指派職責的靈活性
第25章 世界須要和平 [中介者模式]
經過中介者對象,能夠將系統的網狀結構變成以中介者爲中心的星形結構,每一個具體對象再也不經過直接的聯繫與另外一個對象發生相互做用,
而是經過"中介者"對象與另外一個對象發生相互做用.中介者對象的設計,使得系統的結構不會由於新對象的引入形成大量的修改工做.
using System; namespace Test2 { class Program { static void Main(string[] args) { ConcreteMediator m = new ConcreteMediator(); ConcreteColleauge1 c1 = new ConcreteColleauge1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleauge1 = c1; m.Colleague2 = c2; c1.Send("吃過飯了嗎?"); c2.Send("沒有呢,你打算請客?"); } } public abstract class Mediator { public abstract void Send(string message, Colleague colleauge); } public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } } public class ConcreteMediator : Mediator { private ConcreteColleauge1 colleague1; private ConcreteColleague2 colleague2; public ConcreteColleauge1 Colleauge1 { 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); } } } public class ConcreteColleauge1 : Colleague { public ConcreteColleauge1(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message,this); } public void Notify(string message) { Console.WriteLine("同事1獲得信息:" + message); } } public 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); } } }
[中介者模式(Mediator)]用一箇中介對象來封裝一系列的對象交互.中介者使對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互
中介者模式很容易在系統中應用,也很容易在系統中誤用.當系統出現了"多對多"交互複雜的對象羣時,不要急於使用中介者模式,而要先反思你的系統在設計上是否是合理
Mediator的出現減小了各個Colleague的耦合,使得能夠獨立地改變和複用各個Colleague類和Mediator.
因爲把對象如何協做進行了抽象,將中介做爲一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各自自己的行爲轉移到它們之間的交互上來,
也就是站在一個更宏觀的角度去看待系統.
第26章 項目多也別傻作 [享元模式]
using System; using System.Collections.Generic; namespace Test2 { 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); } } public abstract class Flyweight { public abstract void Operation(int extrinsicstate); } public class ConcreteFlyweight : Flyweight { public override void Operation(int extrinsicstate) { Console.WriteLine("具體Flyweight:" + extrinsicstate); } } public class UnsharedConcreteFlyweight : Flyweight { public override void Operation(int extrinsicstate) { Console.WriteLine("不共享的具體Flyweight:" + extrinsicstate); } } public class FlyweightFactory { private Dictionary<string,Flyweight> flyweights = new Dictionary<string, Flyweight>(); public FlyweightFactory() { flyweights.Add("X",new ConcreteFlyweight()); flyweights.Add("Y",new ConcreteFlyweight()); flyweights.Add("Z",new ConcreteFlyweight()); } public Flyweight GetFlyweight(string key) { return flyweights[key]; } } }
[享元模式(Flyweight)]運用共享技術有效地支持大量細粒度的對象.
享元模式能夠避免大量很是相似的開銷.在程序設計中,有時須要生成大量細粒度的類實例來表示數據.
若是能發現這些實例除了幾個參數外基本上都是相同的,有時就可以受大幅度地減小須要實例化的類的數量.
若是能把那些參數移到類實例的外面,再方法調用時將它們傳遞進來,就能夠經過共享大幅度地減小單個實例的數目
若是一個應用程序使用了大量的對象,而大量的這些對象形成了很大的存儲開銷時就應該考慮使用;
還有就是對象的大多數狀態能夠外部狀態,若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象,
此時能夠考慮使用享元模式
第27章 其實你不懂老闆的心 [解釋器模式]
using System; using System.Collections.Generic; namespace Test2 { 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); } } } public abstract class AbstractExpression { public abstract void Interpret(Context context); } public class TerminalExpression : AbstractExpression { public override void Interpret(Context context) { Console.WriteLine("終端解釋器"); } } public class NonterminalExpression : AbstractExpression { public override void Interpret(Context context) { Console.WriteLine("非終端解釋器"); } } public class Context { private string input; private string output; public string Input { get { return input; } set { input = value; } } public string Output { get { return output; } set { output = value; } } } }
[解釋器模式(interpreter)]給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子
若是一種特定類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一個簡單語言的句子.
這樣就能夠構建一個解釋器,該解釋器經過解釋這些句子來解決該問題.
當有一個語言須要解釋執行,而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式
用瞭解釋器模式,就意味着能夠很容易地改變和擴展文法,由於該模式使用類來表示文法規則,你可以使用繼承來改變或擴展該文法.
也比較容易實現文法,由於定義抽象語法樹中各個節點的類的實現大致相似,這些類都易於直接編寫
解釋器模式也有不足的,解釋器模式爲文法中的每一條規則至少定義了一個類,所以包含許多規則的文法可能難以管理和維護.
建議當文法很是複雜時,使用其餘的技術如語法分析程序或編譯器生成器來處理.
第28章 男人和女人 [訪問者模式]
using System; using System.Collections.Generic; namespace Test2 { 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); } } public abstract class Element { public abstract void Accept(Visitor visitor); } public class ConcreteElementA : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementA(this); } public void OperationA() { } } public class ConcreteElementB : Element { public override void Accept(Visitor visitor) { visitor.VisitConcreteElementB(this); } public void OperationB() { } } public abstract class Visitor { public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA); public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB); } public class ConcreteVisitor1 : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0}被{1}訪問", concreteElementA.GetType().Name, this.GetType().Name); } public override void VisitConcreteElementB(ConcreteElementB conreteElementB) { Console.WriteLine("{0}被{1}訪問", conreteElementB.GetType().Name, this.GetType().Name); } } public class ConcreteVisitor2 : Visitor { public override void VisitConcreteElementA(ConcreteElementA concreteElementA) { Console.WriteLine("{0}被{1}訪問", concreteElementA.GetType().Name, this.GetType().Name); } public override void VisitConcreteElementB(ConcreteElementB conreteElementB) { Console.WriteLine("{0}被{1}訪問", conreteElementB.GetType().Name, this.GetType().Name); } } public 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); } } } }
[訪問者模式(Visitor)]表示一個做用於某對象結構中的各元素的操做.它使你能夠在不改變各元素的前提下定義做用於這些元素的新操做
第29章 OOTV杯超級模式大賽 [模式總結]