1、概述
针对简单工厂中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则。
定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
工厂方法模式的主要角色:
- 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
2、工厂方法模式实现思路
首先,我们先创建一个简单的类。
//1.抽象产品类
public abstract class Pizza
{
//名字
public string Name;
//准备原材料
public abstract void Prepare();
public void Bake()
{
Console.WriteLine($"{this.Name} bake");
}
public void Cut()
{
Console.WriteLine($"{this.Name} cut");
}
public void Box()
{
Console.WriteLine($"{this.Name} box");
}
}
//2.具体产品类
public class GreekPizza : Pizza
{
public override void Prepare()
{
Console.WriteLine("GreekPizza 准备原材料");
}
}
//2.具体产品类
public class CheessPizza : Pizza
{
public override void Prepare()
{
Console.WriteLine("CheessPizza 准备原材料");
}
}
//3.抽象工厂类
public abstract class PizzaFactory
{
public abstract Pizza CreatePizza();
}
//4.具体工厂类
public class CheessPizzaFactory : PizzaFactory
{
public override Pizza CreatePizza()
{
CheessPizza cheessPizza = new CheessPizza();
cheessPizza.Name = "奶酪披萨";
cheessPizza.Prepare();
cheessPizza.Bake();
cheessPizza.Cut();
cheessPizza.Box();
return cheessPizza;
}
}
//4.具体工厂类
public class GreekPizzaFactory:PizzaFactory
{
public override Pizza CreatePizza()
{
GreekPizza greekPizza = new GreekPizza();
greekPizza.Name = "希腊披萨";
greekPizza.Prepare();
greekPizza.Bake();
greekPizza.Cut();
greekPizza.Box();
return greekPizza;
}
}
//5.订购披萨
public class PizzaStore
{
PizzaFactory _pizzaFactory;
public void setPizzaFactory(PizzaFactory pizzaFactory)
{
this._pizzaFactory = pizzaFactory;
}
public Pizza OrderPizza()
{
Pizza pizza = _pizzaFactory.CreatePizza();
return pizza;
}
}
//使用工厂方法模式
class Program
{
static void Main(string[] args)
{
PizzaStore pizzaStore = new PizzaStore();
PizzaFactory greekPizzaFactory = new GreekPizzaFactory();
pizzaStore.setPizzaFactory(greekPizzaFactory);
pizzaStore.OrderPizza();
PizzaFactory cheessPizzaFactory = new CheessPizzaFactory();
pizzaStore.setPizzaFactory(cheessPizzaFactory);
pizzaStore.OrderPizza();
}
}
******************【运行结果】******************
GreekPizza 准备原材料
希腊披萨 bake
希腊披萨 cut
希腊披萨 box
CheessPizza 准备原材料
奶酪披萨 bake
奶酪披萨 cut
奶酪披萨 box
从以上的编写的代码可以看到,要增加产品类时也要相应地增加工厂类,不需要修改工厂类的代码了,这样就解决了简单工厂模式的缺点。
工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
3、 优缺点
优点:
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
- 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点:
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。