工厂方法(Factory Method)
工厂方法(Factory Method),定义一个用于创建对象的接口,让子类决定实例化那一个类。Factory Method使一个类的实例化延迟到子类。
别名虚构造器(Virtual Constructor)
结构
Product
— 定义工厂方法所创建的对象的接口。
ConcreteProduct
— 实现Product接口。
Creator
— 声明工厂方法,该方法返回一个Product类型的对象。Product也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
— 可以调用工厂方法以创建一个Product对象。
ConcreteProduct
— 重定义工厂方法以返回一个ConcreteProduct实例。
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod
{
public abstract class Product
{
public abstract void Operation();
}
public class ConcreteProductA : Product
{
public override void Operation()
{
Console.WriteLine("ConreteProduct A");
}
}
public class ConcreteProductB : Product
{
public override void Operation()
{
Console.WriteLine("ConreteProduct B");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod
{
public abstract class Creater
{
public abstract Product FactoryMethod();
}
public class ConcreteCreatorA : Creater
{
public override Product FactoryMethod()
{
return new ConcreteProductA();
}
}
public class ConcreteCreatorB : Creater
{
public override Product FactoryMethod()
{
return new ConcreteProductB();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod
{
class Program
{
static void Main(string[] args)
{
Creater c;
Product p;
c = new ConcreteCreatorA();
p = c.FactoryMethod();
p.Operation();
Console.WriteLine();
c = new ConcreteCreatorB();
p = c.FactoryMethod();
p.Operation();
Console.ReadKey();
}
}
}
效果
1)工厂方法不再将与特定应用有关的类绑定到你的代码中 代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。2)为子类提供挂钩(hook) 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。Factory Method给子类一个挂钩以提供对象的扩展版本。
3)连接平行的类层次 当一个类将它的一些职责委托给一个独立的类的时候,就产生了平行类层次。
4)工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creater的子类。
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实例化产品类,选择判断的问题还是存在的,也就是说工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。
实现1)主要有两种不同的情况 Factory Method模式主要有两种不同的情况:1)第一种情况是,Creator类是一个抽象类并且不提供它所声明的工厂方法的实现。2)第二种情况是,Creator是一个具体的类而且为工厂方法提供一个缺省的实现。也有可能有一个定义了缺省实现的抽象类。
2)参数化工厂方法 该模式的另一种情况使得工厂方法可以创建多种产品。工厂方法采用一个标识要被创建的对象种类的参数。
3)使用模板以避免创建子类。
参考代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod1
{
public class Operation
{
private double numberA = 0;
private double numberB = 0;
public double NumberA
{
get { return numberA; }
set { numberA = value; }
}
public double NumberB
{
get { return numberB; }
set { numberB = value; }
}
public virtual double GetResult()
{
double result = 0;
return result;
}
}
public class OperationAdd : Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
}
class OperationSub : Operation
{
public override double GetResult()
{
return NumberA - NumberB;
}
}
class OperationMul : Operation
{
public override double GetResult()
{
return NumberA * NumberB;
}
}
class OperationDiv : Operation
{
public override double GetResult()
{
if (NumberB == 0)
{
throw new Exception("Divisor cannot be zero");
}
return NumberA / NumberB;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod1
{
// 简单工厂实现
class SimpleFactory
{
public static Operation createOperation(string operate)
{
Operation oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
break;
}
return oper;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod1
{
// 工厂方法实现
interface IFactory
{
Operation CreateOperation();
}
public class AddFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
class SubFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationSub();
}
}
class MulFactory : IFactory
{
public Operation CreateOperation()
{
return (Operation)new OperationMul();
}
}
class DivFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationDiv();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyFactoryMethod1
{
class Program
{
static void Main(string[] args)
{
// 简单工厂
Operation oper1 = SimpleFactory.createOperation("+");
oper1.NumberA = 1;
oper1.NumberB = 2;
double result1 = oper1.GetResult();
Console.WriteLine("result2:{0}", result1);
// 工厂方法
IFactory opFactory = new AddFactory(); // 实例化工厂(子类)
Operation oper2 = opFactory.CreateOperation(); // 工厂方法
oper2.NumberA = 2;
oper2.NumberB = 3;
double result2 = oper2.GetResult();
Console.WriteLine("result2:{0}", result2);
Console.ReadKey();
}
}
}
预告
抽象工厂(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。