第1部分 适应设计模式

  第1章 Iterator(迭代器) 模式-一个一个遍历 (已看)

  第2章 Adapter(适配器) 模式-加个"适配器"模式以便于复用 (已看)

第2部分 交给子类

  第3章 Template Method(模板方法) 模式-将具体处理交给子类 (已看)

  第4章 Factory Method(工厂方法) 模式-将实例的生成交给子类 (已看)

第3部分 生成实例

  第5章 Singleton(单例) 模式-只有一个实例 (已看)

  第6章 Prototype(原型) 模式-通过复制生成实例 (已看)

  第7章 Builder(建造者) 模式-组装复杂的实例 (已看)

  第8章 Abstract Factory(抽象工厂) 模式-将关联零件组装成产品 (已看)

第4部分 分开考虑

  第9章 Brige(桥接) 模式-将类的功能层次结构与实现层次结构分离 (已看)

  第10章 Strategy(策略) 模式-整体地替换算法 (已看)

第5部分 一致性

  第11章 Composite(组合) 模式-容器与内容的一致性 (已看)

  第12章 Decorator(装饰) 模式-装饰边框与被装饰物的一致性 (已看)

第6部分 访问数据结构

  第13章 Visitor(访问者) 模式-访问数据结构并处理数据 (已看)

  第14章 Chain of Responsibility(职责链) 模式-推卸责任 (已看)

第7部分 简单化

  第15章 Facade(外观) 模式-简单窗口 (已看)

  第16章 Mediator(中介者) 模式-只有一个仲裁者 (已看)

第8部分 管理状态

  第17章 Observer(观察者) 模式-发送状态变化通知 (已看)

  第18章 Memento(备忘录) 模式-保存对象状态 (已看)

  第19章 State(状态) 模式-用类表示状态 (已看)

第9部分 避免浪费

  第20章 Flyweight(享元) 模式-共享对象,避免浪费 (已看)

  第21章 Proxy(代理) 模式-只在必要时生成实例 (已看)

第10部分 用类来表现

  第22章 Command(命令) 模式-命令也是类 (已看)

  第23章 Interpreter(解释器) 模式-语法规则也是类 (已看)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第1部分 适应设计模式

  第1章 Iterator(迭代器) 模式-一个一个遍历

using System;
using System.Collections;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {BookShelf bookShelf = new BookShelf(3);Book book1 = new Book("Book1");Book book2 = new Book("Book2");Book book3 = new Book("Book3");bookShelf.AddBook(book1);bookShelf.AddBook(book2);bookShelf.AddBook(book3);IIterator iterator = bookShelf.iterator();while (iterator.hasNext()) {Book book = iterator.next() as Book;Console.WriteLine(book.getName());}}    }public interface IAggregate {IIterator iterator();}public interface IIterator {bool hasNext();object next();}public class BookShelf : IAggregate {private Book[] books;private IIterator iter;private int length;public BookShelf(int maxSize) {books = new Book[maxSize];length = 0;}public int getLength() {return length;}public Book getBookAt(int index) {return books[index];}public void AddBook(Book book) {books[length] = book;length++;}public IIterator iterator() {return new BookShelfIterator(this);}}public class BookShelfIterator : IIterator {private BookShelf bookShelf;private int pos;public BookShelfIterator(BookShelf bookShelf) {this.bookShelf = bookShelf;pos = 0;}public bool hasNext() {if (pos < bookShelf.getLength()) {return true;} else {return false;}}public object next() {Book book = bookShelf.getBookAt(pos);pos++;return book;}}public class Book {private string name;public Book(string name) {this.name = name;}public string getName() {return name;}}
}

View Code

Iterator模式的类图

相关模式

  Vistor模式

    Iterator模式是从集合中一个一个取出元素进行遍历,但是并没有在Iterator接口中声明对取出的元素进行何种处理

    Visitro模式则是在遍历元素集合的过程中,对元素进行相同的处理

    在遍历集合的过程中对元素进行固定的处理是常有的需求.Visitor模式正是为了应对这种需求而出现的.

    在访问元素集合的过程中对元素进行相同的处理.这种模式就是Visitor模式

  Composite模式

    Composite模式是具有递归结构的模式,在其中使用Iterator模式比较困难

  Factory Method模式

    在iterator方法中生成的Iterator的实例可能会使用Factory Method模式

  第2章 Adapter(适配器) 模式-加个"适配器"模式以便于复用

using System;
using System.Collections;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {IPrint banner = new PrintBanner("haha");banner.printWeak();banner.printStrong();}    }public class Banner {private string str;public Banner(string str) {this.str = str;}public void showWithParen() {Console.WriteLine("(" + str + ")");}public void showWithAster() {Console.WriteLine("*" + str + "*");} }public interface IPrint {void printWeak();void printStrong();}public class PrintBanner : Banner,IPrint {public PrintBanner(string str) : base(str) {}public void printWeak() {base.showWithParen();}public void printStrong() {base.showWithAster();}}}

View Code

类适配器模式的类图(使用继承)

using System;
using System.Collections;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {APrint print = new PrintBanner(new Banner("Hello"));print.printWeak();print.printStrong();}    }public abstract class APrint {public abstract void printWeak();public abstract void printStrong();}public class PrintBanner : APrint {private Banner banner;public PrintBanner(Banner banner) {this.banner = banner;}public override void printWeak() {banner.showWithParen();}public override void printStrong() {banner.showWithAster();}}public class Banner {private string str;public Banner(string str) {this.str = str;}public void showWithParen() {Console.WriteLine("(" + str + ")");}public void showWithAster() {Console.WriteLine("*" + str + "*");}}
}

View Code

类适配器模式的类图(使用继承)

相关的设计模式

  Bridge模式

    Adapter模式用于连接接口(API)不同的类,而Bridge模式则用于连接类的功能层次结构与实现层次结构

  Decorator模式

    Adapter模式用于填补不同接口(API)之间的缝隙,而Decorator模式则是在不改变接口(API)的前提下增加功能

第2部分 交给子类

  第3章 Template Method(模板方法) 模式-将具体处理交给子类

using System;namespace Test1 {class Program {static void Main(string[] args) {AbstractDisplay d1 = new CharDisplay('H');AbstractDisplay d2 = new StringDisplay("Hello,World.");AbstractDisplay d3 = new StringDisplay("World,Hello");d1.display();d2.display();d3.display();}    }public abstract class AbstractDisplay {public abstract void open();public abstract void print();public abstract void close();public void display() {open();for (int i = 0; i < 5; i++) {print();}close();}}public class CharDisplay : AbstractDisplay {private char ch;public CharDisplay(char ch) {this.ch = ch;}public override void open() {Console.WriteLine("<<");}public override void print() {Console.WriteLine(ch);}public override void close() {Console.WriteLine(">>");}               }public class StringDisplay : AbstractDisplay {private string str;private int width;public StringDisplay(string str) {this.str = str;this.width = str.ToCharArray().Length;}public override void open() {printLine();}public override void print() {Console.WriteLine("|" + str + "|");}public override void close() {printLine();}private void printLine() {Console.Write("+");for (int i = 0; i < width; i++) {Console.Write("-");}Console.WriteLine("+");}}
}

