Java设计模式 - 工厂模式

工厂模式(factory pattern)

定义

该模式有如下三类模式。
1.简单工厂(simple factory)模式:这是程序员的一种简单编程习惯,封装创建同一类不同对象的代码。
2.工厂方法(factory method)模式:定义了一个创建对象的接口,由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
3.抽象工厂(abstract factory)模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

特点

1.工厂提供创建对象接口;
2.创建对象时,只需new对应类的工厂,并调用其创建对象的接口函数即可。

适用范围

创建对象比较繁琐或者不愿暴露创建方法的时候。

一般写法

一般有三种写法,分别为简单工厂、工厂方法、抽象工厂。我们先从简单工厂和工厂方法讲起。为了方便比较,我们先定义两个待会要被工厂创建的对象类,这两个对象类都具有同一个超类Object,如下:

/**
 * 类一,继承父类Object
 */
public class ObjectOne extends Object {
    // 在构造函数中,打印一下实例化对象时的信息
    public ObjectOne() {
        System.out.println("I am objectOne!");
    }
}
/**
 * 类二,继承同个Object父类
 */
public class ObjectTwo extends Object {
    // 在构造函数中,打印一下实例化对象时的信息
    public ObjectTwo() {
        System.out.println("I am objectTwo!");
    }
}
  • 简单工厂:
/**
 * 简单工厂模式,把具有同一超类的类对象
 * 创建方法封装到函数createObject中
 */
public class SimpleFactory {
    // 简单工厂的创建对象函数,用于创建不同对象
    public Object createObject(String type) {
        Object object;
        if (type.equals("one")) {
            // 创建对象一
            object = new ObjectOne();
        } else if (type.equals("two")) {
            // 创建对象二
            object = new ObjectTwo();
        } else {
            // 兜底,假如传错参数返回空
            return null;
        }
        return object;
    }
}
  • 工厂方法:
    在设计模式中,实现一个接口泛指实现某个超类型(可以是类或接口)的某个方法,在如下的方法中就有体现。一个具体的工厂方法只负责一个物品的创建,这里有两个具体工厂负责两个物品的创建。
/**
 * 工厂方法定义了一个创建对象的接口
 */
public abstract class FactoryMethod {
    // 定义一个实例化函数,实现此接口
    // 的子类在此函数实现实例化对象。
    // abstract修饰的函数,子类继承必须实现其方法体。
    abstract Object createObject();
}
/**
 * 工厂方法一只负责对象一的创建
 */
public class FactoryMethodOne extends FactoryMethod{
    @Override
    public Object createObject() {
        return new ObjectOne();
    }
}
/**
 * 工厂方法二只负责对象二的创建
 */
public class FactoryMethodTwo extends FactoryMethod{
    @Override
    public Object createObject() {
        return new ObjectTwo();
    }
}
  • 抽象工厂
    抽象工厂里面的家族成员具有一定的性质,比如造车,那么家族成员可以是轮子、车窗、方向盘等。
/**
 * 抽象工厂,提供一个接口,其中,ObjectOne
 * 和ObjectTwo为相关的家族成员
 */
public interface AbstractFactory {
    ObjectOne createObjectOne();
    ObjectTwo createObjectTwo();
}
/**
 * 具体工厂类,实现了抽象工厂的接口,
 * 该类必须实现抽象工厂的家族成员创建,
 * 家族成员属于不同的类。
 */
public class ConcreteFactory implements AbstractFactory {
    @Override
    public ObjectOne createObjectOne() {
        return new ObjectOne();
    }

    @Override
    public ObjectTwo createObjectTwo() {
        return new ObjectTwo();
    }
}

工厂模式测试

