设计模式学习笔记——工厂(Factory)模式

设计模式学习笔记——工厂(Factory)模式

@(设计模式)[设计模式, 工厂模式, factory]

基本介绍

工厂(Factory)模式可以看作模版模式的一种固定实现,如果用模版模式生成实例,这就可以视为工厂模式。

在工厂模式中,抽象的工厂类(父类)决定实例的生成方式和内部细节,但是并不决定所要生成的具体的类,具体的处理全权由具体的工厂类(子类)负责。也就是说抽象的工厂类并不知道自己要生成什么具体的产品,只要是其生成的抽象的产品类的子类就行了。

通过以上方式,可以很方便的将工厂类、产品类(父类)和它们的实现类进行解耦。比如说可以将父类放在framework包中,子类放在其自己的包中。

工厂案例

类图

工厂案例类图

实现代码

framework包
Product抽象类
package com.pc.factory.example.framework;

/**
 * 产品类
 * Created by Switch on 2017-02-09.
 */
public abstract class Product {
    /**
     * 使用
     */
    public abstract void use();
}
Factory抽象类
package com.pc.factory.example.framework;

/**
 * 工厂类
 * Created by Switch on 2017-02-09.
 */
public abstract class Factory {
    /**
     * 创建产品
     *
     * @param owner 所有者
     * @return 产品
     */
    public final Product create(String owner) {
        // 创建产品
        Product product = this.createProduct(owner);
        // 注册产品
        this.registerProduct(product);
        return product;
    }

    /**
     * 创建产品
     *
     * @param owner 所有者
     * @return 产品
     */
    protected abstract Product createProduct(String owner);

    /**
     * 注册产品
     *
     * @param product 产品
     */
    protected abstract void registerProduct(Product product);
}
idcard包
IDCard类
package com.pc.factory.example.idcard;

import com.pc.factory.example.framework.Product;

/**
 * IDCard类
 * Created by Switch on 2017-02-09.
 */
public class IDCard extends Product {
    // 所有者
    private String owner;

    /**
     * 构造方法,需要提供所有者<br/>
     * 这里有个优化,访问范围为包内,也就是说只能让IDCardFactory创建实例
     *
     * @param owner 所有者
     */
    IDCard(String owner) {
        System.out.println("制作" + owner + "的ID卡。");
        this.owner = owner;
    }

    @Override
    public void use() {
        System.out.println("使用" + owner + "的ID卡。");
    }

    /**
     * 获取所有者
     *
     * @return 所有者
     */
    public String getOwner() {
        return this.owner;
    }
}
IDCardFactory类
package com.pc.factory.example.idcard;

import com.pc.factory.example.framework.Factory;
import com.pc.factory.example.framework.Product;

import java.util.HashMap;
import java.util.Map;

/**
 * IDCard工厂类
 * Created by Switch on 2017-02-09.
 */
public class IDCardFactory extends Factory {
    // ID卡所有者Map集合
    private Map<String, Product> owners = new HashMap<>();

    @Override
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }

    @Override
    protected void registerProduct(Product product) {
        this.owners.put(((IDCard) product).getOwner(), product);
    }

    /**
     * 获取ID卡所有者Map集合
     *
     * @return ID卡所有者Map集合
     */
    public Map<String, Product> getOwners() {
        return this.owners;
    }
}
测试类
package com.pc.factory.example.test;

import com.pc.factory.example.framework.Factory;
import com.pc.factory.example.framework.Product;
import com.pc.factory.example.idcard.IDCardFactory;
import org.junit.Test;

import java.util.Map;

/**
 * ID卡工厂测试类
 * Created by Switch on 2017-02-09.
 */
public class IDCardFactoryTest {
    @Test
    public void testIDCard() {
        Factory factory = new IDCardFactory();
        Product product1 = factory.create("Switch");
        Product product2 = factory.create("Kity");
        Product product3 = factory.create("Tom");
        product1.use();
        product2.use();
        product3.use();

        // 扩展使用
        IDCardFactory idCardFactory = (IDCardFactory) factory;
        Map<String, Product> owners = idCardFactory.getOwners();
        for (Map.Entry<String, Product> entryOwners : owners.entrySet()) {
            System.out.println(entryOwners.getKey() + ":" + entryOwners.getValue());
        }
    }
}
运行结果
制作Switch的ID卡。
制作Kity的ID卡。
制作Tom的ID卡。
使用Switch的ID卡。
使用Kity的ID卡。
使用Tom的ID卡。
Kity:com.pc.factory.example.idcard.IDCard@e03bb5
Tom:com.pc.factory.example.idcard.IDCard@8c92f4
Switch:com.pc.factory.example.idcard.IDCard@1e4705b

工厂模式中的角色

Product(产品)

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

Creator(创建者)

Creator角色属于框架这一方,它是负责生成Product角色的抽象类,但具体的处理则由子类ConcreteCreator角色决定。在案例中,由Factory类扮演此角色。

Creator角色对于实际负责生成实例的ConcreteCreator角色一无所知,它唯一知道的就是,只要调用Product角色和生成实例的方法(类图中的factoryMethod方法),就可以生成Product的实例。在案例中,createProduct方法是用于生成实例的方法。

不用new关键字来生成实例,而是调用生成实例的专用方法来生成实例,这样就可以防止父类与其他具体类藕合。

ConcreteProduct(具体的产品)

ConcreteProduct角色属于具体加工这一方,它决定了具体的产品。在案例中,由IDCard类扮演此角色。

ConcreteCreator(具体的创建者)

ConcreteCreator角色属于具体加工这一方,它负责生成具体的产品。在案例中,由IDCardFactory类扮演此角色。

类图

工厂模式类图

GitHub:DesignPatternStudy

——————参考《图解设计模式》

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值