工厂模式
- 工厂模式定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 工厂模式优点:良好封装性(通过类名创建对象)、易于扩展性(增加具体产品方便)、屏蔽产品类(产品类的实现如何变化,调用者都不需要关
心)、典型解耦框架(高层模块值需要知道产品的抽象类,其他的实
现类都不用关心)。
1.普通工厂模式
1.抽象产品类
public abstract class Product {
// 产品类公有方法
public void method1() {
// 业务逻辑处理
}
// 抽象方法
public abstract void method2();
}
2.具体产品类
public class ConcreteProduct1 extends Product{
@Override
public void method2() {
// 业务逻辑处理
}
}
public class ConcreteProduct2 extends Product{
@Override
public void method2() {
// 业务逻辑处理
}
}
3.抽象工厂类
public abstract class Creator {
/*
* 创建一个产品对象,其输入参数类型可以自行设置 通常为String、Enum、Class等,当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
4.具体工厂类
public class ConcreteCreator extends Creator {
@Override
public <T extends Product> T createProduct(Class<T> c) {
Product product=null;
try {
product=(Product) Class.forName(c.getName()).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
//异常处理
e.printStackTrace();
}
return (T) product;
}
}
5.场景类
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
* 继续业务处理
*/
}
}
2.简单工厂模式
1.人类
public interface Human {
// 每个人种的皮肤都有相应的颜色
public void getColor();
// 人类会说话
public void talk();
}
2.黑人、白人、黄人
public class BlackHuman implements Human {
@Override
public void getColor() {
System.out.println("黑色人种的皮肤颜色是黑色的!");
}
@Override
public void talk() {
System.out.println("黑人会说话,一般人听不懂。");
}
}
public class WhiteHuman implements Human {
public void getColor() {
System.out.println("白色人种的皮肤颜色是白色的!");
}
public void talk() {
System.out.println("白色人种会说话,一般都是但是单字节。");
}
}
public class YellowHuman implements Human {
public void getColor() {
System.out.println("黄色人种的皮肤颜色是黄色的!");
}
public void talk() {
System.out.println("黄色人种会说话,一般说的都是双字节。");
}
}
3.人类工厂
public class HumanFactory {
public static <T extends Human> T createHuman(Class<T> c) {
//定义一个生产的人种
Human human = null;
try {
//产生一个人种
human = (Human) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("人种生成错误!");
}
return (T) human;
}
}
4.测试类
public class NvWa {
public static void main(String[] args) {
//声明阴阳八卦炉
HumanFactory 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();
}
}
3.多个工厂类
1.人类
2.黑人、白人、黄人
3.抽象人类工厂
public abstract class AbstractHumanFactory {
public abstract Human createHuman();
}
4.具体人类工厂(黑、白、黄)
public class BlackHumanFactory extends AbstractHumanFactory {
@Override
public Human createHuman() {
return new BlackHuman();
}
}
5.测试类
public class NvWa {
public static void main(String[] args) {
// 女娲第一次造人,火候不足,于是白色人种产生了
System.out.println("--造出的第一批人是白色人种--");
Human whiteHuman = (new WhiteHumanFactory()).createHuman();
whiteHuman.getColor();
whiteHuman.talk();
// 女娲第二次造人,火候过足,于是黑色人种产生了
System.out.println("\n--造出的第二批人是黑色人种--");
Human blackHuman = (new BlackHumanFactory()).createHuman();
blackHuman.getColor();
blackHuman.talk();
// 第三次造人,火候刚刚好,于是黄色人种产生了
System.out.println("\n--造出的第三批人是黄色人种--");
Human yellowHuman = (new YellowHumanFactory()).createHuman();
yellowHuman.getColor();
yellowHuman.talk();
}
}
4.延迟加载
迟初始化(Lazy initialization):一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待再次被使用。
public class ProductFactory {
private static final Map<String, Product> prMap = new HashMap();
public static synchronized Product createProduct(String type) throws Exception {
Product product = null;
// 如果Map中已经有这个对象
if (prMap.containsKey(type)) {
product = prMap.get(type);
} else {
if (type.equals("Product1")) {
product = new ConcreteProduct1();
} else {
product = new ConcreteProduct2();
}
// 同时把对象放到缓存容器中
prMap.put(type, product);
}
return product;
}
}
注:《设计模式之禅》笔记