第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模式的类图