设计模式(三):抽象工厂模式
一、概念
抽象工厂模式 是所有形态的工厂模式中,最为抽象和最具一般性的。它可以向客户端提供一个接口。使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
二、实现
昨天,我们的工厂模式的核心类是FruitFactory工厂接口,然后再定义了两个具体工厂类AppleFactory和BananaFactory。而今天,我们厂的大boss又提出了新需求----每种水果又有了产地,比如苹果(Apple)分了北方苹果(NorthApple)和南方苹果(SouthApple),香蕉水果也是如此。没法子,老板说啥就是啥,干活吧!
-
因为苹果(Apple)又分了北方和南方的,所以应该把Apple改成抽象类,并让NorthApple和SouthApple继承于它,香蕉(Banana)同理。
//Apple抽象父类 public abstract class Apple extends Fruit { public abstract void get(); } //北方苹果 public class NorthApple extends Apple { @Override public void get() { System.out.println("采集North苹果"); } } //南方苹果 public class SouthApple extends Apple { @Override public void get() { System.out.println("采集South苹果"); } } //香蕉代码同上,这里就不粘贴了
-
之前我们是按照水果种类划分出了两个具体工厂类----AppleFactory和BananFactory,但现在每种水果有了不同种族(这里是产地),因此,这两个工厂类已不再适用,我们应该按照种族来划分具体工厂类,可以划分成:NorthFruitFactory 与 SouthFruitFactory,它们都是实现于FruitFactory这个抽象工厂接口
//FruitFactory抽象功能类 public interface FruitFactory { Apple getApple(String clsName) throws Exception; Banana getBanana(String clsName)throws Exception; } //NorthFruitFactory具体生产工厂类 public class NorthFruitFactory implements FruitFactory { @Override public Apple getApple(String clsName) throws Exception{ Class<?> cls = Class.forName(clsName); if(cls==NorthApple.class){ return NorthApple.class.newInstance(); } else { throw new Exception("创建Apple水果实例失败"); } } @Override public Banana getBanana(String clsName) throws Exception { Class<?> cls = Class.forName(clsName); if(cls==NorthBanana.class){ return NorthBanana.class.newInstance(); } else { throw new Exception("创建Banana水果实例失败"); } } } //SouthFruitFactory具体生产工厂类 public class SouthFruitFactory implements FruitFactory { @Override public Apple getApple(String clsName) throws Exception{ Class<?> cls = Class.forName(clsName); if(cls==SouthApple.class){ return SouthApple.class.newInstance(); } else { throw new Exception("创建Apple水果实例失败"); } } @Override public Banana getBanana(String clsName) throws Exception { Class<?> cls = Class.forName(clsName); if(cls==SouthBanana.class){ return SouthBanana.class.newInstance(); } else { throw new Exception("创建Banana水果实例失败"); } } }
-
测试
public static void main(String[] args) throws Exception{ FruitFactory nff=new NorthFruitFactory(); Apple northApple = nff.getApple("com.tys.abstractfactory.NorthApple"); northApple.get(); Banana northBanana = nff.getBanana("com.tys.abstractfactory.NorthBanana"); northBanana.get(); FruitFactory sff=new SouthFruitFactory(); Apple southApple = sff.getApple("com.tys.abstractfactory.SouthApple"); southApple.get(); Banana southBanana = sff.getBanana("com.tys.abstractfactory.SouthBanana"); southBanana.get(); }
-
思考:其实最开始,我个人感觉NorthFruitFactory和SouthFruitFactory这两个类代码相仿,于是我就把用反射写成了一个类,把代码精简了。但是,后面一想,代码是少了,可是貌似又违背了开闭-关闭原则。。
三、总结
- 该模式中包含的角色与职责:
- 1.抽象工厂(Creator)角色:抽象工厂的核心, 包含对多个产品结构的声明,任何工厂类都必须实现这个接口
- 2.具体工厂类(Concrete Creator):具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象
- 3.抽象(Product)角色:抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口
- 4.具体产品(Concrete Product)角色:抽象模式所创建的具体实例对象
- 总的来说,抽象工厂模式是各种形态的工厂模式中,最贴近生活场景的一种,同时也是最复杂的一种。万物有弊有利,虽然复杂,但是它的拓展性是很好的。