View Code

Template Method模式的类图

相关的设计模式

  Factory Method模式

    Factory Method模式是将Template Method模式用于生成实例的一个典型例子

  Strategy 模式

    在Template Method模式中,可以使用继承改变程序的行为.这是因为Template Method模式在父类中定义程序行为的框架,在子类中决定具体的处理.

    与此相对的是Strategy模式,它可以使用委托改变程序的行为.与Template Method模式中改变部分程序行为不同的是,Strategy模式用于替换整个算法.

延伸阅读:类的层次与抽象类

  父类对子类的要求

    我们在理解类的层次时,通常是站在子类的角度进行思考的.也就是说,很容易着眼于以下几点

      在子类中可以使用父类中定义的方法

      可以通过在子类中增加方法增加方法以实现新的功能

      在子类中重写父类的方法可以改变程序的行为

    现在,让我们稍微改变一下立场,站在父类的角度进行思考.在父类中,我们声明了抽象方法,而将该方法的实现交给了子类.换言之,就程序而言,声明抽象方法是希望达到以下目的.

      期待子类去实现抽象方法

      要求子类去实现抽象方法

    也就是说,子类具有实现在父类中所声明的抽象方法的责任.因此,这种责任被称为"子类责任"(subclass responsibility).

  第4章 Factory Method(工厂方法) 模式-将实例的生成交给子类

using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;namespace Test1 {class Program {static void Main(string[] args) {AFactory factory = new IDCardFactory();AProduct card1 = factory.create("小明");AProduct card2 = factory.create("小红");AProduct card3 = factory.create("小刚");card1.use();card2.use();card3.use();}    }public abstract class AProduct {public abstract void use();}public abstract class AFactory {public AProduct create(string owner) {AProduct p = createProduct(owner);registerProduct(p);return p;}protected abstract AProduct createProduct(string owner);protected abstract void registerProduct(AProduct product);}public class IDCard : AProduct {private string owner;public IDCard(string owner) {this.owner = owner;Console.WriteLine("制作" + owner + "的ID卡.");}public override void use() {Console.WriteLine("使用" + owner + "的ID卡");}public string getOwner() {return owner;}}public class IDCardFactory : AFactory {private ArrayList owners = new ArrayList();protected override AProduct createProduct(string owner) {return new IDCard(owner);}protected override void registerProduct(AProduct product) {owners.Add(((IDCard) product).getOwner());}public ArrayList getOwners() {return owners;}}
}

View Code

Factory Method模式的类图

相关的设计模式

  Template Method模式

    Factory Method模式是Template Method的典型应用

  Singleton模式

    在多数情况下我们可以将Singleton模式用于扮演Creator角色(或是ConcreteCreator角色)的类

    这是因为在程序中没有必要存在多个Crerator角色(或是ConcreteCreator角色)的实例

  Composite模式

    有时可以将Composite模式用于Product角色(或是ConreteProduct角色).

  Iterator模式

    有时,在Iterator模式中使用iterator方法生成Iterator的实例时会使用Factory Method模式.

第3部分 生成实例

  第5章 Singleton(单例) 模式-只有一个实例

using System;namespace Test1 {class Program {static void Main(string[] args) {Console.WriteLine("Start.");Singleton obj1 = Singleton.getInstance();Singleton obj2 = Singleton.getInstance();if (obj1 == obj2) {Console.WriteLine("obj1与obj2是相同的实例");} else {Console.WriteLine("obj1与obj2是不同的实例");}}    }public class Singleton {private static Singleton singleton = new Singleton();private Singleton() {Console.WriteLine("生成了一个实例");}public static Singleton getInstance() {return singleton;}}
}

View Code

Singleton模式的类图

相关的设计模式

  AbstractFactory 模式

  Builder 模式

  Facade 模式

  Prototype 模式

  第6章 Prototype(原型) 模式-通过复制生成实例

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;namespace ConsoleApplication1 {public class Program {public static void Main(string[] args) {Manager manager = new Manager();UnderlinePen upen = new UnderlinePen('~');MessageBox mBox = new MessageBox('*');MessageBox sBox = new MessageBox('/');manager.register("strong message",upen);manager.register("warning box",mBox);manager.register("slash box",sBox);IProduct p1 = manager.create("strong message");p1.use("Hello,world.");IProduct p2 = manager.create("warning box");p2.use("Hello,world.");IProduct p3 = manager.create("slash box");p3.use("Hello,world.");}}public interface IProduct : ICloneable {void use(string str);IProduct createClone();}public class MessageBox : IProduct {private char decoChar;public MessageBox(char deoChar) {this.decoChar = deoChar;}public void use(string str) {int length = str.ToCharArray().Length;for (int i = 0; i < length + 4; i++) {Console.Write(decoChar);}Console.WriteLine("");Console.WriteLine(decoChar + " " + str + " " + decoChar);for (int i = 0; i < length + 4; i++) {Console.Write(decoChar);}Console.WriteLine("");}public IProduct createClone() {return (IProduct) MemberwiseClone();}public Object Clone() {return MemberwiseClone();}}public class UnderlinePen : IProduct {private char ulChar;public UnderlinePen(char ulChar) {this.ulChar = ulChar;}public void use(string str) {int length = str.ToCharArray().Length;Console.WriteLine("\"" + str + "\"");Console.Write(" ");for (int i = 0; i < length; i++) {Console.Write(ulChar);}Console.WriteLine("");}public IProduct createClone() {return (IProduct)MemberwiseClone();}public Object Clone() {return MemberwiseClone();}}public class Manager {private Dictionary<string,IProduct> showcase = new Dictionary<string, IProduct>();public void register(string name, IProduct proto) {showcase.Add(name,proto);}public IProduct create(string protoName) {IProduct product = (IProduct) showcase[protoName];return product.createClone();}}}

View Code

Prototype模式的类图

相关的设计模式

  Flyweight模式

    使用Prototype模式可以生成一个与当前实例的状态完全相同的实例

    而使用Flyweight模式可以在不同的地方使用同一个实例

  Memento模式

    使用Prototype模式可以生成一个与当前实例的状态完全相同的实例.

    而使用Memento模式可以保存当前实例的状态,以实现快照和撤销功能

  Composite模式以及Decorator模式

    经常使用Composite模式和Decorator模式时,需要能够动态地创建复杂结构的实例.这时可以使用Prototype模式,以帮助我们方便地生成实例

  Command模式

    想要复制Command模式中出现的命令时,可以使用Prototype模式

  第7章 Builder(建造者) 模式-组装复杂的实例

