创建类模式之工厂模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
我的理解:
工厂模式的精髓就是对象的创建是由工厂代理的,工厂会给你一个对象,你只用提供类的个人信息就行。
那么在Java中如何具体的实现呢:

请添加图片描述

我们先来定义一个具体的对象:
1,抽象的产品类

public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
//抽象方法
public abstract void method2();
}
具体的产品类可以有多个,都继承于抽象产品类,其源代码如代码清单8-9所示。
代码清单8-9 具体产品类
public class ConcreteProduct1 extends Product {
public void method2() {
//业务逻辑处理
}
}
//具体的子类实现类产品
public class ConcreteProduct2 extends Product {
public void method2() {
//业务逻辑处理
}
}

我们为啥用的是抽象的类来定义一个类,因为子类是不确定的,我们是通过子类的具体实现确定实例化的对象到底是那样一个。
2.抽象工厂来确定产品的生产

代码清单8-10 抽象工厂类
public abstract class Creator {
/*
* 创建一个产品对象,其输入参数类型可以自行设置
* 通常为String、Enum、Class等,当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体如何产生一个产品的对象,是由具体的工厂类实现的,如代码清单8-11所示。
代码清单8-11 具体工厂类
public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
Product product=null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}

我们们为啥使用的抽象的工厂类应为还是产品未定所以我们使用的还是抽象的,注意具体的实现,我们是通过反射机制来创建的对象的,得到类的个人信息就可以创建对应的实例化对象了

public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
* 继续业务处理
*/
}
}

场景类具体的运行情况
工厂方法模式的使用场景

  1. 首先,工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以
    使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度。
    2.一个产品对象具体由哪一个产品生成是由工厂类
    决定的。在数据库开发中,大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC
    连接数据库,数据库从MySQL切换到Oracle,需要改动的地方就是切换一下驱动名称(前提
    条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接
    案例。

工厂方法模式的扩展

  1. 缩小为简单工厂模式
    当我们使用工厂类,没必要把工厂类new 来的时候,我们就是用静态方法就可以的
    请添加图片描述
    中去掉了AbstractHumanFactory抽象类,同时把createHuman方法设置为静态
    类型
代码清单8-13 简单工厂模式中的工厂类
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;
}
}

测试:

代码清单8-14 简单工厂模式中的场景类
public class NvWa {
public static void main(String[] args) {
//女娲第一次造人,火候不足,于是白色人种产生了
System.out.println("--造出的第一批人是白色人种--");
Human whiteHuman = HumanFactory.createHuman(WhiteHuman.class);
whiteHuman.getColor();
whiteHuman.talk();
//女娲第二次造人,火候过足,于是黑色人种产生了
System.out.println("\n--造出的第二批人是黑色人种--");
Human blackHuman = HumanFactory.createHuman(BlackHuman.class);
blackHuman.getColor();
blackHuman.talk();
//第三次造人,火候刚刚好,于是黄色人种产生了
System.out.println("\n--造出的第三批人是黄色人种--");
Human yellowHuman = HumanFactory.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.talk();
}
}

升级为多个工厂类
我们的工厂可以是多个具体的,特定生产出特定的产品出来的
每一个工厂可以生产出一种产品
请添加图片描述

代码清单8-15 多工厂模式的抽象工厂类
public abstract class AbstractHumanFactory {
public abstract Human createHuman();
}

抽象方法中已经不再需要传递相关参数了,因为每一个具体的工厂都已经非常明
确自己的职责:创建自己负责的产品类对象。

不同的工厂

黑色人种的创建工厂如代码清单8-16所示。
代码清单8-16 黑色人种的创建工厂实现
public class BlackHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new BlackHuman();
}
}
黄色人种的创建工厂如代码清单8-17所示。
代码清单8-17 黄色人种的创建类
public class YellowHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new YellowHuman();
}
}
白色人种的创建工厂如代码清单8-18所示。
代码清单8-18 白色人种的创建类
public class whiteHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new WhiteHuman();
}
}

三个具体的创建工厂都非常简单,但是,如果一个系统比较复杂时工厂类也会相应地变
复杂。

测试类

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();
}
}

替代单例模式
请添加图片描述
定义一个private的构造函数的额类目的是不允许通过new的
方式创建一个对象,如代码清单8-20所示。

代码清单8-20 单例类
public class Singleton {
//不允许通过new产生一个对象
private Singleton(){
}
public void doSomething(){
//业务处理
}
}

Singleton保证不能通过正常的渠道建立一个对象,那SingletonFactory如何建立一个单例
对象呢?答案是通过反射方式创建,

代码清单8-21 负责生成单例的工厂类
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;
}
}

抽象工厂模式
定义:(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们
的具体类。)
说人话就是,当我们要创建一组对象,是同一个父类的时候,就使用抽象接口创造它

请添加图片描述
代码清单9-11 抽象产品类

public abstract class AbstractProductA {
//每个产品共有的方法
public void shareMethod(){
}
//每个产品相同方法,不同实现
public abstract void doSomething();
}
两个具体的产品实现类如代码清单9-12、代码清单9-13所示。
代码清单9-12 产品A1的实现类
public class ProductA1 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A1的实现方法");
}
}
代码清单9-13 产品A2的实现类
public class ProductA2 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A2的实现方法");
}
}

产品B与此类似,不再赘述
抽象工厂类AbstractCreator的职责是定义每个工厂要实现的
功能,定义着不同的生产不同的产品

public abstract class AbstractCreator {
//创建A产品家族
public abstract AbstractProductA createProductA();
//创建B产品家族
public abstract AbstractProductB createProductB();
}

注意 有N个产品族,在抽象工厂类中就应该有N个创建方法。
创建一个产品

代码清单9-15 产品等级1的实现类
public class Creator1 extends AbstractCreator {
//只生产产品等级为1的A产品
public AbstractProductA createProductA() {
return new ProductA1();
}
//只生产产品等级为1的B产品
public AbstractProductB createProductB() {
return new ProductB1();
}
}
代码清单9-16 产品等级2的实现类
public class Creator2 extends AbstractCreator {
//只生产产品等级为2的A产品
public AbstractProductA createProductA() {
return new ProductA2();
}
//只生产产品等级为2的B产品
public AbstractProductB createProductB() {
return new ProductB2();
}
}

有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族
的生产任务。
在具体的业务中如何产生一个与实现无关的对象呢

代码清单9-17 场景类
public class Client {
public static void main(String[] args) {
//定义出两个工厂
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
//产生A1对象
AbstractProductA a1 = creator1.createProductA();
//产生A2对象
AbstractProductA a2 = creator2.createProductA();
//产生B1对象
AbstractProductB b1 = creator1.createProductB();
//产生B2对象
AbstractProductB b2 = creator2.createProductB();
/*
* 然后在这里就可以为所欲为了...
*/
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗中的代码猿--刘同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值