设计模式:Factory Method模式

工厂方法,通过Template Method模式来生成实例的工厂,就是Factory Method模式,和Template Method一样,Factory Method模式超类决定实例的生成方式,但是不决定所要生成的具体的类,具体的处理都还是由子类来负责,这样生成实例的framework框架和实际负责生成实例的类解耦

以制作身份证为例,创建的类如下:

Product:定义一个抽象产品类,类里定义一个抽象方法使用身份证use

Factory:定义制作和注册两个抽象方法,create调用这两个抽象方法生成Product实例

IDCard:重写产品Product类的重写方法use

IDCardFactory:重写工厂类Factory里制作和注册两个抽象方法

Main:测试类main

可以创建两个不同的包完成解耦:

factory.framework:包括了Product类和Factory类,组成了生成实例的框架

factory.idcard:包括了IDCard类和IDCardFactory类,负责身份证的加工处理

首先是Product抽象类,表示任意产品,定义一个use抽象方法,可以给任意产品调用use,但是具体实现在Product类的子类完成

package factory.framework;

/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Product
* Author: lihui
* Date: 2018/4/30 23:38
*/

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

然后工厂类Factory,里面调用create方法生成Product实例,具体实现调用另两个抽象方法,首先createProduct生成产品,然后调用registerProduct注册产品;而他们的具体处理交给了Factory的子类重写

package factory.framework;

/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Factory
* Author: lihui
* Date: 2018/4/30 23:38
*/

public abstract class Factory {
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);

public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
}

接着就是身份证IDCard类,继承超类Product,为了与框架分离,放到idcard包里,重写Product的use方法

package factory.idcard;

import factory.framework.Product;

/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: IDCard
* Author: lihui
* Date: 2018/4/30 23:42
*/

public class IDCard extends Product {
private String owner;
IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
}

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

public String getOwner() {
return owner;
}
}

最后就是IDCardFactory了,继承超类Factory,重写createProduct和registerProduct方法,createProduct方法实例化生产身份证卡,registerProduct方法通过将身份证IDCard的owner保存到owners来注册该身份证

package factory.idcard;

import factory.framework.Factory;
import factory.framework.Product;

import java.util.ArrayList;
import java.util.List;

/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: IDCardFactory
* Author: lihui
* Date: 2018/4/30 23:44
*/

public class IDCardFactory extends Factory {
private List owners = new ArrayList();

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

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

public List getOwners() {
return owners;
}
}

测试类main

package factory;


import factory.framework.Factory;
import factory.framework.Product;
import factory.idcard.IDCardFactory;

/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Main
* Author: lihui
* Date: 2018/4/30 23:48
*/

public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("LiLei");
Product card2 = factory.create("LiMing");
Product card3 = factory.create("LiHui");
card1.use();
card2.use();
card3.use();
}
}

 

工厂方法模式的角色:

Product:例子中的Product类;产品,属于框架的一方,是一个抽象类;定义了工厂方法模式中生成的实例锁持有的接口,而具体的处理实现都是由其子类ConcreteProduct角色来处理

Creator:例子中的Factory类;创建者,属于框架的一方,负责生成Product角色的抽象类,而具体的处理实现都是由其子类ConcreteCreator角色处理

ConcreteProduct:例子中的IDCard类;具体的产品,属于具体加工实现的一方,它决定了具体的产品

ConcreteCreator:例子中的IDCardFactory类;具体的创建者,属于具体加工实现的一方,负责生成具体的产品

Creator角色对于实际负责生成实例的ConcreteCreator角色一无所知,它只要调用Product角色和 生成实例的方法,就可以生成Product的实例;这里不需要用new来生成实例,而是调用生成实例的工厂方法来实现,这样可以防止超类和其它具体类耦合

 

因为产品Product和工厂Factory封装到同一个包里了,这样如果想要创建任何其它产品实例的产品和工厂,都通过这同一个框架来完成,不需要做任何修改就搞定了产品和工厂

发表回复