工厂方法模式
工厂方法模式
什么是工厂方法模式
工厂方法模式使用的频率非常高, 在我们日常的开发中总能见到它的身影。 其定义为:
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
用人话来说就是:定义一个用于创建对象的接口,让子类决定实例化哪一个类。 工厂方法使一个类的实例化延迟到其子类。
也就是说,你要什么产品直接跟工厂接口说,工厂接口它自己不去实例化对象,但是它去找对应的子类(具体的实现工厂)去实例化对象再返回来.
工厂方法的类图结构
在工厂方法模式中, 抽象产品类Product负责定义产品的共性, 实现对事物最抽象的定义; Creator为抽象创建类, 也就是抽象工厂, 具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。
有了类图就可以去做代码实现了
抽象鼠标工厂类
/*
*@DESCRIPTION 抽象是鼠标制造工厂, 功能是造鼠标
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:25
*@PACKAGE_NAME test.factory.general
*/
public abstract class AbstractMouseFactory
{
public abstract MouseProduct createMouser();
}
抽象鼠标产品类
/**
*@DESCRIPTION 抽象的鼠标类也可以是一个接口
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:27
*@PACKAGE_NAME test.factory.general
**/
public abstract class MouseProduct
{
/**
*@DESCRIPTION 打印鼠标的名称
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:28
*@CLASS_NAME MouseProduct
**/
public abstract void getMouserName();
}
Lenovo鼠标
/**
*@DESCRIPTION 联想鼠标
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:28
*@PACKAGE_NAME test.factory.general
**/
public class LenovoMouse extends MouseProduct
{
@Override
public void getMouserName()
{
System.out.println("I'm come from Lenovo...");
}
}
Dell鼠标
/**
*@DESCRIPTION 戴尔鼠标
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:28
*@PACKAGE_NAME test.factory.general
**/
public class DellMouse extends MouseProduct
{
@Override
public void getMouserName()
{
System.out.println("I'm come from Dell...");
}
}
Lenovo鼠标工厂类
/**
*@DESCRIPTION 联想鼠标工厂, 负责生产联想鼠标
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:30
*@PACKAGE_NAME test.factory.general
**/
public class LenovoMouseFactory extends AbstractMouseFactory
{
/*
* 生产一个联想鼠标
*/
@Override
public MouseProduct createMouser()
{
return new LenovoMouse();
}
}
Dell鼠标工厂类
/**
*@DESCRIPTION 戴尔鼠标工厂, 负责生产戴尔鼠标
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:30
*@PACKAGE_NAME test.factory.general
**/
public class DellMouseFactory extends AbstractMouseFactory
{
/*
* 生产一个戴尔鼠标
*/
@Override
public MouseProduct createMouser()
{
return new DellMouse();
}
}
客户端调用类
/**
*@DESCRIPTION 模拟客户端调用
*@AUTHOR SongHongWei
*@TIME 2018/8/12-15:33
*@PACKAGE_NAME test.factory.general
**/
public class Client
{
public static void main(String[] args)
{
//客户现在提需求,说想要一个联想的鼠标
AbstractMouseFactory abstractMouseFactory = new LenovoMouseFactory();
//让联想工厂去生产一个联想鼠标
MouseProduct mouser = abstractMouseFactory.createMouser();
//打印出鼠标的名称
mouser.getMouserName();
//现在客户觉得联想鼠标用腻了,想换个产品,所以想要个Dell的鼠标
abstractMouseFactory = new DellMouseFactory();
//好的,Dell鼠标生产出来了
mouser = abstractMouseFactory.createMouser();
//打印出鼠标的名称
mouser.getMouserName();
}
}
输出结果
I'm come from Lenovo...
I'm come from Dell...
Process finished with exit code 0
总结
工厂方法模式个简单工厂方法模式的区别在于:工厂方法模式自己不去实例化类,它交由对应的子类去实例化,
而简单工厂方法模式,需要通过传参来告诉工厂类我要什么产品了,万一参数写错一个字母呢?是吧。
另外如果我新增加一个产品,在工厂方法模式里我只需要新增对应的产品类和产品的工厂实现就可以了,而在简单工厂模式里,就需要对整个工厂进行修改,万一修改错了影响的可能是所有使用该工厂创建对象的用户。
因此,工厂方法模式做到了“开闭原则“也就是说对扩展开放,对修改关闭;另外工厂方法也做到了“单一职责”简单点说各个工厂只负责生成自己的产品。
简单工厂所有的产品都交给一个工厂去生产,严重违背了”单一职责”原理。
但是工厂方法模式也有相应的缺点,如果我新增100个产品,那么我就要新建100个产品类个100个产品工厂,这无疑是巨大的开发量,对系统的开销也将变大
实际使用
JDBC连接数据库的时候需要配置数据库驱动,如果我们从MySQL数据库换成Oracle数据,那么我们只需要更改数据库驱动就行了,而不用重新写一个数据库连接,执行,提交等一系列方法实现,大大降低了开发难度
上一篇: Java和Scala学习日记3
下一篇: 工厂方法模式