设计模式之抽象工厂模式
(一)什么是抽象工厂模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的。抽象工厂模式可以向客户端提供一个接口,是客户端不必指定产品具体类型的情况下,能够创建多个产品族的产品对象。可能说到这,很多人会对这个产品族不是概念模糊,下面我们会介绍到
(二)产品族和产品等级结构
在之后代码的演示中我们是以水果为例,所以在这里我们就以水果为例介绍产品族和产品等级。
在介绍什么是产品族之前,我们先介绍一下产品等级,这里所说的产品等级其实不过准确,更确切的说应该是产品的种类,就睡过而言,苹果,橘子就是不同的产品等级。而北方苹果、北方橘子就属于同一产品族,南方苹果和南方橘子也属于同一产品族。
概括而来,产品等级就是实现相同父接口的不同抽象类产品(不是具体的产品,还可以继续分类,比如抽象类苹果还可以继续分为南方苹果和北方苹果具体类),而产品族是指不同产品具有的相同特征的抽象,比如南方苹果和南方橘子都是南方的。
(三)抽象工厂模式中的角色
(1)抽象工厂角色
抽象工厂模式的核心,是以产品族的形式生产定义产品的生成,任何具体工厂类必须实现这个接口
(2)具体工厂角色
具体工厂角色是抽象工厂的一个实现,负责实例化某个产品族中的产品。可以看出在抽象工厂模式中,有具体工厂有多个,每个具体工厂不是生产同一类产品(比如只生产苹果),而是生产多种类别的产品,但是必须保证这些类别具有共同抽象出来的特征(比如可以生产南方的苹果和南方的的橘子)。
(3)抽象产品角色
所创建的所有对象的父类。
(4)具体产品角色
抽象模式所创建的具体实例对象。
(四)抽象工厂模式实现
抽象工厂为FruitFactory接口,有两个抽象方法:getApple()、getOrange()方法。
public interface FruitFactory { Fruit getApple(); Fruit getOrange(); }
具体工厂类有两个,一个是SouthFruitFactory,用于生产南方水果(产生具体的对象:南方苹果和南方橘子);一个是NorthFruitFactory,用于生产北方水果(产生具体对象:北方苹果和北方橘子)。
public class NorthFruitFactory implements FruitFactory { @Override public Fruit getApple() { return new NorthApple(); } @Override public Fruit getOrange() { return new NorthOrange(); } }
public class SouthFruitFactory implements FruitFactory { @Override public Fruit getApple() { return new SouthApple(); } @Override public Fruit getOrange() { return new SouthOrange(); } }
Friut接口为所有产品的的父接口。
public interface Fruit { void get(); }
另外还涉及到两个抽象类,分别为Apple和Orange,都实现了Fruit接口
public abstract class Apple implements Fruit { } public abstract class Orange implements Fruit { }
具体产品类包括四个,分别为SouthApple、NorthApple(这两个继承Apple)、SouthOrange、NorthApple(这两个继承Orange)
public class NorthApple extends Apple { @Override public void get() { System.out.println("采摘北方苹果"); } } public class SouthApple extends Apple { @Override public void get() { System.out.println("采摘南方苹果"); } } public class NorthOrange extends Orange { @Override public void get() { System.out.println("采摘北方橘子"); } } public class SouthOrange extends Orange { @Override public void get() { System.out.println("采摘南方橘子"); } }
测试:
public class Test { public static void main(String[] args) { NorthFruitFactory nff = new NorthFruitFactory(); Fruit northApple = nff.getApple(); Fruit northOrange = nff.getOrange(); northApple.get(); northOrange.get(); SouthFruitFactory sff = new SouthFruitFactory(); Fruit southApple = sff.getApple(); Fruit southOrange = sff.getOrange(); southApple.get(); southOrange.get(); } }
(五)抽象工厂模式的优缺点
抽象工厂模式在产品等级(产品种类)确定的情况下,可以在不修改源代码的情况下,只需增加具体工厂类就可以有工厂类产生新的对象;而如果要是增加产品的类别,抽象工厂方法不适合。
简言之,抽象工厂方法适用于产品等级数量确定的情况,可为产品增加新的产品族。