一直对简单工厂、工厂方法、抽象工厂三种设计模式的认识比较模糊,特别是工厂方法和抽象工厂方法模式,容易混淆。今天特别针对这三种设计模式学习了一下,整理下自己的理解。
简单工厂模式(Simple Factory),又称静态工厂方法模式,属于工厂方法模式中的特例,所以GOF在《设计模式》一书中把它归为工厂方法模式。下面是从其他博客摘录的例子:
产品类:
- abstract class BMW {
- public BMW(){
- }
- }
- public class BMW320 extends BMW {
- public BMW320() {
- System.out.println("制造-->BMW320");
- }
- }
- public class BMW523 extends BMW{
- public BMW523(){
- System.out.println("制造-->BMW523");
- }
- }
工厂类:
- public class Factory {
- public BMW createBMW(int type) {
- switch (type) {
- case 320:
- return new BMW320();
- case 523:
- return new BMW523();
- default:
- break;
- }
- return null;
- }
- }
客户类:
- public class Customer {
- public static void main(String[] args) {
- Factory factory = new Factory();
- BMW bmw320 = factory.createBMW(320);
- BMW bmw523 = factory.createBMW(523);
- }
- }
该设计模式合适的应用场景:所有的产品一开始就都已知并且永远不会更改,这样可以都在同一个工厂中被创建。
想象一下这样的场景,如果设计一个jar包给别人使用,别人的需求随时变化,需要随时调整产品策略,设计出符合他们需求的产品类(例如新增产品),如果使用简单工厂模式,每次别人新增产品的时候,都需要修改工厂方法,重新打包给别人引用。这样的设计简直就是灾难!
工厂方法(Factory Method)模式,分别将产品和工厂抽象出来。针对产品变更频繁的应用场景,工厂方法模式可谓应运而生:
产品类:
- abstract class BMW {
- public BMW(){
- }
- }
- public class BMW320 extends BMW {
- public BMW320() {
- System.out.println("制造-->BMW320");
- }
- }
- public class BMW523 extends BMW{
- public BMW523(){
- System.out.println("制造-->BMW523");
- }
- }
创建工厂类:
- interface FactoryBMW {
- BMW createBMW();
- }
- public class FactoryBMW320 implements FactoryBMW{
- @Override
- public BMW320 createBMW() {
- return new BMW320();
- }
- }
- public class FactoryBMW523 implements FactoryBMW {
- @Override
- public BMW523 createBMW() {
- return new BMW523();
- }
- }
客户类:
- public class Customer {
- public static void main(String[] args) {
- FactoryBMW320 factoryBMW320 = new FactoryBMW320();
- BMW320 bmw320 = factoryBMW320.createBMW();
- FactoryBMW523 factoryBMW523 = new FactoryBMW523();
- BMW523 bmw523 = factoryBMW523.createBMW();
- }
- }
该设计模式适合的应用场景:用户可以根据自己需求,轻松扩展产品类和工厂方法类,而不需要修改原来的jar包的实现。符合OCP原则,即开闭原则。
针对同一产品族,即实现统一产品接口的所有产品类,工厂方法模式确实很灵活。实际上这是一个粗粒度的灵活,带来的问题也很多。一、工厂方法类增多;二、如果新增的不是产品,而是产品族(即产品接口)呢?三、如果多个产品族之间有联系,如何解耦呢?
我们以上面例子中的车为例,如果新的产品是空调车。很明显,车和空调不属于一个产品族,我们很自然的会定义两种接口。如果这两种产品族没有任何联系,可以分别创建两套工厂方法,问题来了,空调和车是有联系的,当然,我们可以根据排列组合,在空调的工厂方法中new车,或者在车的工厂方法中new空调,但是这样耦合性太强。抽象工厂(Abstract Factory)模式应运而生了。在相同的工厂接口中定义了两种产品族的创建接口,这样,将两种产品族轻松的联系在一起。
产品类:
- //车子以及型号
- abstract class BMW {
- public BMW(){
- }
- }
- public class BMW320 extends BMW {
- public BMW320() {
- System.out.println("制造-->BMW320");
- }
- }
- public class BMW523 extends BMW{
- public BMW523(){
- System.out.println("制造-->BMW523");
- }
- }
- //空调以及型号
- public class Aircondition {
- public Aircondition(){
- }
- }
- public class AirconditionA extends Aircondition{
- public AirconditionA(){
- System.out.println("制造-->AirconditionA");
- }
- }
- public class AirconditionB extends Aircondition{
- public AirconditionB(){
- System.out.println("制造-->AirconditionB");
- }
- }
创建工厂类:
- //创建工厂的接口
- public interface FactoryBMW {
- BMW createBMW_A();
- BMW createBMW_B();
- Aircondition createaAirconditionA();
- Aircondition createaAirconditionB();
- }
- //宝马320系列,生产配置A,B两种空调型号的320汽车
- public class FactoryBWM320 implements FactoryBMW{
- @Override
- public BMW320 createBMW_A() {
- // TODO Auto-generated method stub
- createaAirconditionA();
- return new BMW320();
- }
- @Override
- public BMW320 createBMW_B() {
- // TODO Auto-generated method stub
- createaAirconditionB();
- return new BMW320();
- }
- @Override
- public Aircondition createaAirconditionA() {
- // TODO Auto-generated method stub
- return new AirconditionA();
- }
- @Override
- public Aircondition createaAirconditionB() {
- // TODO Auto-generated method stub
- return new AirconditionB();
- }
- }
- //宝马523系列,生产配置A,B两种空调型号的523汽车
- public class FactoryBWM523 implements FactoryBMW {
- @Override
- public BMW523 createBMW_A() {
- // TODO Auto-generated method stub
- createaAirconditionA();
- return new BMW523();
- }
- @Override
- public BMW523 createBMW_B() {
- // TODO Auto-generated method stub
- createaAirconditionB();
- return new BMW523();
- }
- @Override
- public Aircondition createaAirconditionA() {
- // TODO Auto-generated method stub
- return new AirconditionA();
- }
- @Override
- public Aircondition createaAirconditionB() {
- // TODO Auto-generated method stub
- return new AirconditionB();
- }
- }
客户:
- public class Customer {
- public static void main(String[] args){
- //想要A型空调宝马320
- FactoryBWM320 factoryBWM320_A = new FactoryBWM320();
- BMW320 bmw320_A = factoryBWM320_A.createBMW_A();
- //想要B型空调宝马320
- FactoryBWM320 factoryBWM320_B = new FactoryBWM320();
- BMW320 bmw320_B = factoryBWM320_B.createBMW_B();
- //想要A型空调宝马523
- FactoryBWM523 factoryBWM523_A = new FactoryBWM523();
- BMW523 bmw523_A = factoryBWM523_A.createBMW_A();
- //想要B型空调宝马523
- FactoryBWM523 factoryBWM523_B = new FactoryBWM523();
- BMW523 bmw523_B = factoryBWM523_B.createBMW_B();
- }
- }
总结:三种设计模式均属于创建型模式。简单工厂模式到工厂方法模式解决的是灵活性、可扩展问题,工厂方法模式到抽象工厂方法模式解决的是不同产品族的耦合问题。当然,三种设计模式都降低了对产品类的耦合。
以上是我对着三种设计模式的一点理解,求指正~
参考:http://blog.youkuaiyun.com/jason0539/article/details/23020989