using System;
using System.Runtime.InteropServices;
using System.Text;namespace ConsoleApplication1 {public class Program {public static void Main(string[] args) {TextBuilder textBuilder = new TextBuilder();Director director = new Director(textBuilder);director.construct();string result = textBuilder.getResult();Console.WriteLine(result);}}public abstract class ABuilder {public abstract void makeTitle(string title);public abstract void makeString(string str);public abstract void makeItems(string[] items);public abstract void close();}public class TextBuilder : ABuilder {private StringBuilder buffer = new StringBuilder();public override void makeTitle(string title) {buffer.Append("=========================\n");buffer.Append("[" + title + "]\n");buffer.Append("\n");}public override void makeString(string str) {buffer.Append('^' + str + '\n');buffer.Append("\n");}public override void makeItems(string[] items) {for (int i = 0; i < items.Length; i++) {buffer.Append("   *" + items[i] + "\n");}buffer.Append("\n");}public override void close() {buffer.Append("=========================\n");}public string getResult() {return buffer.ToString();}}public class Director {private ABuilder builder;public Director(ABuilder builder) {this.builder = builder;}public void construct() {builder.makeTitle("Greeting");builder.makeString("从早上到下午");builder.makeItems(new string[] {"早上好","下午好"});builder.makeString("晚上");builder.makeItems(new string[] {"晚上好","晚安","再见"});builder.close();}}}

View Code

Builder模式的类图

Builder模式的时序图