public class Main {
    public static void main(String[] args) {
        // 简单工厂创建物品
        SimpleFactory simpleFactory = new SimpleFactory();
        Object SimpleFactoryObject1 = simpleFactory.createObject("one");
        Object SimpleFactoryObject2 = simpleFactory.createObject("two");

        // 工厂方法创建物品
        FactoryMethod factoryMethodOne = new FactoryMethodOne();
        Object factoryMethodOneObject1 = factoryMethodOne.createObject();
        FactoryMethod factoryMethodTwo = new FactoryMethodTwo();
        Object factoryMethodOneObject2 = factoryMethodTwo.createObject();

        // 抽象工厂创建物品
        AbstractFactory concreteFactory = new ConcreteFactory();
        ObjectOne concreteFactoryObject1 = concreteFactory.createObjectOne();
        ObjectTwo concreteFactoryObject2 = concreteFactory.createObjectTwo();
    }
}
I am objectOne!
I am objectTwo!
I am objectOne!
I am objectTwo!
I am objectOne!
I am objectTwo!

为什么需要工厂模式

1.创建对象时,我们只需关心工厂对外暴露的接口createObject即可,至于该函数怎么创建对象我们不需要知道,这就是做到了创建对象与实现对象类的解耦。
2.工厂方法中,new一个工厂,调用一次createObject,不是很繁琐吗?以ObjectOne为例,直接new ObjectOne()不行吗?如下所示:

FactoryMethod factoryMethodOne = new FactoryMethodOne();
Object factoryMethodOneObject1 = factoryMethodOne.createObject();
Object factoryMethodOneObject1 = new ObjectOne();

当你ObjectOne需要很复杂地被创建时就不行了,比如ObjectOne类对象的创建要依赖很多其他对象的时候,全部写在当前显然不好看,且创建与实现的耦合度高,而最终我们也只关心ObjectOne,假设我们有PartOne和PartTwo两类,ObjectOne依赖于这两类的对象,全部写在当前如下所示:

PartOne part1 = new PartOne();
PartTwo part2 = new PartTwo();
Object factoryMethodOneObject1 = new ObjectOne(part1, part2);

而写成工厂方法的时候,只需要改造工厂即可,形式如下:

public class FactoryMethodOne extends FactoryMethod{
    @Override
    public Object createObject() {
        PartOne part1 = new PartOne();
		PartTwo part2 = new PartTwo();
        new ObjectOne(part1, part2);
    }
}

这样依旧只new一个工厂,调用createObjectOne()即可。

FactoryMethod factoryMethodOne = new FactoryMethodOne();
Object factoryMethodOneObject1 = factoryMethodOne.createObject();

3.再利用抽象工厂把PartOne和PartTwo封装,如下:

public interface PartsAbstractFactory {
    PartOne createPartOne();
    partTwo createPartTwo();
}
public class Parts implements PartsAbstractFactory {
    @Override
    public PartOne createPartOne() {
        return new PartOne();
    }

    @Override
    public PartTwo createPartTwo() {
        return new PartTwo();
    }
}

那么第2点的FactoryMethodOne可以改造如下:

public class FactoryMethodOne extends FactoryMethod{
    @Override
    public Object createObject() {
        PartsAbstractFactory parts = new Parts();
        new ObjectOne(parts);
    }
}
/**
 * 相应地,ObjectOne要做如下改造
 * 即可获得PartOne和PartTwo的对象
 */
public class ObjectOne extends Object {
    privarte PartOne part1;
    privarte PartTwo part2;
    public ObjectOne(PartsAbstractFactory parts) {
        System.out.println("I am objectOne!");
        this.part1 = parts.createPartOne();
        this.part = parts.createPartTwo();
    }
}

看到这里是不是觉得似乎明白了抽象工厂的作用,它就是把ObjectOne所依赖的对象整到一起,然后只需要new一个工厂,调用相应的创建对象函数即可。当产品的依赖家族稳定很少变化的时候可以试试抽象工厂,如果产品的依赖家族种类频繁变化,抽象工厂提供的方法也频繁变化,那实现其接口的子类将会很繁琐,这样就不建议了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值