设计模式之简单工厂模式
一、简单工厂模式简介
在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 这个时候使用简单工厂方法模式就可以隐藏这些对象new的过程。
比如你现在要买一辆宝马,这个时候你只需要将你的购车信息提供给宝马工厂,宝马工厂就会为你创建一辆你需要的宝马,如果你不通过工厂去创建除非你能够自己制造一辆。下面就通过这个例子给大家讲讲简单工厂模式。
二、简单工厂模式
1、宝马工厂模式
首先你需要提供一个抽象的宝马产品,可能有很多型号,比如宝马X3,宝马320i等等,只需要继承改抽象类即可
public abstract class Bmw { public Bmw(){} }
接下来具体的宝马车的型号,工厂就是专门生产这些产品的,下面是宝马320i,X5型号的宝马,当然还会有非常多的产品,直接继承宝马抽象类Bmw即可
public class Bmw320i extends Bmw{ public Bmw320i(){ System.out.println("生产了一辆BMW320i"); } } public class BmwX5 extends Bmw{ public BmwX5(){ System.out.println("生产了一辆BMWX5"); } }
接下来是生产宝马各类产品的工厂类
public class BmwFactory { public Bmw createBmw(String type){ switch (type) { case "320i": return new Bmw320i(); case "X5": return new BmwX5(); default: System.out.println("没有"); return null; } } }
客户端代码
public class Show { public static void main(String[] args) { BmwFactory bmwFactory = new BmwFactory(); Bmw bmwX5 = bmwFactory.createBmw("X5"); Bmw bmw320i = bmwFactory.createBmw("320i"); } }
测试结果
生产了一辆BMWX5
生产了一辆BMW320i
很明显客户端并没有new宝马产品对象的过程,这就是简单工厂模式的作用,它隐藏了对象的具体创建过程。但是这样的模式是有缺陷的,当我现在需要添加宝马X7,这个时候只能通过修改工厂类BmwFactory的源代码添加一条X5的判断,这严重违反了设计模式的开发-封闭原则,工厂类对于扩展是开放的,但是源码是不许修改的,关于设计模式的六大原则笔者会在后续博客中详述。既然违反了这个原则,肯定是有解决办法的,下面为大家带来工厂方法模式。
2、工厂方法模式
工厂方法模式就很好的解决了上面遇到的问题。简单工厂模式只有一个工厂类,所有的产品的创建都依赖这一个工厂类,需要添加新产品也是直接修改工厂类,这样既增加了工厂类的负担,也违反了开-闭原则。而工厂方法模式提供了一个抽象的工厂类,一个抽象的产品类,抽象工厂类有很多的具体的产品工厂创建类,每个抽象的产品类有很多子类产品。也就是说简单工厂模式就是所有的产品都在一个工厂类里面生产,而抽象方法模式是一个工厂生产一个产品,工厂类的负担不一样。
代码如下:
Bmw抽象类,产品的抽象类
public abstract class Bmw { public Bmw(){} }
Bmw320i类,BmwX5类,具体的宝马产品类,继承了抽象类Bmw
public class Bmw320i extends Bmw{ public Bmw320i(){ System.out.println("生产了一辆BMW320i"); } } public class BmwX5 extends Bmw{ public BmwX5(){ System.out.println("生产了一辆BMWX5"); } }
FactoryBMW类,抽象工厂类,各种产品的创建工厂都需要继承这个抽象类,返回不同的产品
public abstract class FactoryBMW { public abstract Bmw createBMW(); }
FactoryBMW320i类,FactoryBMWX5类,具体的工厂类,每一个工厂类生产这一种产品,这是与简单工厂模式的不同
public class FactoryBMW320i extends FactoryBMW { @Override public Bmw createBMW() { return new Bmw320i(); } } public class FactoryBMWX5 extends FactoryBMW { @Override public Bmw createBMW() { return new BmwX5(); } }
客户端代码
public class Show { public static void main(String[] args) { //这里需要那种产品就获取那种产品工厂 FactoryBMW320i factoryBMW320i = new FactoryBMW320i(); FactoryBMWX5 factoryBMWX5 = new FactoryBMWX5(); factoryBMW320i.createBMW(); factoryBMWX5.createBMW(); } }
测试结果
生产了一辆BMW320i
生产了一辆BMWX5
可以看到和简单工厂模式的结果是一致的。
3、UML图
首先看看简单工厂模式的UML图
接下来是工厂方法模式UML图
对比两种UML就很容易理解两种模式的区别了。
三、总结
简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。 他的结构如下
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。 他的结构如下
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。