您的位置:首页 > 编程语言 > Go语言

GOF 23种设计模式 创建类模式 (2) 工厂方法模式

2014-08-10 17:13 357 查看
定义 : 定义一个用于创建对象的接口,让子类决定实例化那一个类,工厂方法使用一个类的实例化延迟到其他子类

类型 : 创建类模型

类图 :



interface IProduct
{
void productMethod();
}

class ConCreateProduct : IProduct
{
public void productMethod()
{
Console.WriteLine("产品1");
}
}

interface IFactory
{
IProduct FactoryMethod();
}

class ConCreateFactory : IFactory
{
public IProduct FactoryMethod()
{
return new ConCreateProduct();
}
}
public class FactoryMethodSample
{

public static void Test( )
{
Console.WriteLine("FactoryMethod Test ......");
IFactory factory = new ConCreateFactory();
IProduct product = factory.FactoryMethod();
product.productMethod();
}
}


工厂模式:

首先需要说一下工厂模式.工厂模式根据抽象程度的不同分为三种: 简单工厂模式(也叫静态工厂模式) 本文所讲诉的工厂方法模式

以及抽象工厂模式. 工厂模式是编程中经常用到的一种模式.他的主要有点有:

可以是代码结构清晰,有效的封装变化.在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式降产品的实例化封装起来,似的调用者根本无需关心产品的实例化过程,只需要依赖工厂即可得到自己想要的产品.

对调用者屏蔽具体的产品类.如果使用工厂模式,调用者只关心产品的接口就可以了,具体的实现,调用者根本无需关心,即使改变了具体的实现,对调用者来说没有什么影响.

降低耦合度.产品类的实例化通常来说是很复杂的,他需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用,对于调用者来说,产品所依赖的类都是透明的

工厂方法模式:

通过工厂方法模式的类图可以看书,工厂方法模式有四个要素:

工厂接口.工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品,在实际编程中,有时候也会使用一个抽象类来座位调用者交互的接口,起本质上是一样的.

工厂实现.在编程中工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现.

产品接口.产品接口主要的目的是定义产品的会烦,所有的产品实现都必须遵循产品接口定义的规范.产品接口是调用者最为关心,产品接口定义的优劣直接决定了调用者代码的稳定性,同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则

产品实现.实现产品接口的具体类,决定了产品在客户端中的具体行为.

前文提到的简单工厂模式跟工厂方法模式极为相似,区别是:简单工厂只有三个要素,他没有工厂接口,并且得到产品的方法一般都是静态的 . 因为没有工厂接口,所以在工厂实现的扩展性方面稍弱,可以算是工厂方法模式的简化版,关于简单工厂模式再次一笔带过.

适用场景:

不管是简单工厂模式 工厂方法模式,还是抽象工厂模式,他们具有类似的特性,所以他们的适用场景也是类似的.

首先,座位一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式. 有一点需要注意的地方是复杂对象使用使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式.如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度.

其次,工厂模式是一种典型的解耦模式,迪米特法则则在工厂模式中表现的尤为明显.假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式,将会大大降低对象之间的耦合度.

再次,由于工厂模式是依靠抽象架构的,他把实例化产品的人物交由实现类完成,扩展性比较好,也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装.

典型应用:

要说明工厂模式的有点,可能没有比组装汽车更适合的例子了,场景是这样的:汽车是由发动机,轮,底盘组成,现在需要组装一辆车交给调用者

class Engine
{
public void getStyle()
{
Console.WriteLine("这是汽车的发动机");
}
}

class Underpan
{
public void getStyle()
{
Console.WriteLine("这是汽车的底盘");
}
}

class Wheel
{
public void getStyle()
{
Console.WriteLine("汽车的轮子");
}

}

class ICar
{
protected Engine mEngine = null;
protected Underpan mUnderpan = null;
protected Wheel mWheel = null;

public void Show()
{
mEngine.getStyle();
mUnderpan.getStyle();
mWheel.getStyle();
}
}

class Car : ICar
{
public Car(Engine engine, Underpan underpan, Wheel wheel)
{
mEngine = engine;
mUnderpan = underpan;
mWheel = wheel;
}
}
class CarFactory
{
public static void Test()
{
Engine engine = new Engine();
Underpan underpan = new Underpan();
Wheel wheel = new Wheel();
ICar car = new Car(engine , underpan, wheel  );
car.Show();

}
}


使用工厂方法后,调用端的耦合度大大降低了。并且对于工厂来说,是可以扩展的,以后如果想组装其他的汽车,只需要再增加一个工厂类的实现就可以。无论是灵活性还是稳定性都得到了极大的提高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: