1.工厂模式是什么
工厂模式是Java中最常用的设计模式之一,是用工厂方法代替new操作的一种模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式,在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,虽然这样做可能多做一些工作,但是会给你的程序带来更大的可扩展性和尽量少的修改。
工厂模式又主要分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。
2.简单工厂模式
简单工厂模式又称为静态工厂方法模式,从命名上就可以看出这个模式很简单,其实它存在的目的也很简单,就是定义一个用于创建对象的接口。在简单工厂模式中,一个工厂类处于产品实例化调用中心的位置上,它决定哪一个产品类应当被实例化。
就如同我们到了一个Pizza店,在进行点餐的过程中,客人决定点哪款Pizza工厂类就要去实例化哪款Pizza。
首先我们要新建一个Pizza的抽象类,在这个类中我们默认Pizza的烘烤、切割、打包都是一样的,只有准备的配料不一样,所以只有准备方法是抽象方法,具体的Pizza需要具体的实现。
package com.designPatter.chupeng.pizza;
public abstract class Pizza
{
protected String name;
//准备
public abstract void prepare();
//烘烤
public void bake()
{
System.out.println(name+" baking;");
}
//切割
public void cut()
{
System.out.println(name+" cutting;");
}
//打包
public void box()
{
System.out.println(name+" boxing;");
}
public void setname(String name)
{
this.name=name;
}
}
接下来我们还需要新建若干个不同种类的Pizza类,每个种类的Pizza都需要继承自Pizza类,并且实现烘烤方法。
package com.designPatter.chupeng.pizza;
public class CheesePizza extends Pizza
{
@Override
public void prepare()
{
// TODO Auto-generated method stub
super.setname("CheesePizza");
System.out.println(name+" preparing;");
}
}
在这里就仅仅展示出CheesePizza的实现,其余所有种类Pizza的实现都是大同小异,这里就不一一列举出来了。接下来需要实现简单工厂类,简单工厂类主要是通过if-else来针对客人不同的需求实现不同的Pizza实例。
package com.designPatter.chupeng.simplefactory;
import com.designPatter.chupeng.pizza.CheesePizza;
import com.designPatter.chupeng.pizza.GreekPizza;
import com.designPatter.chupeng.pizza.PepperPizza;
import com.designPatter.chupeng.pizza.Pizza;
public class SimplePizzaFactory
{
public Pizza CreatePizza(String ordertype)
{
Pizza pizza = null;
if (ordertype.equals("cheese"))
{
pizza = new CheesePizza();
}
else if (ordertype.equals("greek"))
{
pizza = new GreekPizza();
}
else if (ordertype.equals("pepper"))
{
pizza = new PepperPizza();
}
return pizza;
}
}
接下来我们还需要新建一个点餐类,在这个点餐类中主要通过获取从控制台的输入,来实例化不同种类的Pizza。
package com.designPatter.chupeng.simplefactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import com.designPatter.chupeng.pizza.Pizza;
public class OrderPizza
{
SimplePizzaFactory mSimplePizzaFactory;
public OrderPizza(SimplePizzaFactory mSimplePizzaFactory)
{
setFactory(mSimplePizzaFactory);
}
public void setFactory(SimplePizzaFactory mSimplePizzaFactory)
{
Pizza pizza = null;
String ordertype;
this.mSimplePizzaFactory = mSimplePizzaFactory;
do
{
ordertype = gettype();
//通过工厂类获取不同种类的Pizza实例
pizza = mSimplePizzaFactory.CreatePizza(ordertype);
if (pizza != null)
{
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
} while (true);
}
//通过控制台的输入获取客人的点餐信息
private String gettype()
{
try
{
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
}
catch (IOException e)
{
e.printStackTrace();
return "";
}
}
}
最后,在main方法中,我们只需要一个工厂类和一个点餐类即可实现。
package com.designPatter.chupeng.simplefactory;
public class PizzaStroe
{
public static void main(String[] args)
{
SimplePizzaFactory mSimplePizzaFactory;
OrderPizza mOrderPizza;
mOrderPizza = new OrderPizza(new SimplePizzaFactory());
}
}
3.工厂方法模式
这时我们的Pizza需要开一些分店,也就是需要不同类型的Pizza类,原来的简单工厂类的设计模式就不能满足我们的要求了,我们需要把Pizza再进行抽象化,同一种类的Pizza需要区分出不同的地区所销售的。在这种情况下就需要使用到工厂方法模式,其实工厂方法模式就是对简单工厂模式的进一步抽象和推广。
首先我们需要新建一个点餐的抽象类。
package com.designPatter.chupeng.method;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import com.designPatter.chupeng.pizza.Pizza;
public abstract class OrderPizza
{
public OrderPizza()
{
Pizza pizza = null;
String ordertype;
do
{
ordertype = gettype();
pizza = createPizza(ordertype);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
abstract Pizza createPizza(String ordertype);
private String gettype()
{
try
{
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
}
catch (IOException e)
{
e.printStackTrace();
return "";
}
}
}
在这个抽象类中只有一个抽象方法,这个抽象方法会根据根据点餐的不同返回一个不同种类的Pizza实例。接下来要新建一个纽约点餐的类,继承自点餐类并且实现createPizza()方法,用来实现不同的Pizza店所销售的不同种类的Pizza。
package com.designPatter.chupeng.method;
import com.designPatter.chupeng.pizza.NYCheesePizza;
import com.designPatter.chupeng.pizza.NYPepperPizza;
import com.designPatter.chupeng.pizza.Pizza;
public class NYOrderPizza extends OrderPizza
{
@Override
Pizza createPizza(String ordertype)
{
Pizza pizza = null;
if (ordertype.equals("cheese"))
{
pizza = new NYCheesePizza();
}
else if (ordertype.equals("pepper"))
{
pizza = new NYPepperPizza();
}
return pizza;
}
}
package com.designPatter.chupeng.method;
import com.designPatter.chupeng.pizza.LDCheesePizza;
import com.designPatter.chupeng.pizza.LDPepperPizza;
import com.designPatter.chupeng.pizza.Pizza;
public class LDOrderPizza extends OrderPizza
{
@Override
Pizza createPizza(String ordertype)
{
Pizza pizza = null;
if (ordertype.equals("cheese"))
{
pizza = new LDCheesePizza();
}
else if (ordertype.equals("pepper"))
{
pizza = new LDPepperPizza();
}
return pizza;
}
}
最后在main方法中,新建不同的点餐实例即可。
package com.designPatter.chupeng.method;
public class PizzaStroe
{
public static void main(String[] args)
{
OrderPizza mOrderPizza;
mOrderPizza = new NYOrderPizza();
}
}
4.抽象工厂模式
这时由于开分店的需求,不同分店的Pizza需要各自去实现,不能再使用统一的工厂去实现,此时工厂方法模式就不能满足我们的需求了,我们需要把工厂类中实现实例化的共同方法抽取出来。
首先新建一个抽象工厂类。
package com.designPatter.chupeng.absfactory;
import com.designPatter.chupeng.pizza.Pizza;
public interface AbsFactory
{
public Pizza CreatePizza(String ordertype) ;
}
其次新建工厂类并且继承自抽象工厂类,实现CreatePizza的方法。
package com.designPatter.chupeng.absfactory;
import com.designPatter.chupeng.pizza.LDCheesePizza;
import com.designPatter.chupeng.pizza.LDPepperPizza;
import com.designPatter.chupeng.pizza.Pizza;
public class LDFactory implements AbsFactory
{
@Override
public Pizza CreatePizza(String ordertype)
{
Pizza pizza = null;
if (ordertype.equals("cheese"))
{
pizza = new LDCheesePizza();
}
else if (ordertype.equals("pepper"))
{
pizza = new LDPepperPizza();
}
return pizza;
}
}
package com.designPatter.chupeng.absfactory;
import com.designPatter.chupeng.pizza.NYCheesePizza;
import com.designPatter.chupeng.pizza.NYPepperPizza;
import com.designPatter.chupeng.pizza.Pizza;
public class NYFactory implements AbsFactory
{
@Override
public Pizza CreatePizza(String ordertype)
{
Pizza pizza = null;
if (ordertype.equals("cheese"))
{
pizza = new NYCheesePizza();
}
else if (ordertype.equals("pepper"))
{
pizza = new NYPepperPizza();
}
return pizza;
}
}
从上面的代码中可以看到,不同的工厂类实例化出不同的Pizza实例,最后在main方法中我们只要给出不同的工厂类实例即可。
package com.designPatter.chupeng.absfactory;
public class PizzaStroe
{
public static void main(String[] args)
{
OrderPizza mOrderPizza = new OrderPizza(new LDFactory());
}
}
5.总结
一般情况下在写程序的过程中,在那里用到对象就会new一个对象,这样子的操作会造成对象的依赖化过大就会对程序造成很强的耦合性,对以后代码的变更和升级会造成极大的困难,而我们需要降低这种耦合性的发生,而降低这种耦合性所使用的处置方法就是工厂模式。根据处置方法的不同就会有三种不同的工厂模式,所以工厂模式的本质意义所在就是把项目里面对象实例化的动作提取出来,放在某个地方或者某个区域进行统一的管理,这样就会使得程序具有更好的扩展性和维护性。
简单工厂模式:把对象实例化的过程放在一个简单的类中。
工厂方法模式:把创建对象的过程进行抽象,抽象成创建对象的方法从而在其子类中更具体的实例化,工厂方法模式的意义就是把创建对象的操作从一个简单的类中放到其子类中。
抽象工厂模式:将工厂变成一个工厂族的模式,抽取出建立工厂的通用方法,将某些差异化过程在具体的子类中实现。
以上Demo的源代码地址:点击打开链接