工厂模式:专门负责将大量有共同接口的类实例化,工厂模式可以动态的决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:
- 简单工厂模式(simple factory)又称静态工厂模式。
- 工厂方法模式(Factory Method)又称多态工厂模式模式。
- 抽象工厂模式(Abstract Method):又称工具箱。
1.简单工厂模式UML类图如图所示:
代码:
Fruit 抽象产品:
package com.lp.ecjtu.SimpleFactory; public interface Fruit { /** * 种植 */ public void plant(); /** * 生长 */ public void grow(); /** * 收货 */ public void harvest(); }
具体产品:这里包括Apple,Orange,Grape:
package com.lp.ecjtu.SimpleFactory; public class Apple implements Fruit{ @Override public void plant() { // TODO Auto-generated method stub System.out.println("Apples have been planted!"); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("Apples is growing!"); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("Apples have been harvested!"); } }
package com.lp.ecjtu.SimpleFactory; public class Orange implements Fruit { @Override public void plant() { // TODO Auto-generated method stub System.out.println("Oranges have been planted!"); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("Oranges is growing!"); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("Oranges have been harvested!"); } }
package com.lp.ecjtu.SimpleFactory; public class Grape implements Fruit { private boolean seedless; public boolean isSeedless() { return seedless; } public void setSeedless(boolean seedless) { this.seedless = seedless; } public void plant() { // TODO Auto-generated method stub System.out.println("Grapes have been planted!"); } public void grow() { // TODO Auto-generated method stub System.out.println("Grapes is growing!"); } public void harvest() { // TODO Auto-generated method stub System.out.println("Grapes have been growed!"); } }
工厂类:工厂模式的核心
package com.lp.ecjtu.SimpleFactory; public class FruitGarden { public FruitGarden(){} public static Fruit factoryFruit(String which) throws BadFruitException { if(which.equalsIgnoreCase("apple")){ return new Apple(); }else if(which.equalsIgnoreCase("orange")){ return new Orange(); }else if(which.equalsIgnoreCase("grape")){ return new Grape(); }else{ throw new BadFruitException("bad fruit"); } } }
FruitClient :
package com.lp.ecjtu.SimpleFactory; public class FruitClient { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { Fruit f = FruitGarden.factoryFruit("apple"); f.plant(); f.grow(); f.harvest(); System.out.println("********************************"); Fruit o = FruitGarden.factoryFruit("orange"); o.grow(); o.harvest(); o.plant(); } catch (BadFruitException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行输出:
Apples have been planted!
Apples is growing!
Apples have been harvested!
********************************
Oranges is growing!
Oranges have been harvested!
Oranges have been planted!
简单工厂模式的优点与缺陷:
优点:模式的核心是工厂,这个类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品的实例。而客户端可以免除直接创建产品对象的责任,而仅仅负责"消费"产品。实现了对责任的额分割。
缺陷:工厂类是一个全能类,像上帝类,里面的方法是静态的,无法由子类继承,扩展性比较差,当有新的产品加入到系统中去,就需要修改工厂类。对"开-闭"
2.工厂方法设计模式(多态工厂模式)
工厂方法设计模式:弥补了简单工厂对“开-闭”原则支持不够的缺点,核心的工厂类不在负责所有产品的创建,而将具体创建工作交给了子类去做,这个核心类变成了一个抽象工厂角色。仅负责给出具体工厂子类必须的实现接口,而不接触那个产品类应该被实例化的这种细节。这样当系统需要加入新的产品的时候,不需要修改客户端,也没必要修改抽象工厂类或者其他已有的具体工厂角色,只需要向系统加入一个产品类以及它对应的工厂类。
下面我们对上面的水果类作物系统进行优化,在那个系统中有一个全知全能的园丁角色(FruitGarden),控制所有作物的种植,生长,收货。现在这个农场的规模变大了,而同时发生的是管理更专业化了。过去的全能人物没有了,每一种弄作物都有专门的园丁管理,形成规模化生产和专业化生产。
下图为工厂方法模式UML类图
代码实现:
抽象工厂角色:FruitGarden
package com.lp.ecjtu.FactoryMethod; public interface FruitGarden { /** * 工厂方法,抽象工厂角色 * @return */ public Fruit factory(); }
具体工厂角色:AppleGarden,GrapeGarden,OrangeGarden
package com.lp.ecjtu.FactoryMethod; public class AppleGarden implements FruitGarden{ /** * 工厂方法,抽象工厂角色 * @return */ public Fruit factory() { return new Apple(); } }
package com.lp.ecjtu.FactoryMethod; public class OrangeGarden implements FruitGarden{ /** * 工厂方法,抽象工厂角色 * @return */ public Fruit factory() { return new Orange(); } }
package com.lp.ecjtu.FactoryMethod; public class GrapeGarden implements FruitGarden{ /** * 工厂方法,抽象工厂角色 * @return */ public Fruit factory() { return new Grape(); } }
抽象产品角色:Fruit
package com.lp.ecjtu.FactoryMethod; public interface Fruit { /** * 种植 */ public void plant(); /** * 生长 */ public void grow(); /** * 收货 */ public void harvest(); }
具体产品角色:Apple,Orange,Grape
package com.lp.ecjtu.FactoryMethod; public class Apple implements Fruit { private int treeAge; public int getTreeAge() { return treeAge; } public void setTreeAge(int treeAge) { this.treeAge = treeAge; } @Override public void plant() { System.out.println("Apples have been planted!"); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("Apples is growing!"); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("Apples have been harvested!"); } }
package com.lp.ecjtu.FactoryMethod; public class Orange implements Fruit { @Override public void plant() { System.out.println("Oranges have been planted!"); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("Oranges is growing!"); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("Oranges have been harvested!"); } }
package com.lp.ecjtu.FactoryMethod; public class Grape implements Fruit { private String seedLess; public String isSeedLess() { return seedLess; } public void setSeedLess(String seedLess) { this.seedLess = seedLess; } @Override public void plant() { System.out.println("Grapes have been planted!"); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("Grapes is growing!"); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("Grapes have been harvested!"); } }
水果Client:FruitClient
package com.lp.ecjtu.FactoryMethod; public class FruitClient { /** * @param args */ public static void main(String[] args) { FruitGarden fa = new AppleGarden(); Fruit f = fa.factory(); f.plant(); f.grow(); f.harvest(); System.out.println("********************************"); FruitGarden fo = new OrangeGarden(); Fruit o = fo.factory(); o.grow(); o.harvest(); o.plant(); System.out.println("********************************"); FruitGarden fg = new GrapeGarden(); Fruit g = fg.factory(); g.grow(); g.harvest(); g.plant(); } }
输出结果:
Apples have been planted!
Apples is growing!
Apples have been harvested!
********************************
Oranges is growing!
Oranges have been harvested!
Oranges have been planted!
********************************
Grapes is growing!
Grapes have been harvested!
Grapes have been planted!