相关的设计模式

  Template Method模式

    在Builder模式中,Director角色控制Builder角色

    在Template Method模式中,父类控制子类

  Composite模式

    有些情况下Builder模式生成的实例构成了Composite模式

  Abstract Factory模式

    Builder模式和Abstract Factory模式都用于生成复杂的模式

  Facade 模式

    在Builder模式中,Director角色通过组合Builder角色中的复杂方法向外部提供可以简单生成实例的接口(API)(相当于示例程序中的construct方法)

    Facade模式中的Facade角色则是通过组合内部模块向外部提供可以简单调用的接口(API)

  第8章 Abstract Factory(抽象工厂) 模式-将关联零件组装成产品

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Web;
using System.Reflection;namespace ConsoleApplication1 {public class Program {public static void Main(string[] args) {AFactory factory = AFactory.getFactory();ALink people = factory.createLink("人民日报", "http://www.people.com.cn/");ALink gmw = factory.createLink("光明日报", "http://www.gmw.cn/");ALink us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");ALink jp_yahoo = factory.createLink("Yahoo!Japn", "http://www.yahoo.co.jp/");ALink excite = factory.createLink("Excite", "http://www.excite.com/");ALink google = factory.createLink("Google", "http://www.google.com/");ATray traynews = factory.createTray("日报");traynews.add(people);traynews.add(gmw);ATray trayyahoo = factory.createTray("Yahoo!");trayyahoo.add(us_yahoo);trayyahoo.add(jp_yahoo);ATray traysearch = factory.createTray("检索引擎");traysearch.add(trayyahoo);traysearch.add(excite);traysearch.add(google);APage page = factory.createPage("LinkPage", "void");page.add(traynews);page.add(traysearch);page.output();}}public abstract class AItem {protected string caption;public AItem(string caption) {this.caption = caption;}public abstract string makeHTML();}public abstract class ALink : AItem {protected string url;public ALink(string caption, string url) : base(caption) {this.url = url;}}public class ListLink : ALink {public ListLink(string caption, string url) : base(caption,url) {}public override string makeHTML() {return "  <li><a href=\"" + url + "\">" + caption + "</a></li>\n";}}public abstract class ATray : AItem {protected List<AItem> tray = new List<AItem>();public ATray(string caption) : base(caption) {}public void add(AItem item) {tray.Add(item);}}public class ListTray : ATray {public ListTray(string caption) : base(caption) {}public override string makeHTML() {StringBuilder buffer = new StringBuilder();buffer.Append("<li>\n");buffer.Append(caption + "\n");buffer.Append("<ul>\n");foreach (var item in tray) {buffer.Append(item.makeHTML());}buffer.Append("</ul>\n");buffer.Append("</li>\n");return buffer.ToString();}}public abstract class APage {protected string title;protected string author;protected List<AItem> content = new List<AItem>();public APage(string title, string author) {this.title = title;this.author = author;}public void add(AItem item) {content.Add(item);}public void output() {Console.WriteLine(makeHTML());}public abstract string makeHTML();}public class ListPage : APage {public ListPage(string title, string author) : base(title,author) {}public override string makeHTML() {StringBuilder buffer = new StringBuilder();buffer.Append("<html><head></title>" + title + "</title></head>\n");buffer.Append("<body>\n");buffer.Append("<h1>" + title + "</h1>\n");buffer.Append("<ul>\n");foreach (var item in content) {buffer.Append(item.makeHTML());}buffer.Append("</ul>\n");buffer.Append("<hr><address>" + author + "</address>");buffer.Append("</body></html>");return buffer.ToString();}}public abstract class AFactory {public static AFactory getFactory() {return new ListFactory();}public abstract ALink createLink(string caption, string url);public abstract ATray createTray(string caption);public abstract APage createPage(string title, string author);}public class ListFactory : AFactory {public override ALink createLink(string caption, string url) {return new ListLink(caption,url);}public override ATray createTray(string caption) {return new ListTray(caption);}public override APage createPage(string title, string author) {return new ListPage(title,author);}}}

View Code

Abstract Factory模式

相关的设计模式

  Builder模式

    Abstract Factory模式通过调用抽象产品的接口(API)来组装抽象产品,生成具有复杂结构的实例.

  Factory Method模式

    有时Abstract Factory模式中零件和产品的生成会使用到Factory Method模式.

  Composite模式

    有时Abstract Factory模式在制作产品时会使用Composite模式

  Singleton模式

    有时Abstract Factory模式中的具体工厂会使用Singleton模式

第4部分 分开考虑

  第9章 Brige(桥接) 模式-将类的功能层次结构与实现层次结构分离

类的功能层次结构

  父类具有基本功能

  在子类中增加新的功能

  

类的实现层次结构

  父类通过声明抽象方法来定义接口(API)

  子类通过实现具体方法来实现接口(API)

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {Display d1 = new Display(new StringDisplayImpl("Hello,China."));Display d2 = new CountDisplay(new StringDisplayImpl("Hello,World."));CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello,Universe"));d1.display();d2.display();d3.display();d3.multiDisplay(5);}    }public class Display {private ADisplayImpl impl;public Display(ADisplayImpl impl) {this.impl = impl;}public void open() {impl.rawOpen();}public void print() {impl.rawPrint();}public void close() {impl.rawClose();}public void display() {open();print();close();}}public class CountDisplay : Display {public CountDisplay(ADisplayImpl impl) : base(impl) {}public void multiDisplay(int times) {open();for (int i = 0; i < times; i++) {print();}close();}}public abstract class ADisplayImpl {public abstract void rawOpen();public abstract void rawPrint();public abstract void rawClose();}public class StringDisplayImpl : ADisplayImpl {private string str;private int width;public StringDisplayImpl(string str) {this.str = str;this.width = str.ToCharArray().Length;}public override void rawOpen() {printLine();}public override void rawPrint() {Console.WriteLine("|" + str + "|");}public override void rawClose() {printLine();}private void printLine() {Console.Write("+");for (int i = 0; i < width; i++) {Console.Write("-");}Console.WriteLine("+");}}
}

View Code

Birdge 模式的类图

相关的设计模式

  Template Method模式

    在Template Method模式中使用了“类的实现层次结构".父类调用抽象方法,而子类实现抽象方法

  Abstract Factory模式

    为了能够根据需求设计出良好的ConcreteImplement角色,有时我们会使用Abstract Factory模式

  Adapter模式

    使用Bridge模式可以达到类的功能层次结构与类的实现层次结构分离的目的,并在此基础上使这些层次结构结合起来.

    而使用Adapter模式则可以结合那些功能上相似但是接口(API)不同的类

  第10章 Strategy(策略) 模式-整体地替换算法

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {int seed1 = 314;int seed2 = 15;Player player1 = new Player("Taro",new WinningStrategy(seed1));Player player2 = new Player("Hana",new ProbStrategy(seed2));for (int i = 0; i < 10000; i++) {Hand nextHand1 = player1.nextHand();Hand nextHand2 = player2.nextHand();if (nextHand1.isStrongerThan(nextHand2)) {Console.WriteLine("Winner:" + player1);player1.win();player2.lose();} else if (nextHand2.isStrongerThan(nextHand1)) {Console.WriteLine("Winner:" + player2);player1.lose();player2.win();} else {Console.WriteLine("Even...");player1.even();player2.even();}}Console.WriteLine("Total result:");Console.WriteLine(player1.toString());Console.WriteLine(player2.toString());}    }public class Hand {public static int HANDVALUE_GUU = 0;public static int HANDVALUE_CHO = 1;public static int HANDVALUE_PAA = 2;private int handvalue;public static Hand[] hand = {new Hand(HANDVALUE_GUU),new Hand(HANDVALUE_CHO),new Hand(HANDVALUE_PAA),};public static string[] name = {"石头","剪刀","布"};private Hand(int handvalue) {this.handvalue = handvalue;}public static Hand getHand(int handvalue) {return hand[handvalue];}public bool isStrongerThan(Hand h) {return fight(h) == 1;}public bool isWeakerThan(Hand h) {return fight(h) == -1;}private int fight(Hand h) {if (this == h) {return 0;} else if ((this.handvalue + 1) % 3 == h.handvalue) {return 1;} else {return -1;}}public string toString() {return name[handvalue];}}public interface IStrategy {Hand nextHand();void study(bool win);}public class WinningStrategy : IStrategy {private Random random;private bool won = false;private Hand prevHand;public WinningStrategy(int seed) {random = new Random(seed);}public Hand nextHand() {if (!won) {prevHand = Hand.getHand(random.Next(3));}return prevHand;}public void study(bool win) {won = win;}        }public class ProbStrategy : IStrategy {private Random random;private int prevHandValue = 0;private int currentHandValue = 0;private int[,] history =  {{1,1,1},{1,1,1},{1,1,1},};public ProbStrategy(int seed) {random = new Random();}public Hand nextHand() {int bet = random.Next(getSum(currentHandValue));int handvalue = 0;if (bet < history[currentHandValue, 0]) {handvalue = 0;} else if (bet < history[currentHandValue, 0] + history[currentHandValue, 1]) {handvalue = 1;} else {handvalue = 2;}prevHandValue = currentHandValue;currentHandValue = handvalue;return Hand.getHand(handvalue);}private int getSum(int hv) {int sum = 0;for (int i = 0; i < 3; i++) {sum += history[hv,i];}return sum;}public void study(bool win) {if (win) {history[prevHandValue,currentHandValue]++;}   else {history[prevHandValue, (currentHandValue + 1) % 3]++;history[prevHandValue, (currentHandValue + 2) % 3]++;}}}public class Player {private string name;private IStrategy strategy;private int wincount;private int losecount;private int gamecount;public Player(string name, IStrategy strategy) {this.name = name;this.strategy = strategy;}public Hand nextHand() {return strategy.nextHand();}public void win() {strategy.study(true);wincount++;gamecount++;}public void lose() {strategy.study(false);losecount++;gamecount++;}public void even() {gamecount++;}public string toString() {return "[" + name + ":" + gamecount + " games, " + wincount + " win, " + losecount + " lose" + "]";}}
}

View Code

Strategy模式的类图

相关的设计模式

  Flyweight模式

    有时会使用Flyweight模式让多个地方可以共用ConcreteStrategy角色

  AbstractFactory模式

    使用Strategy模式可以整体地替换算法.

    使用Abstract Factory模式则可以整体地替换具体工厂,零件和产品.

  State模式

    使用Strategy模式和State模式都可以替换被委托对象,而且它们之间的关系也很相似.但是两种模式的目的不同.

    在Strategy模式中,ConcreteStrategy角色是表示算法的类.在Strategy模式中,可以替换被委托对象的类.当然如果没有必要,也可以不替换.

    而在State模式中,ConcreteState角色是表示"状态"的类.在State模式中,每次状态变化时,被委托对象的类都必定会被替换.

第5部分 一致性

  第11章 Composite(组合) 模式-容器与内容的一致性

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {Console.WriteLine("Making root entries...");Directory rootdir = new Directory("root");Directory binddir = new Directory("bin");Directory tmpdir = new Directory("tmp");Directory usrdir = new Directory("usr");rootdir.add(binddir);rootdir.add(tmpdir);rootdir.add(usrdir);binddir.add(new File("vi", 10000));binddir.add(new File("latex", 20000));rootdir.printList();Console.WriteLine("");Console.WriteLine("Making user entries...");Directory yuki = new Directory("yuki");Directory hanako = new Directory("hanako");Directory tomura = new Directory("tomura");usrdir.add(yuki);usrdir.add(hanako);usrdir.add(tomura);yuki.add(new File("diary.html", 100));yuki.add(new File("Composite.java", 200));hanako.add(new File("memo.tex", 300));hanako.add(new File("game.doc", 400));hanako.add(new File("junk.mail", 500));rootdir.printList();}    }public abstract class AEntry {public abstract string getName();public abstract int getSize();public AEntry add(AEntry entry) {throw new  NotImplementedException();}public void printList() {printList("");}public abstract void printList(string prefix);public override string ToString() {return getName() + " (" + getSize() + ") "; }}public class File : AEntry {private string name;private int size;public File(string name, int size) {this.name = name;this.size = size;}public override string getName() {return name;}public override int getSize() {return size;}public override void printList(string prefix) {Console.WriteLine(prefix + "/" + this);}}public class Directory : AEntry {private string name;private List<AEntry> entries = new List<AEntry>();public Directory(string name) {this.name = name;}public override string getName() {return name;}public override int getSize() {int size = 0;foreach (var item in entries) {size += item.getSize();}return size;}public AEntry add(AEntry entry) {entries.Add(entry);return this;}public override void printList(string prefix) {Console.WriteLine(prefix + "/" + this);foreach (var item in entries) {item.printList(prefix + "/" + name);}}}
}

