再设计模式的23个模式中一共分为大三类: 创建型模式,结构型模式,行为型模式。
今天我们主要学习创建型模式:创建型模式一共包含五个模式,其中“工厂模式”和“抽象工厂模式”已经在上一篇“工厂三姐妹”中介绍过,所以本篇就不再重复介绍。
单例模式:
在它的核心结构中只包含一个被称为单例类的特殊类,该模式的目的是使得类的一个对象成为系统中的唯一实例
如何保证一个类只能有一个实例并且这个实例容易被访问?
1.确保一个类只有一个实例 ,通过私有构造函数来保证类外部不能对类进行实例化
2.在类定义中含有一个该类的静态私有对象
3.该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
代码如下:
/// <summary>
/// 单例模式的实现
/// </summary>
public class Singleton
{
// 定义一个静态变量来保存类的实例
private static Singleton uniqueInstance;
// 定义私有构造函数,使外界不能创建该类实例
private Singleton()
{
}
/// <summary>
/// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
/// </summary>
/// <returns></returns>
public static Singleton GetInstance()
//该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象
{
// 如果类的实例不存在则创建,否则直接返回
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
2.建造者模式:
在建造者模式中,指挥者是直接与客户端打交道的
建造者模式主要用于“分步骤来构建一个复杂的对象
前面的抽象工厂模式解决了“系列产品的”需求,而建造者模式解决的是“产品部分”的需求
{
/// 以组装电脑为例子
/// 每台电脑的组成过程都是一致的,但是使用同样的构建过程可以创建不同的表示(即可以组装成不一样的电脑,配置不一样)
/// 组装电脑的这个场景就可以应用建造者模式来设计
/// <summary>
/// 客户类
/// </summary>
class Customer
{
static void Main(string[] args)
{
// 客户找到电脑城老板说要买电脑,这里要装两台电脑
// 创建指挥者和构造者
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
// 老板叫员工去组装第一台电脑
director.Construct(b1);
// 组装完,组装人员搬来组装好的电脑
Computer computer1 = b1.GetComputer();
computer1.Show();
// 老板叫员工去组装第二台电脑
director.Construct(b2);
Computer computer2 = b2.GetComputer();
computer2.Show();
Console.Read();
}
}
/// <summary>
/// 小王和小李难道会自愿地去组装嘛,谁不想休息的,这必须有一个人叫他们去组装才会去的
/// 这个人当然就是老板了,也就是建造者模式中的指挥者
/// 指挥创建过程类
/// </summary>
public class Director
{
// 组装电脑
public void Construct(Builder builder)
{
builder.BuildPartCPU();
builder.BuildPartMainBoard();
}
}
/// <summary>
/// 电脑类
/// </summary>
public class Computer
{
// 电脑组件集合
private IList<string> parts = new List<string>();
// 把单个组件添加到电脑组件集合中
public void Add(string part)
{
parts.Add(part);
}
public void Show()
{
Console.WriteLine("电脑开始在组装.......");
foreach (string part in parts)
{
Console.WriteLine("组件"+part+"已装好");
}
Console.WriteLine("电脑组装好了");
}
}
/// <summary>
/// 抽象建造者,这个场景下为 "组装人" ,这里也可以定义为接口
/// </summary>
public abstract class Builder
{
// 装CPU
public abstract void BuildPartCPU();
// 装主板
public abstract void BuildPartMainBoard();
// 当然还有装硬盘,电源等组件,这里省略
// 获得组装好的电脑
public abstract Computer GetComputer();
}
/// <summary>
/// 具体创建者,具体的某个人为具体创建者,例如:装机小王啊
/// </summary>
public class ConcreteBuilder1 : Builder
{
Computer computer = new Computer();
public override void BuildPartCPU()
{
computer.Add("CPU1");
}
public override void BuildPartMainBoard()
{
computer.Add("Main board1");
}
public override Computer GetComputer()
{
return computer;
}
}
/// <summary>
/// 具体创建者,具体的某个人为具体创建者,例如:装机小李啊
/// 又装另一台电脑了
/// </summary>
public class ConcreteBuilder2 : Builder
{
Computer computer = new Computer();
public override void BuildPartCPU()
{
computer.Add("CPU2");
}
public override void BuildPartMainBoard()
{
computer.Add("Main board2");
}
public override Computer GetComputer()
{
return computer;
}
}
}
3.原型模式:
当我们需要多个相同的类实例时,没必要每次都使用new运算符去创建相同的类实例对象,此时我们的一般思路就是想---只创建一个类实例对象,如果后面
需要更多的这样的实例,可以通过对原来对象拷贝一份来完成创建
如:细胞的分裂,西游记中孙悟空变出很多子孙
class Client
{
static void Main(string[] args)
{
// 孙悟空 原型
MonkeyKingPrototype prototypeMonkeyKing = new ConcretePrototype("MonkeyKing");
// 变一个
MonkeyKingPrototype cloneMonkeyKing = prototypeMonkeyKing.Clone() as ConcretePrototype;
Console.WriteLine("Cloned1:\t"+cloneMonkeyKing.Id);
// 变两个
MonkeyKingPrototype cloneMonkeyKing2 = prototypeMonkeyKing.Clone() as ConcretePrototype;
Console.WriteLine("Cloned2:\t" + cloneMonkeyKing2.Id);
Console.ReadLine();
}
}
/// <summary>
/// 孙悟空原型
/// </summary>
public abstract class MonkeyKingPrototype
{
public string Id { get; set; }
public MonkeyKingPrototype(string id)
{
this.Id = id;
}
// 克隆方法,即孙大圣说“变”
public abstract MonkeyKingPrototype Clone();
}
/// <summary>
/// 创建具体原型
/// </summary>
public class ConcretePrototype : MonkeyKingPrototype
{
public ConcretePrototype(string id)
: base(id)
{ }
/// <summary>
/// 浅拷贝
/// </summary>
/// <returns></returns>
public override MonkeyKingPrototype Clone()
{
// 调用MemberwiseClone方法实现的是浅拷贝,另外还有深拷贝
return (MonkeyKingPrototype)this.MemberwiseClone();
}
}