工厂方法模式:
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
本文复盘《设计模式之禅》中的案例,共享(侵权必删)。
案例的类图如下:
代码如下:
package test5;
public interface Human {
// 每个人种的皮肤都有相应的颜色
public void getColor();
// 人类会说话
public void talk();
}
package test5;
public class BlackHuman implements Human {
@Override
public void getColor() {
System.out.println("黑色人种的皮肤颜色是黑色的!");
}
@Override
public void talk() {
System.out.println("黑人会说话,一般人听不懂。");
}
}
package test5;
public class YellowHuman implements Human {
public void getColor(){
System.out.println("黄色人种的皮肤颜色是黄色的!");
}
public void talk() {
System.out.println("黄色人种会说话,一般说的都是双字节。");
}
}
package test5;
public class WhiteHuman implements Human {
public void getColor(){
System.out.println("白色人种的皮肤颜色是白色的!");
}
public void talk() {
System.out.println("白色人种会说话,一般都是但是单字节。");
}
}
package test5;
public abstract class AbstractHumanFactory {
public abstract <T extends Human> T createHuman(Class<T> c);
}
package test5;
public class HumanFactory extends AbstractHumanFactory {
@Override
public <T extends Human> T createHuman(Class<T> c) {
// 定义一个生产的人种
Human human = null;
try {
// 产生一个人种
human = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("人种生成错误!");
}
return (T) human;
}
}
package test5;
public class NvWa {
public static void main(String[] args) {
// 声明阴阳八卦炉
AbstractHumanFactory YinYangLu = new HumanFactory();
// 女娲第一次造人,火候不足,于是白人产生了
System.out.println("--造出的第一批人是白色人种--");
Human whiteHuman = YinYangLu.createHuman(WhiteHuman.class);
whiteHuman.getColor();
whiteHuman.talk();
// 女娲第二次造人,火候过足,于是黑人产生了
System.out.println("\n--造出的第二批人是黑色人种--");
Human blackHuman = YinYangLu.createHuman(BlackHuman.class);
blackHuman.getColor();
blackHuman.talk();
// 第三次造人,火候刚刚好,于是黄色人种产生了
System.out.println("\n--造出的第三批人是黄色人种--");
Human yellowHuman = YinYangLu.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.talk();
}
}
结果如下:
--造出的第一批人是白色人种--
白色人种的皮肤颜色是白色的!
白色人种会说话,一般都是但是单字节。
--造出的第二批人是黑色人种--
黑色人种的皮肤颜色是黑色的!
黑人会说话,一般人听不懂。
--造出的第三批人是黄色人种--
黄色人种的皮肤颜色是黄色的!
黄色人种会说话,一般说的都是双字节。
解释:
AbstractHumanFactory 我们在这里采用了泛型(Generic),通过定义泛型对createHuman的输入参数产
生两层限制:
● 必须是Class类型;
● 必须是Human的实现类。
工厂模式扩展:
1. 缩小为简单工厂模式:
在类图中去掉了AbstractHumanFactory抽象类,同时把createHuman方法设置为静态类型。
2. 升级为多个工厂类
每个人种(具体的产品类)都对应了一个创建者,每个创建者都独立负责创建对应的产品对象。
3. 替代单例模式(通过反射)
代码如下:
package test5;
public class Singleton {
// 不允许通过new产生一个对象
private Singleton() {
}
public void doSomething() {
// 业务处理
}
}
package test5;
import java.lang.reflect.Constructor;
public class SingletonFactory {
private static Singleton singleton;
static {
try {
Class cl = Class.forName(Singleton.class.getName());
// 获得无参构造
Constructor constructor = cl.getDeclaredConstructor();
// 设置无参构造是可访问的
constructor.setAccessible(true);
// 产生一个实例对象
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
// 异常处理
}
}
public static Singleton getSingleton() {
return singleton;
}
}
通过获得类构造器,然后设置访问权限,生成一个对象,然后提供外部访问,保证内存中的对象唯一。
参考文献:《设计模式之禅》 侵权必删!