工厂模式定义:提供创建对象的接口.
有工厂方法和抽象工厂
统一管理对象的创建过程
降低耦合
假设你有一个披萨店,你的代码可能这么写:
Pizza orderPizza()
{
Pizza pizza = new Pizza();
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
但,当你需要更多披萨类型时,你必须增加一些代码
Pizza orderPizza(String type) //传入披萨类型
{
Pizza pizza ;
//根据披萨的类型,我们实例化明确的具体类,然后将其赋值给pizza实例变量。请注意,这里的任何披萨都必须实现Pizza借口。
if (typeof.Equals("cheese"))
{
pizza=new CheesePizza();
}
else if (typeof.Equals("greek"))
{
pizza=new GreekPizza();
}
else if (typeof.Equals("pepperoni"))
{
pizza=new PepperoniPizza();
}
//有了披萨,需要做一些准备,然后烘焙等!每个pizza的子类都有这些步骤。
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
很多竞争者都在他们的菜单中加入了一些流行的新比萨,而最近GreeekPizza卖得不好,所以你决定将它从菜单中去掉,同时添加一些新品:
很明显, orderPizza()需要经常改变,该是使用封装的时候了。
封装代码
把创建对象的代码移到orderPizza()之外。把这些代码搬到另一个对象中,这个新对象只负责创建比萨---SimplePizzaFactory。这个新对象我们称为工厂。
建立一个简单比萨工厂
public class SimplePizzaFactory
{
//代码没什么变动和元贝orderPizza()方法中的代码一样。
public Pizza createPizza(string type)
{
if (typeof.Equals("cheese"))
{
pizza=new CheesePizza();
}
else if (typeof.Equals("greek"))
{
pizza=new GreekPizza();
}
else if (typeof.Equals("pepperoni"))
{
pizza=new PepperoniPizza();
}
return pizza;
}
}
这就是一个工厂方法,这样写有什么好处,只是把问题搬到另一个对象了。但是这样封装了后,很多客户都可以调用它。以后把创建一个新的比萨类,只需要修改这个类即可。
但这也有个缺点,就是不能通过继承来改变创建方法的行为。
public class PizzaStore
{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) //构造器需要一个工厂作为参数
{
this.factory=factory;
}
Pizza orderPizza(String type) //传入披萨类型
{
Pizza pizza ;
pizza =factory.createPizza(type); //把new操作符替换成工厂对象的创建方法,不在使用具体实例化。
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//这里是其它方法
}
现在有加盟店,要提供不同风味的比萨。
如果利用SimplePizzaFactory,写出三种不同的工厂,分别是NYPizzaFactory,ChicagoPizzaFactory, CaliforniaPizzaFactory, 那么各地加盟店都有适合的工厂可以使用,这是一种做法。 NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nySotre = new PizzaStore(nyFactory ); //建立一个披萨店,将纽约作为参数
nySotre .orderPizza("Veggie");
得到纽约风味的披萨
ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore chicagoSotre = new PizzaStore(chicagoFactory ); //建立一个披萨店,将纽约作为参数
chicagoSotre .orderPizza("Veggie");
得到芝加哥风味的披萨
这样做之后,有些店需要采用他们自己的一些加工方法,烘烤的做法有些诧异、不要切片,使用不同的盒子。该怎么做
所要做的事情,就是把createPizza()方法放回到PizzaStore 中,不过要把它设置成抽象方法,然后为每个区域风味创建一个PizzaStore 的子类。public abstract class PizzaStore
{
public Pizza orederPizza(String type)
{
Pizza pizza ;
pizza =createPizza(type) //传入披萨类型
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type) ;
}
现在已经有一个PizzaStore作为超类,让每个地方的store都继承这个PizzaStore,每个子类各自决定如何制造披萨。
加盟店可以从PizzaStore免费取得所有的功能,只需要继承PizaStore,然后提供CreatePizza()方法实现自己的比萨风味即可。
public class NYPizzaStore extends PizzaStore
{
//代码没什么变动和元贝orderPizza()方法中的代码一样。
Pizza createPizza(string item)
{
if (item.Equals("cheese"))
{
return new NYStyleCheesePizza();
}
else if (item.Equals("greek"))
{
return new NYStylePizza();
}
else if (item.Equals("pepperoni"))
{
return new NYStylePizza();
}
else return null;
}
}
实现披萨类
public abstract class Pizza
{
string name;
string dough;
string sauce
ArrayList topping=new ArrayList();
void prepare()
{
print("preparing "+ name);
print("Tossing dough. . .");
print("Adding sauce...");
print("Adding toppings...");
for(int i=0; i < tippings.size(); i++)
print(" "+ toppings.get(i));
}
void bake()
{
print("Bake for 25 minutes at 350");
}
void cut()
{
print("cutting the pizza into diagonal slices");
}
void box()
{
print("Place pizza in official pizzaStore box");
}
public string getName()
{
return name;
}
}
实现具体的子类,来定义纽约和芝加哥风味的比萨
public class NYStyleCheesePizza extends Pizza
{
pulbic NYStyleCheesePizza()
{
name="NY Style Sauce and Chees Pizza";
dough= "Thin Crust Dough";
sauce = "Marinara souce";
toppings.add("Grated Reggiano Cheese");
}
}
public class ChicagoStyleCheesePizza extends Pizza
{
pulbic ChicagoStyleCheesePizza()
{
name="Chicago Style Deep and Chees Pizza";
dough= "TExtra Thick Crust Dough";
sauce = "Plum Tomato souce";
toppings.add("Shredded Mozzarella Cheese");
}
void cut()
{
print("cutting the pizza into square slices") //这个芝加哥风味的比萨覆盖了cut()方法,将比萨切成正方形
}
}
生成一个披萨
publice class PizzaTEstDrive
{
public static void main(stirng[] args)
{
PizzaStore nyStore = new NYPizzaStore ();
PizzaStore chicagoStore = new ChicagoStore ();
Pizza pizza = nyStore .orederPizza("cheese");
print("hao order a "+ pizza.getName());
pizza = chicagoStore .orederPizza("cheese");
print("dong order a "+ pizza.getName());
}
}
认识工厂模式
组成元素:
创建者类Creator,产品类
工厂方法模式:
定义了一个创建对象的借口,但由于子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
工厂就是你要什么去到工厂里拿就好了,工厂负责生产,你除了使用什么都不用管,小程序你看不出优势来,打个比方说如果12亿人人,一人一个电视,那么如果每个人都去工厂里制造是多么麻烦的事,你只要告诉他你要什么类型的,工厂会生产出来给你,这个就是通俗意义上的工厂模式了。
至于说使用这个的好处,可以方便的更改应用程序,方便扩展。比如说你修改了一个类,或者在这个类的基础上生成了一个子类那么你现在要把以前使用父类的地方都给改为子类,如果小程序可能有几十个地方要改,如果大一点可能就几百几千个地方要改了。如果使用工厂模式,你只要改一个地方就可以了。