View Code

Composite模式的类图

相关的设计模式

  Command模式

  Visitor模式

    可以使用Visitor模式访问Composite模式中的递归结构

  第12章 Decorator(装饰) 模式-装饰边框与被装饰物的一致性

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {ADisplay b1 = new StringDisplay("Hello,World.");ADisplay b2 = new SideBorder(b1,'#');ADisplay b3 = new FullBorder(b2);b1.show();b2.show();b3.show();ADisplay b4 = new SideBorder(new FullBorder(new FullBorder(new SideBorder(new FullBorder(new StringDisplay("Hello")),'*'))),'/');b4.show();}}public abstract class ADisplay {public abstract int getColumns();public abstract int getRows();public abstract string getRowText(int row);public void show() {for (int i = 0; i < getRows(); i++) {Console.WriteLine(getRowText(i));}}               }public class StringDisplay : ADisplay {private string str;public StringDisplay(string str) {this.str = str;}public override int getColumns() {return str.ToCharArray().Length;}public override int getRows() {return 1;}public override string getRowText(int row) {if (row == 0) {return str;} else {return null;}}}public abstract class ABorder : ADisplay {protected ADisplay display;protected ABorder(ADisplay display) {this.display = display;}}public class SideBorder : ABorder {private char borderChar;public SideBorder(ADisplay display, char ch) : base(display) {this.borderChar = ch;}public override int getColumns() {return 1 + display.getColumns() + 1;}public override int getRows() {return display.getRows();}public override string getRowText(int row) {return borderChar + display.getRowText(row) + borderChar;}}public class FullBorder : ABorder {public FullBorder(ADisplay display) : base(display) {}public override int getColumns() {return 1 + display.getColumns() + 1;}public override int getRows() {return 1 + display.getRows() + 1;}public override string getRowText(int row) {if (row == 0) {return "+" + makeLine('-', display.getColumns()) + "+";} else if (row == display.getRows() + 1) {return "+" + makeLine('-', display.getColumns()) + "+";} else {return "|" + display.getRowText(row - 1) + "|";}}private string makeLine(char ch, int count) {StringBuilder buf = new StringBuilder();for (int i = 0; i < count; i++) {buf.Append(ch);}return buf.ToString();}}
}

View Code

Decorator模式的类图

相关的设计模式

  Adapter模式

    Decorator模式可以在不改变被装饰物的接口(API)的前提下,为被装饰物添加边框(透明性)

    Adapter模式用于适配两个不同的接口(API)

  Strategy模式

    Decorator模式可以像改变被装饰物的边框或是被装饰物添加多重边框那样,来增加类的功能.

    Stragety模式通过整体地替换算法来改变类的功能

第6部分 访问数据结构

  第13章 Visitor(访问者) 模式-访问数据结构并处理数据

using System;
using System.Collections;
using System.Collections.Generic;namespace ConsoleApplication1 {public class Program {public static void Main(string[] args) {Console.WriteLine("Making root entries...");Directory rootdir = new Directory("root");Directory bindir = new Directory("bin");Directory tmpdir = new Directory("tmp");Directory usrdir = new Directory("usr");rootdir.add(bindir);rootdir.add(tmpdir);rootdir.add(usrdir);bindir.add(new File("vi", 100000));bindir.add(new File("latex", 20000));rootdir.accept(new ListVisitor());}}public abstract class AVisitor {public abstract void visit(File file);public abstract void visit(Directory dir);}public class ListVisitor : AVisitor {private string currentdir = "";public override void visit(File file) {Console.WriteLine(currentdir + "/" + file);}public override void visit(Directory directory) {Console.WriteLine(currentdir + "/" + directory);string savedir = currentdir;currentdir = currentdir + "/" + directory.getName();foreach (var item in directory.dir) {item.accept(this);}currentdir = savedir;}}public interface IElement {void accept(AVisitor v);}public abstract class AEntry : IElement {public abstract string getName();public abstract int getSize();public AEntry add(AEntry entry) {throw new NotImplementedException();}public override string ToString() {return getName() + " (" + getSize() + ")";}public abstract void accept(AVisitor v);}public class File : AEntry {private string name;private int size;public File(string name, int size) {this.name = name;this.size = size;}public override string getName() {return name;}public override int getSize() {return size;}public override void accept(AVisitor v) {v.visit(this);}}public class Directory : AEntry {private string name;public List<AEntry> dir = new List<AEntry>();public Directory(string name) {this.name = name;}public override string getName() {return name;}public override int getSize() {int size = 0;foreach (var item in dir) {size += item.getSize();}return size;}public AEntry add(AEntry entry) {dir.Add(entry);return this;}public override void accept(AVisitor v) {v.visit(this);}}
}

View Code

Visitor模式的类图

相关的设计模式

  Iterator模式

    Iterator模式和Visitor模式都是在某种数据结构上进行处理

    Iterator模式用于逐个遍历保存在数据结构中的元素

    Visitor模式用于对保存在数据结构中的元素进行某种特定的处理

  Composite模式

    有时访问者所访问的数据结构会使用Composite模式

  Interpreter模式

    在Interpreter模式中,有时会使用Visitor模式

  第14章 Chain of Responsibility(职责链) 模式-推卸责任

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;namespace Test1 {class Program {static void Main(string[] args) {ASupport alice = new NotSupport("Alice");ASupport bob = new LimitSupport("Bob",100);ASupport charlie = new SpecialSupport("Charlie",429);ASupport diana = new LimitSupport("Diana",200);ASupport elmo = new OddSupport("Elmo");ASupport fred = new LimitSupport("Fred",300);alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);for (int i = 0; i < 500; i += 33) {alice.support(new Trouble(i));}}}public class Trouble {private int number;public Trouble(int number) {this.number = number;}public int getNumber() {return number;}public string toString() {return "[Trouble " + number + "]";}}public abstract class ASupport {private string name;private ASupport next;public ASupport(string name) {this.name = name;}public ASupport setNext(ASupport next) {this.next = next;return next;}public void support(Trouble trouble) {if (resolve(trouble)) {done(trouble);  } else if(next != null) {next.support(trouble);} else {fail(trouble);  }}public override string ToString() {return "[" + name + "]";}protected abstract bool resolve(Trouble trouble);protected void done(Trouble trouble) {Console.WriteLine(trouble + " is resolved by " + this + ".");}protected void fail(Trouble trouble) {Console.WriteLine(trouble + " cannot be resolved.");}}public class NotSupport : ASupport {public NotSupport(string name) : base(name) {}protected override bool resolve(Trouble trouble) {return false;}}public class LimitSupport : ASupport {private int limit;public LimitSupport(string name, int limit) : base(name) {this.limit = limit;}protected override bool resolve(Trouble trouble) {if (trouble.getNumber() < limit) {return true;} else {return false;}}}public class OddSupport : ASupport {public OddSupport(string name) : base(name) {}protected override bool resolve(Trouble trouble) {if (trouble.getNumber() % 2 == 1) {return true;} else {return false;}}}public class SpecialSupport : ASupport {private int number;public SpecialSupport(string name, int number) : base(name) {this.number = number;}protected override bool resolve(Trouble trouble) {if (trouble.getNumber() == number) {return true;} else {return false;}}}
}

