Tag Archives: 设计模式

设计模式 — Builder

上下文:一个产品有 n 个零件,通过构建产品的不同部分来生产不同的产品。

解决方法:将一个产品的不同部件交由某个构建者的不同方法来实现,然后导演通过调用不同的方法,构建出不同的产品。
using System;

namespace Builder {
///

/// 产品,其中包括两个部件
///

public class Product {
string part1 = string.Empty;
string part2 = string.Empty;

public string Part1 {
get { return part1; }
set { part1 = value; }
}

public string Part2 {
get { return part2; }
set { part2 = value; }
}
}

///

/// 构建者的接口标准
///

public interface IBuilder {
void BuildPart1();
void BuildPart2();
Product RetrieveProduct { get; }
}

///

/// 从接口派生出具体的构建者
///

public class ConcreteBuilder:IBuilder {
Product myProduct = new Product();

#region IBuilder 成员
public void BuildPart1() {
// TODO: 添加 ConcreteBuilder.BuildPart1 实现
myProduct.Part1 = “Part1 has been built!”;
}

public void BuildPart2() {
// TODO: 添加 ConcreteBuilder.BuildPart2 实现
myProduct.Part2 = “Part2 has been built!”;
}

public Product RetrieveProduct {
get {
// TODO: 添加 ConcreteBuilder.RetrieveProduct getter 实现
return myProduct;
}
}
#endregion
}

///

/// 导演通过调用具体构建者的不同构建方法,构建不同的部件,进而行成不同的产品
/// 该导演生产了这样的三种产品
/// 1、具有零件 1 和 2 的产品
/// 2、只具有零件 1 的产品
/// 3、只具有零件 2 的产品
///

public class Director {
Product product1, product2, product3;

public Product Product1 {
get { return product1; }
}
public Product Product2 {
get { return product2; }
}
public Product Product3 {
get { return product3; }
}

public Director() { }

public void Construct() {
ConcreteBuilder myCB1 = new ConcreteBuilder();
myCB1.BuildPart1();
myCB1.BuildPart2();
product1 = myCB1.RetrieveProduct;

ConcreteBuilder myCB2 = new ConcreteBuilder();
myCB2.BuildPart1();
product2 = myCB2.RetrieveProduct;

ConcreteBuilder myCB3 = new ConcreteBuilder();
myCB3.BuildPart2();
product3 = myCB3.RetrieveProduct;
}
}

///

/// 测试 Builder 模式
///

class TestBuilder {
///

/// 应用程序的主入口点。
///

[STAThread]
static void Main(string[] args) {
Director myDirector = new Director();
myDirector.Construct();
Console.WriteLine(myDirector.Product1.Part1);
Console.WriteLine(myDirector.Product1.Part2);
Console.WriteLine(myDirector.Product2.Part1);
Console.WriteLine(myDirector.Product2.Part2);
Console.WriteLine(myDirector.Product3.Part1);
Console.WriteLine(myDirector.Product3.Part2);

Console.Read();
}
}
}

设计模式 — ProtoType

问题:当我们在编写大型应用程序的时候,可能会遇到这样的情况:构造了一个基类,然后从该基类派生出子类。在子类的数目比较少的情况下,没有任何事情会发 生,但是如果当从某一个基类派生出的子类达到一定数目的时候,维护这些子类将是一件非常繁复的工作。

解决方案:既然如此,干脆就不派生子类。无论如何,子类都是具有特性的基类的衍生,我们可以将这种特性直接在基类中反映出来。具体说来,就是实现不同种类的克隆。

方法:传递进相关特性的参数,得到具有该特性的对象。

其它:本示例代码以 C# 为示例语言,通过实现 ICloneable 和 ISerializable 来实现对象的浅表复制 (Shallow copy) 和深层复制 (Deep copy) 。这同时也是学习序列化的很好的演示示例。

附件:一个 XML 文档:
< ?xml version="1.0" encoding="utf-8" ?>


Rui
Tang


Lichao
Mu

