【序】
设计模式学到这小编唯有总结才能抒发内心的兴奋,23个设计模式中分为三个类别,在本文中小编只是挑出了一类创建型模式来总结。
【正文】
创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建,组合和表示他的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。
· 它们都将关于该系统使用哪些具体的类的信息封装起来。
· 它们隐藏了这些类的实例是如何被创建和放在一起的。整个系统关于这些对象所知道方法的是由抽象类所定义的接口。
单例模式
单例模式(饿汉模式):保证一个类仅有一个实例,并提供一个访问他的全局访问点。
举例:对MDI窗体点击多次出现的多个“工具箱”进行“计划生育”。
模式基本代码:
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2)
{
Console.WriteLine("Objects are the same instance");
}
Console.Read();
}
}
class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
总结:单例模式是为了控制在运行期间,某些类的实例数目只能有一个。如果你想要控制多个,可以利用 Map 来帮助缓存多个实例。
工厂方法模式
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。
举例:做雷锋不需要知道真实姓名, 只要封装好谁做好事都一样。做的好事都在工厂里进行,降低了耦合。
模式基本代码:
public class Complex
{
public double real;
public double imaginary;
public static Complex fromCartesianFactory(double real, double imaginary )
{
return new Complex(real, imaginary);
}
public static Complex fromPolarFactory(double modulus , double angle )
{
return new Complex(modulus * Math.Cos(angle), modulus * Math.Sin(angle));
}
private Complex (double a, double b)
{
real = a;
imaginary = b;
}
}
Complex product = Complex.fromPolarFactory(1,pi);
总结:下列情况可以考虑使用工厂方法模式:
· 创建对象需要大量重复的代码。
· 创建对象需要访问某些信息,而这些信息不应该包含在复合类中。
· 创建对象的生命周期必须集中管理,以保证在整个程序中具有一致的行为。
抽象工厂模式
抽象工厂模式:提供一个创建一系列或相关依赖对象的接口,而无需指定他们具体的类。
举例:、
模型基本代码:
class Program
{
static void Main(string[] args)
{
AbstractFactory factory1 = new ConcreteFactory1();
Client c1 = new Client(factory1);
c1.Run();
AbstractFactory factory2 = new ConcreteFactory2();
Client c2 = new Client(factory2);
c2.Run();
Console.Read();
}
}
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
abstract class AbstractProductA
{
}
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
class ProductA1 : AbstractProductA
{
}
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
class ProductA2 : AbstractProductA
{
}
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
class Client
{
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
public void Run()
{
AbstractProductB.Interact(AbstractProductA);
}
}
总结:
·一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
·系统中有多于一个的产品族,而每次只使用其中某一产品族。
·属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
·系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
建造者模式
建造者模式:将一个复杂对象的构建与它的表示分离。
举例:
模式基本代码:
class Program
{
static void Main(string[] args)
{
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
director.Construct(b1);
Product p1 = b1.GetResult();
p1.Show();
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
Console.Read();
}
}
class Director
{
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
abstract class Builder
{
public abstract void BuildPartA();
public abstract void BuildPartB();
public abstract Product GetResult();
}
class ConcreteBuilder1 : Builder
{
private Product product = new Product();
public override void BuildPartA()
{
product.Add("部件A");
}
public override void BuildPartB()
{
product.Add("部件B");
}
public override Product GetResult()
{
return product;
}
}
class ConcreteBuilder2 : Builder
{
private Product product = new Product();
public override void BuildPartA()
{
product.Add("部件X");
}
public override void BuildPartB()
{
product.Add("部件Y");
}
public override Product GetResult()
{
return product;
}
}
class Product
{
IList<string> parts = new List<string>();
public void Add(string part)
{
parts.Add(part);
}
public void Show()
{
Console.WriteLine("\n产品 创建 ----");
foreach (string part in parts)
{
Console.WriteLine(part);
}
}
}
总结:建造者模式可以将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。也就是说如果我们用了建造者模式,那么用户就需要指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。
原型模式
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
举例:更改简历,先把简历实例化,再利用浅复制和神复制。
模式基本代码:
class Program
{
static void Main(string[] args)
{
ConcretePrototype1 p1 = new ConcretePrototype1("I");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Cloned: {0}", c1.Id);
ConcretePrototype2 p2 = new ConcretePrototype2("II");
ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
Console.WriteLine("Cloned: {0}", c2.Id);
// Wait for user
Console.Read();
}
}
abstract class Prototype
{
private string id;
// Constructor
public Prototype(string id)
{
this.id = id;
}
// Property
public string Id
{
get { return id; }
}
public abstract Prototype Clone();
}
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id)
: base(id)
{
}
public override Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
class ConcretePrototype2 : Prototype
{
// Constructor
public ConcretePrototype2(string id)
: base(id)
{
}
public override Prototype Clone()
{
// Shallow copy
return (Prototype)this.MemberwiseClone();
}
}
总结:
· Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。
· Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来实现,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
· Prototype模式中的Clone方法可以利用Object类的MemberwiseClone()或者序列化来实现深拷贝。
---参考 大话设计模式 程杰