View Code

Chain of Responsibility模式的类图

相关的设计模式

  Composite模式

    Handler角色经常会使用Composite模式

  Command模式

    有时会使用Command模式向Handler角色发送请求

第7部分 简单化

  第15章 Facade(外观) 模式-简单窗口

using System;namespace Test1 {class Program {static void Main(string[] args) {Facade f = new Facade();f.Interface();}}public class Facade {private ClassA a;private ClassB b;private ClassC c;public Facade() {a = new ClassA();b = new ClassB();c = new ClassC();}public void Interface() {a.method();b.method();c.method();}}public class ClassA {public void method() {Console.WriteLine("ClassA Method");}}public class ClassB {public void method() {Console.WriteLine("ClassB Method");}        }public class ClassC {public void method() {Console.WriteLine("ClassC Method");}}
}

View Code

Facade模式的类图

相关的设计模式

  Abstract Factory模式

    可以将Abstract Factory模式看作生成复杂实例时的Facade模式.因为它提供了"要想生成这个实例只需要调用这个方法就OK了"的简单接口

  Singleton 模式

    有时会使用SIngleton模式创建Facade角色

  Mediator 模式

    在Facade模式中,Facade角色单方面地使用其他角色来提供高层接口(API)

    而在Mediator模式中,Mediator角色作为Colleague角色间的仲裁者负责调停.可以说,Facade模式是单向的,而Mediator角色是双向的.

  第16章 Mediator(中介者) 模式-只有一个仲裁者

using System;namespace Test1 {class Program {static void Main(string[] args) {IMediator mediator = new LoginFrame();mediator.colleagueChanged();}}public interface IMediator {void createColleagues();void colleagueChanged();}public interface IColleague {void setMediator(IMediator mediator);void setColleagueEnabled(bool enabled);}public class ColleagueButton : IColleague {private IMediator mediator;private string caption;public ColleagueButton(string caption) {this.caption = caption;}public void setMediator(IMediator mediator) {this.mediator = mediator;}public void setColleagueEnabled(bool enabled) {Console.WriteLine("enabled:" + enabled);}  }public class ColleagueTextField : IColleague {private IMediator mediator;private string caption;public ColleagueTextField(string caption) {this.caption = caption;}public void setMediator(IMediator mediator) {this.mediator = mediator;}public void setColleagueEnabled(bool enabled) {Console.WriteLine("enabled:" + enabled);}public void textValueChanged() {mediator.colleagueChanged();}}public class ColleagueCheckbox : IColleague {private IMediator mediator;private string caption;public ColleagueCheckbox(string caption) {this.caption = caption;}public void setMediator(IMediator mediator) {this.mediator = mediator;}public void setColleagueEnabled(bool enabled) {Console.WriteLine("enabled:" + enabled);}public void itemStateChanged() {mediator.colleagueChanged();}}public class LoginFrame : IMediator {private ColleagueButton button;private ColleagueCheckbox checkbox;private ColleagueTextField textField;public LoginFrame() {createColleagues();button.setMediator(this);checkbox.setMediator(this);textField.setMediator(this);                        }public void createColleagues() {button = new ColleagueButton("Button");checkbox = new ColleagueCheckbox("Checkbox");textField = new ColleagueTextField("TexField");            }public void colleagueChanged() {button.setColleagueEnabled(false);checkbox.setColleagueEnabled(false);textField.setColleagueEnabled(false);}}
}

View Code

Mediator 模式中的类图

相关的设计模式

  Facade模式  

    在Mediator模式中,Mediator角色与Colleague角色进行交互.

    而在Facade模式中,Facade角色单方面地使用其他角色来对外提供高层接口(API).因此,可以说Mediator模式是双向的,而Facade模式是单向的.

  Observer模式

    有时会使用Observer模式来实现Mediator角色与Colleague角色之间的通信

第8部分 管理状态

  第17章 Observer(观察者) 模式-发送状态变化通知

using System;
using System.Collections.Generic;
using System.Net;namespace Test1 {class Program {static void Main(string[] args) {NumberGenerator generator = new RandomNumberGenerator();Observer observer1 = new DigitObserver();Observer observer2 = new GraphObserver();generator.addObserver(observer1);generator.addObserver(observer2);generator.execute();}}public interface Observer {void update(NumberGenerator generator);}public class DigitObserver : Observer {public void update(NumberGenerator generator) {Console.WriteLine("DigitObserver:" + generator.getNumber());System.Threading.Thread.Sleep(100);}}public class GraphObserver : Observer {public void update(NumberGenerator generator) {Console.WriteLine("GraphObserver:");int count = generator.getNumber();for (int i = 0; i < count; i++) {Console.Write("*");}Console.WriteLine("");System.Threading.Thread.Sleep(100);}}public abstract class NumberGenerator {private List<Observer> observers = new List<Observer>();public void addObserver(Observer observer) {observers.Add(observer);   }public void deleteObserver(Observer observer) {observers.Remove(observer);}public void notifyObservers() {foreach (var item in observers) {item.update(this);}}public abstract int getNumber();public abstract void execute();}public class RandomNumberGenerator : NumberGenerator {private Random random = new Random();private int number;public override int getNumber() {return number;}public override void execute() {for (int i = 0; i < 20; i++) {number = random.Next(50);notifyObservers();}}}
}

View Code

Observer模式的类图

相关的设计模式

  Mediator模式

    在Mediator模式中,有时会使用Observer模式来实现Mediator角色与Colleague角色之间的通信

    就"发送状态变化通知"这一点而言,Mediator模式与Observer模式是类似的.不过,两种模式中,通知的目的和视角不同.

    在Mediator模式中,虽然也会发送通知,不过那不过是为了对Colleague角色进行仲裁而已.

    而在Observer模式中,将Subject角色的状态变化通知给Observer角色的目的则主要是为了使Subject角色和Observer角色同步.

  第18章 Memento(备忘录) 模式-保存对象状态

