您的位置:首页 > 其它

设计模式之——抽象工厂设计模式

2016-09-21 16:57 543 查看
开篇致谢:http://www.cnblogs.com/zuoxiaolong/p/pattern6.html

它与工厂方法唯一的区别就是工厂的接口里是一系列创造抽象产品的方法,而不再是一个,而相应的,抽象产品也不再是一个了,而是一系列相关的产品。与此对应的就要对对应的产品及进行实现。

比方说我们定义了一系列产品IProduct1,IProduct2要同时生产这两个产品

package com.zndroid.dm.FactoryModel.AbstractFactory;

/**
* Created by luzhenyu on 2016/9/21.
*/
public interface IProduct1 {
void product1Method();
}
package com.zndroid.dm.FactoryModel.AbstractFactory;

/**
* Created by luzhenyu on 2016/9/21.
*/
public interface IProduct2 {
void product2Method();
}
产品具体实现如下:
package com.zndroid.dm.FactoryModel.AbstractFactory.impl;

import com.zndroid.dm.FactoryModel.AbstractFactory.IProduct1;

/**
* Created by luzhenyu on 2016/9/21.
*/
public class Product1 implements IProduct1 {
@Override
public void product1Method() {
System.out.println("Product1 's method");
}
}
package com.zndroid.dm.FactoryModel.AbstractFactory.impl;

import com.zndroid.dm.FactoryModel.AbstractFactory.IProduct2;

/**
* Created by luzhenyu on 2016/9/21.
*/
public class Product2 implements IProduct2 {
@Override
public void product2Method() {
System.out.println("product2 's method");
}
}
创建一个工厂接口用于生产这两件产品:

package com.zndroid.dm.FactoryModel.AbstractFactory;

/**
* Created by luzhenyu on 2016/9/21.
*/
public interface IAbstractFactory {
IProduct1 getProduct1();
IProduct2 getProduct2();
}
具体实现该工厂:

package com.zndroid.dm.FactoryModel.AbstractFactory.impl;

import com.zndroid.dm.FactoryModel.AbstractFactory.IAbstractFactory;
import com.zndroid.dm.FactoryModel.AbstractFactory.IProduct1;
import com.zndroid.dm.FactoryModel.AbstractFactory.IProduct2;

/**
* Created by luzhenyu on 2016/9/21.
*/
public class AbstractCreate implements IAbstractFactory {
@Override
public IProduct1 getProduct1() {
return new Product1();
}

@Override
public IProduct2 getProduct2() {
return new Product2();
}
}
至此就可以通过如下使用,来创建这两个产品了

log("----------------我是分割线-----------------");
IAbstractFactory mAbstractFactory = new AbstractCreate();
Product1 mProduct1 = (Product1) mAbstractFactory.getProduct1();
Product2 mProduct2 = (Product2) mAbstractFactory.getProduct2();

mProduct1.product1Method();
mProduct2.product2Method();

log("========================================");
最后总结:

1,首先从简单工厂进化到工厂方法,是因为工厂方法弥补了简单工厂对修改开放的弊端,即简单工厂违背了开闭原则。

2,从工厂方法进化到抽象工厂,是因为抽象工厂弥补了工厂方法只能创造一个系列的产品的弊端。

还有一个用处是:

有一套产品是一个第三方的jar包提供的。我们有我们的另外一个产品,那么为了扩展这个第三方的jar包,我们可以将jar包中的工厂方法模式扩展成为抽象工厂来达到我们扩展现有类功能的目的。(想到了采用继承的方式:好处是我们可以完整的复用jar包中的各个类功能,缺点是继承会导致系统的复杂性增加,耦合度相对较高。),鉴于此,抽象工厂设计模式就有了用武之地。另外一种做法,就是创造我们自己的一套独有的工厂方法模式,这套体系与jar包中的类和接口毫无关系,我们再使用一个组合工厂将二者结合起来,如下:

//抽象产品
interface Product{}

//具体产品
class ProductA implements Product{}
class ProductB implements Product{}

//工厂接口
interface Factory{
Product getProduct();
}

//具体的工厂A,创造产品A
class FactoryA implements Factory{

public Product getProduct() {
return new ProductA();
}

}
//具体的工厂B,创造产品B
class FactoryB implements Factory{

public Product getProduct() {
return new ProductB();
}

}

/*   假设以上是一个第三方jar包中的工厂方法模式,我们无法改动源码   */

//我们自己特有的产品
interface MyProduct{}

//我们自己特有的产品实现
class MyProductA implements MyProduct{}
class MyProductB implements MyProduct{}

//我们自己的工厂接口
interface MyFactory{
MyProduct getMyProduct();
}

//我们自己特有的工厂A,产生产品A
class MyFactoryA implements MyFactory{

public MyProduct getMyProduct() {
return new MyProductA();
}

}

//我们自己特有的工厂B,产生产品B
class MyFactoryB implements MyFactory{

public MyProduct getMyProduct() {
return new MyProductB();
}

}

/*  到这里是我们自己的一套工厂方法模式,去创造我们自己的产品,以下我们将以上二者组合   */

//我们使用组合的方式将我们的产品系列和jar包中的产品组合起来
class AssortedFactory implements MyFactory,Factory{

MyFactory myFactory;
Factory factory;

public AssortedFactory(MyFactory myFactory, Factory factory) {
super();
this.myFactory = myFactory;
this.factory = factory;
}

public Product getProduct() {
return factory.getProduct();
}

public MyProduct getMyProduct() {
return myFactory.getMyProduct();
}

}
 可以看到,组合的工厂AssortedFactory集成了我们自己的工厂和jar包中的工厂两者的功能。这样做则会非常灵活,因为我们的一套体系不再依赖于jar包中的类或接口而存在,哪怕是jar包中的类改变或者不在了,我们自己的这一套依旧可以独立存在。

【欢迎上码】
【微信公众号搜索 h2o2s2】

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息