浅谈设计模式之一----------工厂模式
设计模式,我们不得不面对,但开始的时候又有些晕.所以,难免有些不妥的地方,希望大家能够指出来,相互交流.
"对扩展开放,对修改封闭".
"找出会变化的方面,把它们从不变的地方分离出来".
Duck duck = new MallarDuck(); //其中Duck为接口,接口可以使代码更具体弹性,但还是得建立具体类的实例
当有一群相关的具体类时,就会写出如下代码:
Duck pizza = null;
if (Mallar)
{
pizza = new MallarDuck();
}
else if (Decoy)
{
pizza = new DecoyDuck();
}
else if (Rebbuer)
{
pizza = new RebbuerDuck();
}
究竟要实例那个类,要在运行时才能决定.一旦有变化和扩展,就得重新打开这些代码进行检查和修改.违背了"对扩展开放,对修改封闭".
下面正式进入主题:
我们以一个比莎店为例子.
作为一个比莎店的主人:有如下代码:
class PizzaStore
{
//定制Pizza
Pizza orderPizza(string type)
{
Pizza pizza = new Pizza();//无法为抽象类或接口实例化
pizza.prepare();//准备材料
pizza.bake(); //烘干
pizza.cut(); //切片
pizza.box(); //封装起来
return pizza;
}
}
当需要更多的Pizza时:
class PizzaStore
{
Pizza orderPizza(string type)
{
//Pizza pizza = new Pizza();无法为抽象类或接口实例化
Pizza pizza;
if (type.Equals("cheesepizza"))
{
pizza = new CheesePizza();
}
else if (type.Equals("greekpizza"))
{
pizza = new GreekPizza();
}
else if (type.Equals("pepperonipizza"))
{
pizza = new PepperoniPizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
此时,如果我要别的味道的Pizza时,会有:
class PizzaStore
{
Pizza orderPizza(string type)
{
//Pizza pizza = new Pizza();无法为抽象类或接口实例化
Pizza pizza;
if (type.Equals("cheesepizza"))
{
pizza = new CheesePizza();
}
//else if (type.Equals("greekpizza"))这个不要了,因为已经过时了,不适合大众的口味了
//{
// pizza = new GreekPizza();
//}
else if (type.Equals("pepperonipizza"))
{
pizza = new PepperoniPizza();
}
else if (type.Equals("newtastepizza"))//我喜欢新味道的,给我添加,等等,可以增加许多种
{
pizza = new NewtastePizza(); //这是我们不愿意改动的,太麻烦了,我要增加100种,你难道……
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
此时,我们要该知道这样一个事实了,那些会变化,那些不变化, "找出会变化的方面,把它们从不变的地方分离出来".
重要:封装创建对象代码,因为它是变的.
我们可以将创建对象移到orderPizza()之外.找一个类,专门创造Pizza.暂时我们把这个类叫为SimplePizzaFactory.
我们称这个对象为"工厂";
public class SimplePizzaFactory
{
//生产Pizza
public Pizza creatPizza(string type)
{
Pizza pizza = null;
if (type.Equals("cheesepizza"))
{
pizza = new CheesePizza();
}
else if (type.Equals("greekpizza"))
{
pizza = new GreekPizza();
}
else if (type.Equals("pepperonipizza"))
{
pizza = new PepperoniPizza();
}
return pizza;
}
}
这个时候,我们就要重新改写PizzaStore类了,因为它移出了一部分代码.
class PizzaStore
{
SimplePizzaFactory factory;//加上一个对SimplePizzaFactory的引用
public PizzaStore(SimplePizzaFactory factory)//PizaaStore的构造器,需要一个“工厂”作为参数
{
this.factory = factory;
}
public Pizza orderPizza(string type)
{
Pizza pizza;
pizza = factory.creatPizza(type);//注意,这里不再使用具体的实例化了,成了通过穿入定单给工厂,让工厂去做吧,我不管你了
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
下面给大家个关系图看看,是自己P的,因为一些画图工具没下.所以不怎么好,请大家谅解. https://files.cnblogs.com/dreamersjun/11.gif
另外,全部的代码在这.
class CheesePizza:Pizza
{
//






public override void prepare()
{
Console.WriteLine("我是CheesePizza的准备操作");
}
public override void bake()
{
Console.WriteLine("我是CheesePizza的烘干操作");
}
public override void box()
{
Console.WriteLine("我是CheesePizza的封装箱子操作");
}
public override void cut()
{
Console.WriteLine("我是CheesePizza的切片操作");
Console.WriteLine("你定制了CheesePizza");
}
}
class GreekPizza:Pizza
{
//




public override void prepare()
{
Console.WriteLine("我是GreekPizza的准备操作");
}
public override void bake()
{
Console.WriteLine("我是GreekPizza的烘干操作");
}
public override void box()
{
Console.WriteLine("我是GreekPizza的封装箱子操作");
}
public override void cut()
{
Console.WriteLine("我是GreekPizza的切片操作");
}
}
class PepperoniPizza:Pizza
{
//




.public override void prepare()
{
Console.WriteLine("我是PepperoniPizza的准备操作");
}
public override void bake()
{
Console.WriteLine("我是PepperoniPizza的烘干操作");
}
public override void box()
{
Console.WriteLine("我是PepperoniPizza的封装箱子操作");
}
public override void cut()
{
Console.WriteLine("我是PepperoniPizza的切片操作");
}
}
public abstract class Pizza
{
//实现一些动作
public abstract void prepare();//准备材料
public abstract void bake(); //烘干
public abstract void cut(); //切片
public abstract void box(); //封装起来
}
class PizzaStore
{
SimplePizzaFactory factory;//加上一个对SimplePizzaFactory的引用
public PizzaStore(SimplePizzaFactory factory)//PizaaStore的构造器,需要一个“工厂”作为参数
{
this.factory = factory;
}
public Pizza orderPizza(string type)
{
Pizza pizza;
pizza = factory.creatPizza(type);//注意,这里不再使用具体的实例化了,成了通过穿入定单给工厂,让工厂去做吧,我不管你了
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
class SimplePizzaFactory
{
public Pizza creatPizza(string type)
{
Pizza pizza = null;
if (type.Equals("cheesepizza"))
{
pizza = new CheesePizza();
}
else if (type.Equals("greekpizza"))
{
pizza = new GreekPizza();
}
else if (type.Equals("pepperonipizza"))
{
pizza = new PepperoniPizza();
}
return pizza;
}
}
class Program
{
static void Main(string[] args)
{
string type="cheesepizza";
SimplePizzaFactory factory = new SimplePizzaFactory();
PizzaStore pizzaStore = new PizzaStore(factory);
pizzaStore.orderPizza(type);
}
}
OK,希望大家多指教,会用一个礼拜的时间来持续学习工厂模式.

浙公网安备 33010602011771号