• 欢迎访问 winrains 的个人网站!
  • 本网站主要从互联网整理和收集了与Java、网络安全、Linux等技术相关的文章,供学习和研究使用。如有侵权,请留言告知,谢谢!

图解设计模式(4):Factory Method模式(将实例的生成交给子类)

设计模式 winrains 1年前 (2019-09-19) 42次浏览

父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。这样可以将生成实例的框架和实际负责生成实例的类解耦。

1 Factory Method模式中的角色

  • Product(产品)

Product角色属于框架这一方,是一个抽象类。它定义了在Factory Method模式中生成的那些实例所持有的接口。但具体的处理则由子类ConcreateProduct角色决定。在示例中,对应Product类。

  • Creator(创建者)

Creator角色属于框架这一方,它是负责生成Product角色的抽象类,但具体的处理则由子类ConcreateCreator角色决定。在示例中,对应Factory类。
Creator角色对于实际负责生成实例的ConcreteCreator角色一无所知,它唯一知道的就是,只要调用Product角色和生成实例的方法(factoryMethod方法),就可以生成Product的实例。在示例中,createProduct方法是用于生成实例的方法。不用new关键字来生成实例,而是调用生成实例的专用方法来生成实例,这样就可以防止父类与其它具体类耦合。

  • ConcreateProduct(具体的产品)

ConcreateProduct角色属于具体加工这一方,它决定了具体的产品。在示例中,对应IDCard类。

  • ConcreateCreator(具体的创建者)

ConcreateCreator角色属于具体加工这一方,它负责生成具体的产品。在示例中,对应IDCardFactory类。

2 Factory Method模式的类图

3 示例程序

3.1 类一览表

名字 说明
framework Product 只定义抽象方法use的抽象类
framework Factory 实现了create方法的抽象类
idcard IDCard 实现了use方法的类
idcard IDCardFactory 实现了createProduct、registerProduct方法的类
无名 Main 测试程序行为的类

3.2 类图

3.3 示例代码

Product类

用来表示“产品”的类,在该类中仅声明了use抽象方法,具体实现交由子类去完成。

package framework;
public abstract class Product {
    public abstract void use();
}

Factory类

使用了Template Method模式,声明了用于“生成产品”和createProduct抽象方法和用于“注册产品”的registerProduct抽象方法。

package framework;
public abstract class Factory {
    public final Product create(String owner) {
        Product p = createProduct(owner);
        registerProduct(p);
        return p;
    }
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}

IDCard类

Product的子类,表示ID卡的类。

package idcard;
import framework.*;
public class IDCard extends Product {
    private String owner;
    IDCard(String owner) {
        System.out.println("制作" + owner + "的ID卡。");
        this.owner = owner;
    }
    public void use() {
        System.out.println("使用" + owner + "的ID卡。");
    }
    public String getOwner() {
        return owner;
    }
}

IDCardFactory类

Factory类的子类。

package idcard;
import framework.*;
import java.util.*;
public class IDCardFactory extends Factory {
    private List owners = new ArrayList();
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }
    protected void registerProduct(Product product) {
        owners.add(((IDCard)product).getOwner());
    }
    public List getOwners() {
        return owners;
    }
}

Main类

测试程序。

import framework.*;
import idcard.*;
public class Main {
    public static void main(String[] args) {
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("小明");
        Product card2 = factory.create("小红");
        Product card3 = factory.create("小刚");
        card1.use();
        card2.use();
        card3.use();
    }
}

运行结果

制作小明的ID卡。
制作小红的ID卡。
制作小刚的ID卡。
使用小明的ID卡。
使用小红的ID卡。
使用小刚的ID卡。

4 框架与具体加工

可以使用相同的框架创建出其他的产品和工厂。例如,我们这次要创建表示电视机类的Televison和表示电视机工厂类的TelevisonFactory,这时,我们只需要引入framework包就可以编写televison包。
请注意:这里我们没有修改,也根本没有必要修改framework包中的任何内容,就可以创建出其他的产品和工厂。
framework包中我们并没有引入idcard包,在Product类和Factory类中,并没有出现IDCardIDCardFactory等具体类的名字。因此,即使用已有的框架生成全新的类时,也完全不需要对framework进行修改,即不需要“将televison包引入到框架中”。关于这一点,我们称作是“framework包不依赖于idcard包”。

摘自《图解设计模式》


版权声明:文末如注明作者和来源,则表示本文系转载,版权为原作者所有 | 本文如有侵权,请及时联系,承诺在收到消息后第一时间删除 | 如转载本文,请注明原文链接。
喜欢 (1)