您的位置:首页 > 编程语言 > Java开发

Java 之 简单工厂模式

2016-06-29 19:59 357 查看

定义

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
定义中最重要的一句话就是,由一个工厂对象决定创建出哪一种产品类的实例。

类图



角色

1. 工厂类(Creator): 工厂类在客户端的直接调用下创建对象,它往往有一个具体的java类实现。

2. 抽象产品(Product) : 担任这个角色的类是由工厂方法模式所创建的对象的父类,或者他们拥有共同的接口。抽象产品角色可以用一个Java接口或者Java抽象类实现。

3. 具体产品(Concrete Product):工厂方法模式创建的任何对象都是这个角色的实例,具体产品由一个具体的Java类实现。当然具体产品不只有一个。

示例

抽象产品:

public interface IProduct {

public void method();
}

具体产品:

public class ProductA implements IProduct{

public void method() {
System.out.println("产品A方法");
}

}

public class ProductB implements IProduct{

public void method() {
System.out.println("产品B方法");
}

}

工厂类:

public class Creator {

private Creator(){}

public static IProduct createProduct(String productName){
if (productName == null) {
return null;
}
if (productName.equals("A")) {
return new ProductA();
}else if (productName.equals("B")) {
return new ProductB();
}else {
return null;
}
}
}

客户端调用:

public class Client {

public static void main(String[] args) {
IProduct product1 = Creator.createProduct("A");
product1.method();

IProduct product2 = Creator.createProduct("B");
product2.method();
}
}

输出:

===============================
产品A 方法
产品B 方法

引文:Java 与 模式

使用Java接口或者Java抽象类

如果模式所产生的具体产品彼此之间没有共同的商业逻辑,那么抽象产品就可以由一个Java接口扮演,相反,如果这些具体的产品批次之间确实有共同的商业逻辑,那么这些拥有的逻辑就应该移到抽象角色里面,这就意味着抽象角色由一个抽象类扮演,在一个类型的等级结构里面,共同的代码应当尽量向上移动,已达到共享的目的。

多个工厂方法

每个工厂类可以有多于一个的工厂方法,分别负责创建不同的产品对象。比如DateFormat类就是其子类的工厂类,而DateFormat类就提供了多个静态工厂方法。

抽象产品角色的省略

如果系统仅有一个具体产品的话,就可以省略掉抽象产品类,略.....

工厂角色与抽象产品合并

在有些情况下,工厂角色可以由抽象产品角色扮演,典型的应用还是DateFormat类,一个抽象产品同时是子类的工厂

开-闭原则

对于产品消费角色(Client)来说,任何时候需要某种产品,只需要向工厂角色请求即可,产品消费角色无需知道得到的是哪一个产品,换言之,产品消费角色无需修改就可以接纳新产品。对于工厂角色来说,新怎么产品意为着工厂必须知道如何创建他们,必须要修改工厂类。所以简单工厂模式对开-闭原则支持的不够。

DateFormat 与 简单工厂模式

DateFormat是一个抽象类,它的具体实现子类为SimpleDateFormat。但是DateFormat却提供了跟多静态工厂方法类,比如getDateInstance()。第一次接触这个类的初级程序员会有一些困惑,抽象类怎么可以有自己的实例,并通过几个方法提供自己的实例。实际上一个抽象类不能够有自己的实例这是正确的。DateFormat的getDateInstance()是静态工厂方法,并不是普通的方法。它并没有调用自己的构造函数,它所做的事情基本上就是两件,运用多态和调用静态工厂方法。

因为SimpleDateFormat是抽象类DateFormat的具体子类,这意味着该静态工厂方法返回的是SimpleDateFormat的实例,用DateFormat接收,这是最纯正的多态的运用。

如果这是一个非静态方法,客户端首先要获取DateFormat的实例,但是抽象类不可能有实例,客户端只能获取子类的实例,但是如果客户端能获取子类的实例,要静态工厂方法做什么,显然,这是为了将具体子类的实例化隐藏起来,因为DateFormat抽象类提供了子类的实例,这是一个简单工厂方法绝佳的应用。当然getTimeInstance()方法也是这样的道理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: