引言
今天回看之前总结的抽象工厂模式的实现《Java常用设计模式————抽象工厂模式》,聚焦于抽象工厂模式的缺点,试着改进了一下。
回顾一下抽象工厂模式的缺点:
在添加新的产品类型时,难以扩展抽象工厂来生产新种类的产品。
这是怎么回事呢?原来,老套的实现方式是为每种类型的产品都创建一个具体的工厂类,这个类只生产一种特定类型的产品。因此,当有新的类型的产品加入系统时,就必须添加一个对应的工厂类来支持这类产品,不仅不利于扩展,而且会增加大量的工厂类。
例如之前会有如下两个具体产品的工厂类来生产对应类型的产品:
今天试着使用泛型的方式,得出了一种更加通用的抽象工厂实现方式。可以避免大量工厂的再造。
实现
为了本篇文章的完整性,依然将全部实现过程贴出,各位同学可以与《Java常用设计模式————抽象工厂模式》进行比较阅读。
一、抽象化产品族
产品族的概念其实很好理解,每种类型的产品就是一个产品族,它包含多种不同的表现形式,例如汽车就是一个产品族,它包含卡车、轿车等,这些具体的产品隶属于汽车这个产品族。
如图所示,创建了电视产品族和汽车产品族。电视产品族包括索尼电视和夏普电视:
public interface Television {void play();
}
public class SonyTV implements Television{@Overridepublic void play() {System.out.println("SonyTV playing...");}
}
public class SharpTV implements Television{@Overridepublic void play() {System.out.println("SharpTV playing...");}
}
汽车产品族包括奥迪汽车和奔驰汽车:
public interface Car {void run();
}
public class Audi implements Car{@Overridepublic void run() {System.out.println("Audi running...");}
}
public class Benz implements Car{@Overridepublic void run() {System.out.println("Benz running...");}
}
二、创建抽象工厂及泛型工厂
抽象工厂是具体工厂的进一步抽象化,在原版的抽象工厂模式实现中,会存在多个具体的产品工厂,而在本例中,将会以泛型化的实现类来代替它们,而且即便再增加新的产品族也不需要修改泛型工厂:
public interface Factory<T> {T getProduct(Class<? extends T> clazz);
}
public class GenericFactory<T> implements Factory<T> {@Overridepublic T getProduct(Class<? extends T> clazz) {if (clazz == null)return null;try {T obj = (T) clazz.newInstance();return obj;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}
}
三、测试产品的生产
public class MyProgram {public static void main(String[] args) {Factory<Car> carFactory = new GenericFactory<>();Factory<Television> tvFactory = new GenericFactory<>();Car benz = carFactory.getProduct(Benz.class);Car audi = carFactory.getProduct(Audi.class);benz.run();audi.run();Television sonyTV = tvFactory.getProduct(SonyTV.class);Television sharpTV = tvFactory.getProduct(SharpTV.class);sonyTV.play();sharpTV.play();}
}
执行结果:
总结
抽象工厂是一种非常有趣的设计模式,它隔离了对象创建的过程,并且可以应用反射机制来完成这一经典的设计模式。但传统的实现需要具体每一个产品族的工厂,这样就依然没有提高通用性。本例中使用泛型的工厂方式,不需要为具体工厂的创建而增加新的编码。这种方式需要注意泛型的实现,使用<? extends T>可以完美的应对具体产品生产的需要。是一个非常不错的实现手段。
鸣谢
《Java常用设计模式————抽象工厂模式》
《Java泛型初探————泛型通配》