java 工厂模式的写法_[java设计模式] 工厂模式解析

什么是工厂模式?

我的总结是: 遵守软件设计中的开闭原则和依赖反转原则, 并且客户端只需通过参数来创造多个对象, 并且在创建过程中,创建对象的过程对客户端是透明的. 这种开发模式叫做工厂模式.

出现原因.

我们在java中创建对象最入门的方法就是

ClassXXX xx = new ClassXXX();

xx.MM();

但当需要创建的同种类型的对象较多时, 重复的代码就会很多, 这样的写法就显得略过于臃肿, 并且混乱.

于是人们创造了“由一个第三方专门负责创建对象”的这么一种设计模式.

简单来说, 工厂模式分为三步:

总结出要创建的对象的特征, 将其抽象成接口

各类型的实现方法

创造工厂类, 输入接口,输出具体实现类.

废话不多说, 上demo

比如我们想要创建一个乐队, 这个乐队有吉他手,有钢琴手. 假设我们想要像流水线一样生产这群成员.

按工厂模式的步骤, 我们首先创建出乐器的规则(即接口) (假设我们不需要活人,有乐器就可以自动弹奏)

public interface Instrument {

public void play();

}

以及两个乐器的实现类, 钢琴和吉他.

public class Guitar implements Instrument{

@Override

public void play() {

System.out.println("playing guitar");

}

}

public class Piano implements Instrument {

@Override

public void play() {

System.out.println("playing Piano");

}

}

这样, 我们的第一步和第二步就完成了.

下面是第三步, 创建工厂方法

public class InstrumentFactory {

public Instrument export(String inst){

if (inst=="guitar"){

return new Guitar();

}

return new Piano();

}

}

这样, 一个最简单的工厂模式就出来了.

我们在main 方法中调用

public class Main {

public static void main(String[] args) {

InstrumentFactory factory = new InstrumentFactory();

factory.export("guitar").play();

factory.export("piano").play();

}

结果是:

playing guitar

playing Piano

当然, 程序如果这样写, 肯定是不行的. 关键点在于factory的输入太过于不专业.

所以, 下面我们对这个最简单的工厂模式做一下改良.

我们使用泛型改一下factory的输入.

public class InstrumentFactory {

public Instrument export(Class extends Instrument> instClass) throws IllegalAccessException, InstantiationException {

return instClass.newInstance();

}

}

而在main方法里, 只需要将输入由String改成class即可

InstrumentFactory factory = new InstrumentFactory();

factory.export(Guitar.class).play();

factory.export(Piano.class).play();

这样, 一个最简单的工厂模式就被写出来了. 很简单吧? 我们在研究JDK源码或Spring源码(尤其是Spring底层的Spring Data时), 他们使用的工厂模式和我们写的这个工厂模式也没有太大的区别. 很多时候研究源码觉得眼花缭乱,是因为很多的源码都是把多种设计模式混在一起. 如果我们把设计模式各个击破, 再去看源码,就会有“一览众山小”的感觉了.

你以为这样就结束了吗?

我们还差一步. 上面的部分仅仅是一个简单的工厂模式, 实际上它就叫做简单工厂模式(“Simple Factory Pattern”). 在GOF的23种设计模式里, 简单工厂模式是并不在其中的.

我们想要让你的代码登上大雅之堂, 还是需要做一番改良, 让他更符合标准.

这时我们就需要思考了, 我们的简单工厂模式哪里有问题呢? 或者说, 哪里不规范呢?

我们会发现, 我们创建的工厂是一个“万能工厂”,它既能造吉他, 也能造钢琴. 世界上有这样的工厂吗? 也许有, 但是在软件的世界里, 不要忘了还有一个原则叫“单一职责”的原则.

我在这篇文章的开头提到了开闭原则和依赖倒置原则. 这两个原则的意思是: 一个软件,或是一种功能,要对修改关闭, 对扩展开放, 简而言之就是易于扩展, 可多处复用. 以及, 要让底层依赖高层, 而不是高层依赖底层.

那么单一职责原则又是什么呢?

行话叫做: 不能存在多于一个导致类变更的原因.

在我们创建的factory中, guita的实现和piano的实现都会导致factory类被改变.

所以我们要修复一下这个问题.

我们可以把factory抽象出来, 并用多个工厂实现工厂的抽象类. 让一个工厂只负责一种对象.

public interface IFactory {

public void play();

}

public class GuitaFactory implements IFactory {

@Override

public Instrument generate() {

return new Guitar();

}

}

public class PianoFactory implements IFactory{

@Override

public Instrument generate() {

return new Piano();

}

}

在main 方法中, 我们使用以下方法使用出厂的乐器

IFactory guitarFactory = new GuitaFactory();

IFactory pianoFactory = new PianoFactory();

guitarFactory.generate().play();

pianoFactory.generate().play();

这就是一个标准的工厂模式.

你的代码终于可以带上规范化的标签, 登上GOF24的大雅之堂, 与各类高手坐在一起谈笑风生了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值