设计模式基于C#的实现与扩展——创建型模式(一)

创建模式

使用创建模式的主要动机来自于“变化”,应用的哪些组成会快速变化呢?不一定,多数项目会有一个相对稳定的核心,无论是被叫做Framework,还是更时髦,感觉更底层的Foundation,这个部分相对比较稳定,言外之意其他部分都会“相对”变化比较频繁。
创建模式抽象了实例化过程。它们帮组一个系统独立于如何创建、组合和表示对象。一个类创建模式使用继承改变被实例化的类,而一个对象创建模式将实例化委托给另外一个对象。
随着系统的演化,越来越依赖于对象复合而不是类继承,创建模式变得更为重要。

1. 预备役——简单工厂

最简单的工厂类

作为一个预备役,首先用朴实的方法实现一个工厂。

public interface IProduct
{
	string Name { get; }        
}

public class ConcreteProductA : IProduct
{
	public string Name { get { return "Product A"; } }
}

public class SimpleFactory
{
	public IProduct Create()
    {
    	return new ConcreteProductA();
    }
}

Unit Test:

[TestMethod]
public void Test_SimpleFactory()
{
    SimpleFactory factory = new SimpleFactory();
    IProduct product = factory.Create();

    Assert.IsNotNull(product);
    Assert.IsInstanceOfType(product, typeof(ConcreteProductA));
}

优点:

  • 通过IProduct隔离Client与具体ContreteProductX的依赖关系,在客户程序视野中根本就没有ContreteProductX。
  • 即使ContreteProductX增加、删除方法或属性,也无妨大局,只要按照要求实现了IProduct就可以,Client无需关心ContreteProductX的变化。

缺点:

  • 相对于直接写ContreteProductX而言,要平白地多写一个工厂出来。
  • 效率问题。如果构建一个Factory实例,并用它获取一个抽象类型实例后就不再使用,资源上有些浪费,尤其当这个过程非常频繁的时候。

改进:

  • 把工厂实例作为参数注入到操作中,而不是在每个方法内部自行创建。
  • 把工厂设计为单例方式,因为工厂的指责相对单一,所有客户端需要的工厂使用的都是一个唯一的共享实例。
  • 使用静态类。这也算是一个有效节省资源使用的途径,不过切记:静态类不能被继承它只能从Object继承,没有其他可能。这个有些违反面向对象的设计原则,同时也会为测试的数据隔离工作带来了很大的障碍。

扩展

参数化工厂

如果想让工厂在运行时有效选择符合抽象类型要求的某个实例,最简单的机制莫过于传递一个参数,它可能是一个字符串,一个枚举值,例如在工厂类的实现中显示的传递一个Cat
egory类型的枚举参数。

public interface IProduct
{
    string Name { get; }        
}

public class ConcreteProductA : IProduct
{
    public string Name { get { return "Product A"; } }
}

public class ConcreteProductB : IProduct
{
    public string Name { get { return "Product B"; } }
}

public class ParametricFactory
{
    public enum Category
    {
        A, 
        B
    }

    public IProduct Create(Category category)
    {
        switch(category)
        {
            case Category.A:
                return new ConcreteProductA();
            case Category.B:
                return new ConcreteProductB();
            default:
                throw new NotSupportedException();
        }
    }
}

Unit Test:

[TestMethod]
public void Test_ParametricFactory()
{
    ParametricFactory factory = new ParametricFactory();
    IProduct product = factory.Create(ParametricFactory.Category.A);
    Assert.IsNotNull(product);
    Assert.IsInstanceOfType(product, typeof(ConcreteProductA));

    product = factory.Create(ParametricFactory.Category.B);
    Assert.IsNotNull(product);
    Assert.IsInstanceOfType(product, typeof(ConcreteProductB));
}

猜你喜欢

转载自blog.csdn.net/rocket2002/article/details/103243575