设计模式之abstract factory(抽象工厂)

来源:互联网 发布:门诊系统的数据库设计 编辑:程序博客网 时间:2024/06/05 08:03
1、意图
创建一系列相关或互相依赖得对象得接口。
2、参与者关系

3、效果
a、当提供库得时候,使用这种方式来创建对象,可以使得客户只和类得接口打交道,而隐藏其实现。
b、当需要更换另一系列得产品时,只需要重新实现一个子类,并且在创建工厂实例得时候改变以下代码,其余代码都保持不变,也可以在运行状态通过一个参数来改变创建工厂实例得行为。
c、保证一个应用只使用同一系列得产品,因为所有相关联得产品都在同一个工厂里面创建。
d、不足之处在于需要在一个系列中增加一种产品得时候,必须在每一个工厂里面增加一个函数。
4、举例
如果我们得应用程序需要同时支持android和ios两种操作系统,但是不同操作系统下,有其自己得一套实现方案,并且以后我们有可能还需要增加windowsphone等更多得平台,那么我们就可以先对我们得底层实现方案进行抽象,然后对每一种平台产生一个子类。

interface A  {
void f();
void g();
}

interface B {
void b();
void a();
}

class IosA  implements A {
public void f() {}
public void g() {}
}

class AndroidA implements A {
public void f()
public void g()
}

class IosB implements B {
public void b() {}
public void a() {}
}

class AndroidB implements B {
public void b() {}
public void a() {}
}

public class Test {
public static void main(String[] args) {
A a1 = new IosA();
B b1 = new IosB();
a1.f(); b1.a();
A a2 = new IosA();
B b2 = new IosB();
a2.g(); b2.b();
}
}

在以上得代码中,如果我们需要把应用更换为android,那么就需要将上面所有得IosA和IosB创建得地方都改为AndroidA和AndroidB,并且必须重新编译,如果这些创建代码散落程序得各个角落,那么还有可能会漏改一些地方,编译也不会报错,无形中增加了代码得维护成本。因此这里我们可以使用一个abstract factory来帮助我们完成对象得实例化。下面增加如下代码
instance Factory {
A createA();
B createB();
}

class IosFactory implements Factory {
public A createA() {
return new IosA();
}
public B createB() {
return new IosB();
}
}

class AndroidFactory implements Factory {
public A createA() {
return new AndroidA();
}
public B createB() {
return new AndroidB();
}
}
然后test代码可以修改如下
public class Test {
public static void main(String[] args) {
Factory fac = new IosFactory();
A a1 = fac.createA();
B b1 = fac.createB();
a1.f(); b1.a();
A a2 = fac.createA();
B b2 = fac.createB();
a2.g(); b2.b();
}
}
当需要修改得时候只需要修改初始化fac的代码
Factory fac = new AndroidFactory();

当然还可以修改代码使它在运行的时候根据不同的系统来自动改变创建行为。
public class Test {
public static void main(String[] args) {
String sys = getSystemType();
Factory fac = null;
if (sys.equals(“IOS”)) {
fac = new IosFactory();
} else (sys.equals(“ANDROID”)) {
fac = new AndroidFactory();
}
A a1 = fac.createA();
B b1 = fac.createB();
a1.f(); b1.a();
A a2 = fac.createA();
B b2 = fac.createB();
a2.g(); b2.b();
}
}
其中getSystemType可以从一个配置文件中获取系统类型。
0 0
原创粉丝点击