前言
示例:
pizza
店做pizza
的过程:
- 种类:
GreekPizza
,CheesePizza
等 - 制作过程:
prepare(准备)
,bake(烘烤)
,cut(切割)
,box(打包)
- 完成
pizza
店订购的功能
首先介绍传统模式:
Pizza类
//抽象类Pizza
public abstract class Pizza {
//pizza的名字,具体的pizza
protected String name;
//准备原材料,不同的pizza原材料不同,所以设置成抽象方法
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;");
}
//将pizza的名字设置进去
public void setName(String name){
this.name=name;
}
}
GreekPizza类
//希腊pizza,继承了抽象类pizza
public class GreekPizza extends Pizza {
//重写抽象类中的准备方法
@Override
public void prepare() {
System.out.println("给制作希腊pizza做准备!");
}
}
CheesePizza类
//奶酪pizza,继承Pizza抽象类
public class CheesePizza extends Pizza{
//重写抽象类中的准备方法
@Override
public void prepare() {
System.out.println("给制作奶酪pizza做准备!");
}
}
OrderPizza类
//订购pizza(依赖Pizza,CheesePizza,GreekPizza)
public class OrderPizza {
//构造器
public OrderPizza(){
Pizza pizza=null;
String orderType;//订购pizza的种类
do{
//假设定做的是greekpizza(可以调用getType()方法,动态的进行pizza的定制)
orderType=getType();
if(orderType.equals("greek")){
pizza=new GreekPizza();
pizza.setName("希腊pizza");
}else if(orderType.equals("cheese")){
pizza=new CheesePizza();
pizza.setName("奶酪pizza");
}else{
break;
}
//输出pizza的制作过程
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}while(true);
}
//此方法可以获取客户希望订购的pizza种类
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 "";
}
}
}
PizzaStore类
//相当于客户端
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
优缺点:
- 违反了开闭原则(ocp),即对扩展开放,对修改关闭。我们给类增加新功能的时候,尽量不修改代码,或者是尽量少的修改代码。
- 假如需要增加一种
pizza
的种类,(只要是订购pizza
的代码都要修改)需要增加一个新的pizza
类,并且在OrderPizza
类中要进行代码的修改,增加一个新的pizza
类。
改进方法:
把创建pizza
对象封装到一个类中,这样需要增加新的pizza
类的时候,只要修改这个类就行了,其他有创建pizza
对象的代码就不需要修改了,这样就引出了简单工厂模式。
- 简单工厂模式属于创建型模式,是工厂模式的一种。是由一个工厂对象决定创建出哪一种产品类的实例。
- 定义了一个创建对象的 类,这个类来封装实例化对象的代码。
- 我们用到大量的创建某种、某类或者某批对象时,会用到工厂模式。
运用简单工厂模式,在传统方法上进行改进的地方,有两点:
- 增加一个
SimpleFactory
类 - 修改
PizzaStore
类和OrderPizza
类中的内容
SimpleFactory类
public class SimpleFactory {
//根据orderType返回一个对应的pizza对象
public Pizza createPizza(String orderType){
Pizza pizza=null;
System.out.println("使用简单工厂模式!");
if(orderType.equals("greek")){
pizza=new GreekPizza();
pizza.setName("希腊pizza");
}else if(orderType.equals("cheese")){
pizza=new CheesePizza();
pizza.setName("奶酪pizza");
}
return pizza;
}
}
PizzaStore类
//相当于客户端
public class PizzaStore {
public static void main(String[] args) {
//使用简单工厂模式
new OrderPizza(new SimpleFactory());
System.out.println("退出程序!");
}
}
OrderStore类
//订购pizza(依赖Pizza,CheesePizza,GreekPizza)
public class OrderPizza {
//定义一个简单工厂对象(聚合关系)
SimpleFactory simpleFactory;
Pizza pizza=null;
//构造器
public OrderPizza(SimpleFactory simpleFactory){
setFactory(simpleFactory);
}
public void setFactory(SimpleFactory simpleFactory) {
String orderType = "";//用户输入的内容
this.simpleFactory = simpleFactory;
do {
orderType = getType();//获取pizza种类,调用下面的方法
pizza=this.simpleFactory.createPizza(orderType);
//输出pizza
if(pizza!=null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}else{
System.out.println("订购pizza失败(没有这个种类的pizza!)");
break;
}
} while (true);
}
//此方法可以获取客户希望订购的pizza种类
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 "";
}
}
}