using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;namespace ConsoleApplication1 {public class Program {public static void Main(string[] args) {Gamer gamer = new Gamer(100);Memento memento = gamer.createMemento();for (int i = 0; i < 100; i++) {Console.WriteLine("===== " + i);Console.WriteLine("当前状态:" + gamer);gamer.bet();Console.WriteLine("所持金钱为:" + gamer.getMoney() + "元.");if (gamer.getMoney() > memento.getMoney()) {Console.WriteLine("    (所持金钱增加了许多,因此保存游戏当前的状态)");memento = gamer.createMemento();} else if (gamer.getMoney() < memento.getMoney() / 2) {Console.WriteLine("    (所持金钱减少了许多,因此将游戏恢复至以前的状态)");gamer.restoreMemento(memento);}}}}public class Memento {private int money;private ArrayList fruits;public Memento(int money) {this.money = money;this.fruits = new ArrayList();}public int getMoney() {return money;}public void addFruit(string fruit) {fruits.Add(fruit);}public ArrayList getFruits() {return (ArrayList)fruits.Clone();} }public class Gamer {private int money;private ArrayList fruits = new ArrayList();private Random random = new Random();private static string[] fruitsname = {"苹果","葡萄","香蕉","橘子"};public Gamer(int money) {this.money = money;}public int getMoney() {return money;}public void bet() {int dice = random.Next(6) + 1;if (dice == 1) {money += 100;Console.WriteLine("所持金钱增加了.");} else if (dice == 2) {money /= 2;Console.WriteLine("所持金钱减半了.");} else if (dice == 6) {string f = getFruit();Console.WriteLine("获得了水果(" + f + ").");fruits.Add(f);} else {Console.WriteLine("什么都没有发生");}}public Memento createMemento() {Memento m = new Memento(money);foreach (var item in fruits) {if (item.ToString().StartsWith("好吃的")) {m.addFruit(item.ToString());}}return m;}public void restoreMemento(Memento memento) {this.money = memento.getMoney();this.fruits = memento.getFruits();}public override string ToString() {var str = "[";foreach (var item in fruits) {str += item.ToString() + ",";}str += "]";return "[money = " + money + ", fruits = " + str;}private string getFruit() {string prefix = "";if (random.Next(2) == 1) {prefix = "好吃的";}return prefix + fruitsname[random.Next(fruitsname.Length)];}}}

View Code

Memento模式的类图

相关的设计模式

  Command模式

    在使用Command模式处理命令时,可以使用Memento模式实现撤销功能

  Prototype模式

    在Memento模式中,为了能够实现快照和撤销功能,保存了对象当前的状态.保存的信息只是在恢复状态时所需要的那部分信息.

    而在Prototype模式中,会生成一个与当前实例完全相同的另外一个实例.这两个实例的内容完全一样.

  State模式

    在Memento模式中,是用"实例"表示状态

    而在State模式中,则是用"类"表示状态

  第19章 State(状态) 模式-用类表示状态

State模式的类图

相关的设计模式

  Singleton模式

    Singleton模式常常会出现在ConcreteState角色中.

  Flyweight模式

    在表示状态的类中并没有定义任何实例字段.因此,有时我们可以使用Flyweight模式在多个Context角色之间共享ConcreteState角色

第9部分 避免浪费

  第20章 Flyweight(享元) 模式-共享对象,避免浪费

using System;
using System.Collections.Generic;
using System.Net;namespace Test2 {class Program {static void Main(string[] args) {BigString bs = new BigString("aascd");bs.print();}}public class BigChar {private char charname;private string fontdata;public BigChar(char charname) {this.charname = charname;fontdata = "#" + charname +"#";}public void print() {Console.WriteLine(fontdata);}}public class BigCharFactory {private Dictionary<char,BigChar> pool = new Dictionary<char, BigChar>();private static BigCharFactory singleton = new BigCharFactory();private BigCharFactory() {}public static BigCharFactory getInstance() {return singleton;}public BigChar getBigChar(char charname) {BigChar bc;if (!pool.TryGetValue(charname, out bc)) {bc = new BigChar(charname);}return bc;}}public class BigString {private BigChar[] bigchars;public BigString(string str) {bigchars = new BigChar[str.Length];BigCharFactory factory = BigCharFactory.getInstance();for (int i = 0; i < bigchars.Length; i++) {bigchars[i] = factory.getBigChar(str.ToCharArray()[i]);}}public void print() {for (int i = 0; i < bigchars.Length; i++) {bigchars[i].print();}}}
}

View Code

Flyweight模式的类图 

相关的设计模式

  Proxy模式

    如果生成实例的处理需要花费较长时间,那么使用Flyweight模式可以提高程序的处理速度.

    而Proxy模式则是通过设置代理提高程序的处理速度

  Composite模式

    有时可以使用Flyweight模式共享Composite模式中的Leaf角色

  Singleton模式

    在FlyweightFactory角色中有时会使用Singleton模式.

  第21章 Proxy(代理) 模式-只在必要时生成实例

using System;
using System.Collections.Generic;
using System.Net;namespace Test2 {class Program {static void Main(string[] args) {Printable p = new PrinterProxy("Alice");Console.WriteLine("现在的名字是" + p.getPrinterName() + ".");p.setPrinterName("Bob");Console.WriteLine("现在的名字是" + p.getPrinterName() + ".");p.print("Hello,world");}}public interface Printable {void setPrinterName(string name);string getPrinterName();void print(string str);}public class Printer : Printable {private string name;public Printer() {heavyJob("正在生成Printer实例");}public Printer(string name) {this.name = name;heavyJob("正在生成Printer的实例(" + name +")");}public void setPrinterName(string name) {this.name = name;}public string getPrinterName() {return name;}public void print(string str) {Console.WriteLine("=== " + name + " ===");Console.WriteLine(str);}private void heavyJob(string msg) {Console.WriteLine(msg);for (int i = 0; i < 5; i++) {System.Threading.Thread.Sleep(1000);Console.Write(".");}Console.WriteLine("结束.");}}public class PrinterProxy : Printable {private string name;private Printer real;public PrinterProxy() {}public PrinterProxy(string name) {this.name = name;}public void setPrinterName(string name) {if (real != null) {real.setPrinterName(name);}this.name = name;}public string getPrinterName() {return name;}public void print(string str) {realize();real.print(str);}private void realize() {if (real == null) {real = new Printer(name);}}}
}

View Code

Proxy模式的类图

