1.工厂方法模式简介
工厂方法模式(FACTORY METHOD)是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品
2.工厂方法模式UML类图
3.工厂方法模式简单实现
工厂方法模式可以用我们现实中的例子来阐述:比如张三想成立一个鞋厂(抽象工厂)生产鞋(抽象产品),但由于刚刚开始并没有好的想法,所以这个厂是一个空壳。后续有新的业务市场人员加入。某个市场调查人员经过调查给张三说皮鞋在该地有比较大的利润空间比较大,可以成立一个皮鞋生产部(具体工厂)来生产皮鞋(具体产品),然后张三听从了该调查人员的建议成立皮鞋生产部。过了一段时间张三觉得可以再生产其他的鞋,又叫其他的市场调查人员去做市场调查,这回决定生产流行的帆布鞋。
从上述的现实示例中,我们可以用工厂方法模式去抽象:
抽象工厂的实现:
抽象工厂相当于一个总工厂(鞋厂),并不负责生产具体的产品(鞋)。他相当于决策层,要想生产具体的产品要实现它。
//抽象工厂 鞋厂
public interface ShoeFactory{
Shoe createShoe();
}
具体工厂的实现:
具体工厂相当于一个皮鞋或者其他鞋的生产部门。
//具体工厂 皮鞋生产部
public class LeatherShoeFactory implements ShoeFactory{
private Shoe shoe;
public Shoe createShoe(){
shoe = new LeatherShoe();
return shoe;
}
}
// 具体工厂 帆布鞋生产部
public class FanbuShoeFactory implements ShoeFactory{
private Shoe shoe;
public Shoe createShoe(){
shoe = new FanbuShoe();
return shoe;
}
}
抽象角色的实现:
鞋在房示例中可以抽象为 抽象产品角色。
//抽象产品角色 鞋
public abstract class Shoe{
private String name;
private Float price;
public void showType();
}
具体角色的实现:
皮鞋或者帆布鞋可以抽象为具体产品角色。
//具体产品角色 皮鞋
public class LeatherShoe extends Shoe{
private String name;
private Float price;
@override
public void showType(){
System.out.println("皮鞋");
}
}
public FanbuShoe extends Shoe{
private String name;
private Float price;
@override
public void showType(){
System.out.println("帆布鞋");
}
}
4.工厂方法模式在jdk中的使用
在java.sql中顶层接口连接数据库的驱动 Driver
package java.sql;
import java.util.logging.Logger;
//等价于抽象工厂角色
public interface Driver{
// 数据库连接 相当于 抽象产品角色
Connection connect(String url, java.util.Properties info)
throws SQLException;
}
而不同的数据库厂商(具体工厂角色)只要 implements 该Driver后,就可以提供自己的具体实现如:mysql数据库厂商提供一个驱动包
package com.mysql.jdbc;
import java.sql.SQLException;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
}
java.sql包里提供的Connection 属性是要取得数据库连接就相当于 抽象产品角色。
package java.sql;
import java.util.Properties;
import java.util.concurrent.Executor;
public interface Connection extends Wrapper, AutoCloseable {
Statement createStatement() throws SQLException;
PreparedStatement prepareStatement(String sql)throws SQLException;
CallableStatement prepareCall(String sql) throws SQLException;
........
}
而具体取得什么连接 就看你是哪个数据库 如MySQL数据库的就实现 Connection接口(具体产品角色)。
public interface Connection extends java.sql.Connection, ConnectionProperties {
public abstract java.sql.PreparedStatement clientPrepareStatement(String sql) throws SQLException;
public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, int autoGenKeyIndex) throws SQLException;
public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException;
public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, int[] autoGenKeyIndexes) throws SQLException;
public abstract java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException;
}