简单工厂模式(静态工厂方法模式)就是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例。其结构如下图所示:
简单工厂模式涉及到工厂角色、抽象产品角色和具体产品角色。
(1)工厂类(Creator)角色:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,镪往往由一个具体Java类实现。
(2)抽象产品(Product)角色:担任这个角色的类是由工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个Java接口或者Java抽象类实现。
(3)具体产品(ConcreteProduct)角色:工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体Java类实现。
源代码:
抽象产品(Product)接口
public interface Product { }
具体产品(ConcreteProduct)类
public class ConcreteProduct implements Product{ public ConcreteProduct(){ } }
工厂类(Creator)
public class Creator { public static Product factory(){ return new ConcreteProduct(); } }
最后我们来看个例子:
比如有一个农场公司,专门向市场销售各类水果:葡萄(Grape)、草莓(Strawberry)、苹果(Apple)。水果(Fruit)接口规定所有水果必须实现的接口,包括任何水果类必须具备的方法: 种植plant(),生长grow(),收获harvest()。
Fruit接口
public interface Fruit { void grow(); void harvest(); void plant(); }
Apple类
public class Apple implements Fruit { public void grow() { System.out.println("Apple is growing..."); } public void harvest() { System.out.println("Apple has been harvested."); } public void plant() { System.out.println("Apple has been planted."); } public int getTreeAge(){ return treeAge; } public void setTreeAge(int treeAge){ this.treeAge = treeAge; } private int treeAge; }
Grape类
public class Grape implements Fruit { public void grow() { System.out.println("Grape is growing..."); } public void harvest() { System.out.println("Grape has been harvested."); } public void plant() { System.out.println("Grape has been planted."); } public boolean getSeedless() { return seedless; } public void setSeedless(boolean seedless) { this.seedless = seedless; } private boolean seedless; }
Strawberry类
public class Strawberry implements Fruit { public void grow() { System.out.println("Strawberry is growing..."); } public void harvest() { System.out.println("Strawberry has been harvested."); } public void plant() { System.out.println("Strawberry has been planted."); } }
FruitFactory类
public class FruitFactory { public static Fruit factory(String which) throws BadFruitException { if (which.equalsIgnoreCase("apple")) { return new Apple(); } else if (which.equalsIgnoreCase("strawberry")) { return new Strawberry(); } else if (which.equalsIgnoreCase("grape")) { return new Grape(); } else { throw new BadFruitException("Bad fruit request"); } } }
简单工厂模式的优点:
简单工厂模式的核心是工厂类,这个类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,而客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品,简单工厂模式通过这种做法实现 了对责任的分割。
简单工厂模式的缺点:
(1)工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,它什么时候不工作了,影响很大。
(2)当产品类有不同的接口种类时,工厂类需要判断在什么时候创建某种产品。这种对时机的判断和对哪一种具体产品的判断逻辑混合在一起,使得系统在将来进行功能扩展较为困难。
(3)由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。
简单工厂方法与开闭原则:
开闭原则要求一个 系统的设计能够允许系统在无须修改的情况下,扩展其功能。
对于产品消费角色来说,任何时候需要某种产品,只需向工厂角色请求即可。而工厂角色在接到请求后,会自行判断创建和提供哪一个产品。所以,产品消费角色无需知道它得到的是哪一个产品;换言之,产品消费角色无需修改就可以接纳新的产品。
对于工厂角色而言,增加 新产品是一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户端提供它们。换言之,接纳新的产品意味着修改这个工厂角色的源码。
开闭原则要求系统允许当新的产品加入系统中时,而无需对现有代码进行修改。这一点对于产品的消费角色是成立的,而对于工厂角色是不成立的。
综上,简单工厂模式只在有限的程度上支持“开闭”原则。