相关的设计模式

  Adapter模式

    Adapter模式适配了两种具有不同接口(API)的对象,以使它们可以一同工作.

    而在Proxy模式中,Proxy角色与RealSubject角色的接口(API)是相同的(透明性)

  Decorator模式

    Decorator模式与Proxy模式在实现上很相似,不过它们的使用目的不同.

    Decorator模式的目的在于增加新的功能.而在Proxy模式中,与增加新功能相比,它更注重通过设置代理人的方式来减轻本人的工作负担

第10部分 用类来表现

  第22章 Command(命令) 模式-命令也是类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Threading;namespace Test2 {class Program {static void Main(string[] args) {MacroCommand history = new MacroCommand();Drawable draw = new DrawCanvas(400,400,history);Command cmd = new DrawCommand(draw, new Point(50, 50));history.append(cmd);cmd.execute();}}public interface Command {void execute();}public class MacroCommand : Command {private Stack<Command> commands = new Stack<Command>();public void execute() {commands.Pop().execute();foreach (var item in commands) {item.execute();}}public void append(Command command) {if (command != this) {commands.Push(command);}}public void undo() {if (commands.Count != 0) {commands.Pop();} }public void clear() {commands.Clear();}}public class DrawCommand : Command {protected Drawable drawable;private Point position;public DrawCommand(Drawable drawable, Point position) {this.drawable = drawable;this.position = position;}public void execute() {drawable.draw(position.X,position.Y);}}public interface Drawable {void draw(int x, int y);}public class DrawCanvas : Drawable {private int radius = 6;private MacroCommand history;public DrawCanvas(int width, int height, MacroCommand history) {this.history = history;}public void paint() {history.execute();;}public void draw(int x, int y) {Console.WriteLine("Draw X:" + x + ", Y:" + y);}}
}

View Code

Command模式的类图

相关的设计模式

  Composite模式

    有时会使用Composite模式实现宏命令(macrocommand)

  Memento模式

    有时会使用Memento模式来保存Command角色的历史记录

  Prototype模式

    有时会使用Prototype模式复制发生的事件(生成的命令)

  第23章 Interpreter(解释器) 模式-语法规则也是类

Interpreter模式的类图

相关的设计模式

  Composite模式

    NonterminalExpression角色多是递归结构,因此常会使用Composite模式来实现NonterminalExpression角色.

  Flyweight模式

    有时会使用Flyweight模式来共享TerminalExperssion角色

  Visitor模式

    在推导出语法树后,有时会使用Visitor模式来访问语法树的各个节点

转载于:https://www.cnblogs.com/revoid/p/6719867.html

图解设计模式 (结城浩 著)相关推荐

  1. 结城浩 java_JAVA多线程设计模式 结城浩著 PDF下载

    <JAVA多线程设计模式>中包含JAVA线程的介绍导读,12个重要的线程设计模式和全书总结以及丰富的附录内容.每一章相关线程设计模式的介绍,都举一反三使读者学习更有效率.最后附上练习问题, ...

  2. 知名著者结城浩:坚持做一件事而不厌倦,一旦厌倦马上更换目标

    非商业转载请注明作译者.出处,并保留本文的原始链接:http://www.ituring.com.cn/article/216181 结城浩(Hiroshi Yuki),1963年出生,居住于东京都武 ...

  3. 结城浩《图解设计模式》笔记

    文章目录 Prototype模式 示例程序 源代码 Builder模式 示例程序 源代码 Abstract Factory模式 示例程序 源代码 文章地址 前五个设计模式 Prototype模式 通过 ...

  4. 结城浩的《图解设计模式》设计模式之Adapter模式的理解

    书中举的电源适配器的例子,还有网上各种同类的例子,无法说服我. Banner类的两个方法,代表输出交流100伏,虽然外部调用的是Print接口的要输出12伏特的方法,但是实际还是调用PrintBann ...

  5. 阅读笔记-《图解密码技术》(日)结城浩

    第1章    环游密码世界 加密和解密 加密之前的消息称为明文(plaintest),加密之后的消息称为密文(ciphertext). 正当的接收者将密文还原为明文称为"解密",但 ...

  6. 《图解密码技术》(第三版)结城浩-知识结构整理

    由于是自己的整理的,有些地方直接略过了,上图,图链接,密码15df.  

  7. 结城浩所著《数学女孩3:哥德尔不完备定理》读书笔记

    一.哥德尔编码的奥秘 哥德尔编码建立了自然数与形式系统的映射关系,形式系统可以引用这些映射的自然数参与形式系统计算,从而在看似牢不可破的形式系统中引入了自我指涉的隐患. #mermaid-svg-T2 ...

  8. 解密码技术(结城浩)概括

    对称密码:加密和解密使用同一密钥的方式 公钥密码:加密和解密使用不同密钥.

  9. 程序员的数学【结城浩】学习笔记(1-3章)0的故事,逻辑,余数

    一,0的故事     计算机为什么用2值表示?   开关链通和断开的状态     进制的转换: 将数字反复除以2,将每步所得的余数的 列逆序排列,得到二进制的表示 指数法则: 10的0次方,2的0次方 ...

最新文章

  1. 【模板】树链剖分 P3384
  2. Excel 2010 下拉菜单的制作方法
  3. poj1797Heavy Transportation最大生成树
  4. 如何在Clion中使用C++调用Python代码
  5. 【渝粤教育】 广东开放大学 21秋期末考试物业环境与秩序管理10122k2
  6. (转)Hibernate框架基础——cascade属性
  7. 500万人“动口”收蚂蚁森林能量!天猫精灵发布语音“云种树”报告
  8. html 居中 center,html – 如何居中的元素 – 使用什么而不是align:center属性?
  9. 冬季宝宝不着凉有绝招
  10. FLEX4中的Panel如何实现带自定义图标和按钮
  11. transactional replication 的immediate_sync属性
  12. oracle的即时客户端,安装oracle即时客户端
  13. OpenSesame免费提供新冠病毒防疫准备和远程工作培训
  14. Microsoft Word 2010 - 清除格式
  15. Linux-Kali——解决Gnome桌面右键菜单无法打开terminal终端的问题
  16. 【字符串匹配】BF算法
  17. 超强锁SuperPro
  18. labuladong 公众号的使用方法
  19. 工具传送门(持续更新)
  20. 土地估价师继续教育培训心得体会

热门文章

  1. 牛客白月赛26【题解】
  2. 前端路由vue-router
  3. 东华大学计算机专业导论考试,【东华大学】学姐考研经验,设计素描和艺术设计概论初试如何准备...
  4. C++中的取余(rem)与取模(mod), 与实现fix函数
  5. antv x6自定义节点(使用vue渲染节点)
  6. 语音中的响度,音调与音色的决定因素
  7. 使用 Docker 运行 SQL Server 容器映像 在Windows操作系统上,重设置密码和操作数库
  8. 想封谁QQ,就封谁QQ
  9. java 检查bytebuf长度_Netty实战五之ByteBuf
  10. python编程简易打字评分小游戏