前言 以前粗略的看过设计模式,有的看懂了,有的没看懂,有的看懂了又忘了,有的在写程序时已不知不觉在用了. 总之,现在从头学习一遍,并且开始做笔记,这样记的牢。 以后写程序也要有意识的向设计模式靠拢。 那本经典的《设计模式》准备去买一本,一共有23种设计模式,这里我先研究了5种,后面争取都研究完,例子是C#的,不过对于C++、java、delphi应该都是适用的。 欢迎大家和我讨论!
目录 1.singleton 2.strategy 3.Decorator 4.composite 5.state
1.Singleton 说明:保证类只有一个实例。 实例: using System; class Singleton { private static Singleton singleton = null; public static Singleton Instance() { if (null == singleton) singleton = new Singleton(); return singleton; }
private Singleton() { } }
class Application { public static void Main() { Singleton s1 = Singleton.Instance(); //Singleton s2 = new Singleton(); //错误:构造器不可访问 Singleton s2 = Singleton.Instance(); if (s1.Equals(s2)) // 引用相等 Console.WriteLine("Instances are identical"); } }
/*以下是程序输出结果: Instances are identical */
2.strategy 说明:利用接口实现方法无关化,客户程序同特定算法实现细节毫无耦合关系。 实例: using System;
namespace strategy1 { /// <summary> /// Summary description for Class. /// </summary> interface Strategy { bool IsPrime(int n); }
class Miller : Strategy { public bool IsPrime(int n){ bool result = false; //使用Miller法测试n是否为素数,果真,则更新result值 Console.WriteLine("Using Miller's algorithm"); return result; } }
class Fermat : Strategy { public bool IsPrime(int n){ bool result = false; //使用Fermat法测试n是否为素数,果真,则更新result值 Console.WriteLine("Using Fermat's algorithm"); return result; } }
class Mersenne : Strategy { public bool IsPrime(int n) { bool result = false; //使用Mersenne法测试n是否为素数,果真,则更新result值 Console.WriteLine("Using Mersenne's algorithm"); return result; } }
class Primality { private Strategy strategy;
public Primality(Strategy s) { strategy = s; } public bool Test(int n) { return strategy.IsPrime(n); } }
class Class { [STAThread] static void Main(string[] args) { Console.Write("Number to be tested: "); string input = Console.ReadLine(); int n = Int32.Parse(input); Console.Write("Desired algorithm performance: lo, medium, hi? "); input = Console.ReadLine(); char ch = char.Parse(input); Primality prime = null; switch (ch) { case 'l': case 'L': prime = new Primality(new Miller()); break;
case 'm': case 'M': prime = new Primality(new Fermat()); break;
case 'h': case 'H': prime = new Primality(new Mersenne()); break; }
if (prime != null) { bool result = prime.Test(n); } else Console.WriteLine("Bad Choice!");
Console.ReadLine(); }
}
}
/*以下是某次测试输出结果: Number to be tested:1 Desired algorithm performance: lo, medium, hi? M Using Fermat's algorithm */
3.Decorator 说明:通过子类实现功能的灵活扩展。 实例: using System;
namespace decortation { /// <summary> /// Summary description for Class. /// </summary>
class FileTransfer { public virtual void Download(string url, byte[] data, int size) { // 下载文件 } public virtual void Upload(string url, byte[] data, int size) { // 上传文件 } }
class Decorator : FileTransfer { private FileTransfer ft = new FileTransfer(); private bool IsAccessAllowed(string url) { bool result = true; // 决定是否对请求的URL访问授权 return result; }
private void LogAccess(string url) { // 将URL、时间、用户身份等信息写入数据库 Console.WriteLine("Logging access to {0}", url); }
public override void Download(string url, byte[] data, int size) { if (!IsAccessAllowed(url)) return; ft.Download(url, data, size); LogAccess(url); }
public override void Upload(string url, byte[] data, int size) { if (!IsAccessAllowed(url)) return; ft.Upload(url, data, size); LogAccess(url); } }
class Class { public static void Main() { Console.Write("Enter URL to access: "); string url = Console.ReadLine(); Console.Write("Enable logging and access check? "); string input = Console.ReadLine(); char ch = char.Parse(input); bool decoration = (ch == 'y' || ch == 'Y'); FileTransfer ft = null; if (!decoration) ft = new FileTransfer(); else ft = new Decorator(); byte[] buf = new byte[1024]; ft.Download(url, buf, 1024); } }
}
4.composite 说明:利用接口达到用一致的方式来访问所有对象(这个很常用的)。 实例: C#示例: using System; using System.Collections; interface Shape { void Draw(); } class Line : Shape { private double x1, y1, x2, y2; public Line(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } public void Draw() { //从(x1, y1) 到(x2, y2)画一条线 Console.WriteLine("Drawing a line"); } } class Circle : Shape { private double x, y, r; public Circle(double x, double y, double radius) { this.x = x; this.y = y; this.r = r; } public void Draw() { //以(x, y)为圆心,r为半径画一个圆 Console.WriteLine("Drawing a circle"); } } class Drawing : Shape { private ArrayList shapes; public Drawing() { shapes = new ArrayList(); } public void Add(Shape s) { shapes.Add(s); } public void Draw() { IEnumerator enumerator = shapes.GetEnumerator(); while (enumerator.MoveNext()) ((Shape) enumerator.Current).Draw(); } } class Application { public static void Main() { Shape[] array = new Shape[3]; array[0] = new Line(0, 0, 10, 12); array[1] = new Circle(2, 3, 5.5); Drawing dwg = new Drawing(); dwg.Add(new Line(3, 4, 3, 5)); dwg.Add(new Circle(5, 6, 7.7)); array[2] = dwg; // 画出所有的图形,注意:用一致的方式来访问所有对象 for (int i = 0; i < 3; ++i) array[i].Draw(); } } /*以下是程序输出结果: Drawing a line Drawing a circle Drawing a line Drawing a circle */
5.state 说明:当对象内部状态改变时自动改变它的行为。
实例: 这个实例比较长,我简单说明一下,这是一个自动售货机的例子,客户可以投掷面值5、10、25的硬币,货物价值25。每当客户投了硬币就打印投的钱数和,如果够了25,就提示货物售出。 state是个抽象类,它派生了5、10、15、20、25几种钱数和的类(也就是所有可能的钱数和),由于它们都是从STATE继承的,所以它们都有一个STATE类型的静态成员state作为状态的标识(你可以把它想象成全局变量),每个类都接收投入5、10、25面值的硬币,对应的方法是 public virtual void AddNickel(VendingMachine vm) { } public virtual void AddDime(VendingMachine vm) { } public virtual void AddQuarter(VendingMachine vm) { } 虽然方法一样,但是每个类内部实现的状态跃迁是不一样的,比如5元的类,接收10元后state就跃迁到了15元,以此类推。 仔细看看吧,这是一个非常有意思的实例。不过说实话,这样实现程序确实太累了,也许在别的应用中可以降低程序员的负担,不过我还没发现(有的话告诉我)。 另外如果有100种状态,有10种路径,难道每个状态都要继承(100×10)?那coding起来岂不是太累,而且代码不要太长啊,唉,当程序员真不容易啊...
using System;
abstract class State
{
public virtual void AddNickel(VendingMachine vm) { }
public virtual void AddDime(VendingMachine vm) { }
public virtual void AddQuarter(VendingMachine vm) { }
protected virtual void ChangeState(VendingMachine vm, State s)
{
vm.ChangeState(s);
}
}
class VendingMachine
{
private State state;
public VendingMachine()
{
Console.WriteLine("The Vending Machine is now online: product costs 25c");
state = Start.Instance();
}
public void ChangeState(State to)
{
state = to;
}
public void Vend()
{
// 发饮料
Console.WriteLine("Dispensing product...Thank you!");
}
public void AddNickel()
{
state.AddNickel(this);
}
public void AddDime()
{
state.AddDime(this);
}
public void AddQuarter()
{
state.AddQuarter(this);
}
}
class Start : State
{
private static State state = new Start();
private Start()
{
}
public static State Instance()
{
// singleton逻辑
Console.WriteLine("Credit: 0c");
return state;
}
public override void AddNickel(VendingMachine vm)
{
ChangeState(vm, Five.Instance());
}
public override void AddDime(VendingMachine vm)
{
ChangeState(vm, Ten.Instance());
}
public override void AddQuarter(VendingMachine vm)
{
vm.Vend();
}
}
class Five : State
{
private static State state = new Five();
private Five()
{
}
public static State Instance()
{
// singleton 逻辑
Console.WriteLine("Credit: 5c");
return state;
}
public override void AddNickel(VendingMachine vm)
{
ChangeState(vm, Ten.Instance());
}
public override void AddDime(VendingMachine vm)
{
ChangeState(vm, Fifteen.Instance());
}
public override void AddQuarter(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance()); // no change returned :-)
}
}
class Ten : State
{
private static State state = new Ten();
private Ten()
{
}
public static State Instance()
{
// singleton 逻辑
Console.WriteLine("Credit: 10c");
return state;
}
public override void AddNickel(VendingMachine vm)
{
ChangeState(vm, Fifteen.Instance());
}
public override void AddDime(VendingMachine vm)
{
ChangeState(vm, Twenty.Instance());
}
public override void AddQuarter(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance()); // no change returned :-)
}
}
class Fifteen : State
{
private static State state = new Fifteen();
private Fifteen()
{
}
public static State Instance()
{
// singleton 逻辑
Console.WriteLine("Credit: 15c");
return state;
}
public override void AddNickel(VendingMachine vm)
{
ChangeState(vm, Twenty.Instance());
}
public override void AddDime(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance());
}
public override void AddQuarter(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance()); // no change returned :-)
}
}
class Twenty : State
{
private static State state = new Twenty();
private Twenty()
{
}
public static State Instance()
{
// singleton 逻辑
Console.WriteLine("Credit: 20c");
return state;
}
public override void AddNickel(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance());
}
public override void AddDime(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance());
}
public override void AddQuarter(VendingMachine vm)
{
vm.Vend();
ChangeState(vm, Start.Instance()); // no change returned :-)
}
}
class Application
{
public static void Main()
{
int coin = 0;
string input = null;
VendingMachine vm = new VendingMachine();
while (true)
{
Console.Write("Insert a coin (5, 10, 25): ");
input = Console.ReadLine();
coin = Int32.Parse(input);
switch (coin)
{
case 5:
vm.AddNickel();
break;
case 10:
vm.AddDime();
break;
case 25:
vm.AddQuarter();
break;
default:
break;
}
}
}
}
/*以下是某次运行时输出结果:
The Vending Machine is now online: product costs 25c
Credit: 0c
Insert a coin <5, 10, 25>: 5
Credit: 5c
Insert a coin <5, 10, 25>: 10
Credit: 15c
Insert a coin <5, 10, 25>: 5
Credit: 20c
Insert a coin <5, 10, 25>: 5
Dispensing product...Thank you!
*/

|