using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace ProtoType {
///

/// 用于存储每个员工的基本信息
///

public class Employee {
private string firstName;
private string lastName;

public string FirstName {
get { return this.firstName; }
set { this.firstName = value; }
}

public string LastName {
get { return this.lastName; }
set { this.lastName = value; }
}

///

/// 默认构造函数
///

public Employee() { }

///

/// 从序列化信息中得到数据
///

/// 序列化信息
/// /// 序列化信息中字典的索引
public Employee(SerializationInfo info, StreamingContext context, int index) {
this.firstName = info.GetString(“emp_fname” + index.ToString());
this.lastName = info.GetString(“emp_lname” + index.ToString());
}

///

/// 将数据添加到序列化信息中
///

/// 序列化信息
/// /// 序列化信息中字典的索引
public void GetObjectData(SerializationInfo info, StreamingContext context, int index) {
o.AddValue(“emp_fname” + index.ToString(), firstName);
info.AddValue(“emp_lname” + index.ToString(), lastName);
}
}

///

/// 处理员工信息的类
///

[Serializable]
public class EmployeeProcess : ICloneable,ISerializable {
///

/// 存储所有的员工
///

private ArrayList employeeArray = new ArrayList();

///

/// 默认构造函数,读取XML文档,并将员工添加到employeeArray中
///

public EmployeeProcess() {
XmlDocument xmlDoc = new XmlDocument();
Employee objEmp = null;

xmlDoc.Load(“Employees.xml”);
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) {
objEmp = new Employee();
objEmp.FirstName = node.SelectSingleNode(“FirstName”).InnerText;
objEmp.LastName = node.SelectSingleNode(“LastName”).InnerText;
employeeArray.Add(objEmp);
}
}

///

/// 反序列化必须要实现的一个方法,用于在反序列化时构造对象
///

/// 序列化信息
/// public EmployeeProcess(SerializationInfo info, StreamingContext context) {
int count;
string temp = string.Empty;
Employee objEmp = null;

count = int.Parse(info.GetValue(“emp_count”,temp.GetType()).ToString());
for (int i=0; i /// 实现浅表复制的克隆方法
///
/// 返回对象的引用
public object Clone() {
try { return this; }
catch (Exception exce) {
Console.WriteLine(exce.Message);
return null;
}
}

///

/// 实现深层复制的克隆方法
///

/// 判断是否请求深层复制的标志量
/// 返回对象的深层副本
public object Clone(bool isDeep) {
try {
if (isDeep) { return CreateDeepCopy(); }
else { return this.Clone(); }
} catch (Exception exce) {
Console.WriteLine(exce.Message);
return null;
}
}

///

/// 序列化必须要实现的一个方法,将数据写到序列化信息中
///

/// 序列化信息
/// public void GetObjectData(SerializationInfo info, StreamingContext context) {
Employee objEmp;
info.AddValue(“emp_count”,employeeArray.Count);
for (int i=0; i /// 枚举所有员工的信息
///
/// 员工信息
public string GetEmployeeInfo() {
string strEmpData = string.Empty;
for (int i=0; i
/// 改变员工信息,用于测试深层复制和浅表复制的异同
///
public void ChangeEmployeeInfo() {
foreach (Employee objEmp in employeeArray) {
objEmp.FirstName = “FirstName”;
objEmp.LastName = “LastName”;
}
}

///

/// 通过序列化创建对象的深层副本
///

/// 返回对象的深层副本
private EmployeeProcess CreateDeepCopy() {
EmployeeProcess objEmpCopy;
Stream objStream;
BinaryFormatter objBinFormatter = new BinaryFormatter();

try {
objStream = File.Open(“Employees.bin”,FileMode.Create);
objBinFormatter.Serialize(objStream, this);
objStream.Close();

objStream = File.Open(“Employees.bin”,FileMode.Open);
objEmpCopy = (EmployeeProcess)objBinFormatter.Deserialize(objStream);
objStream.Close();

return objEmpCopy;
} catch (Exception exce) {
Console.WriteLine(exce.Message);
return null;
}
}
}

///

/// 测试ProtoType
///

class TestProtoType {
[STAThread]
static void Main(string[] args) {
//用正常的方法创建一个对象
EmployeeProcess mainEmployeeProcess = new EmployeeProcess();
//输出该对象的信息
Console.WriteLine(mainEmployeeProcess.GetEmployeeInfo());

//通过浅表复制得到一个刚才创建的对象的副本
EmployeeProcess childEmployeeProcess1 = (EmployeeProcess)mainEmployeeProcess.Clone();
//通过深层复制得到一个刚才创建的对象的副本
EmployeeProcess childEmployeeProcess2 = (EmployeeProcess)mainEmployeeProcess.Clone(true);
//改变用正常方法得到的对象的信息
mainEmployeeProcess.ChangeEmployeeInfo();
//输出浅表副本对象的信息,应该已经改变
Console.WriteLine(childEmployeeProcess1.GetEmployeeInfo());
//输出深成副本对象的信息,和原始的一样
Console.WriteLine(childEmployeeProcess2.GetEmployeeInfo());

Console.Read();
}
}
}