书接上回,本篇讲一下创建型模式-抽象工厂设计模式
定义:提供一个用于创建一系列相关或相互依赖对象的接口,而不需要明确指定具体类。
单从定义上看读起来有点拗口,细读后又有点犯迷糊。难办!这里先放将概念放一边,我们直接上代码,用代码说话
1>设计一个华为工厂类,能生成华为手机,华为电脑
2>设计一个小米工厂类,能生产小米手机,小米电脑
3>设计一个代工厂,能生产华为系列产品,也能生产小米系列产品。
产品-父类
//手机产品基类
public abstract class PhoneProduct {
public abstract void phoneInfo();
}
//电脑产品基类
public abstract class ComputerProduct {
public abstract void computerInfo();
}
产品-子类
华为系
//华为手机-子类
public class HWPhoneProduct extends PhoneProduct{
@Override
public void phoneInfo() {
System.out.println("华为手机信息....");
}
}
//华为电脑-子类
public class HWComputerProduct extends ComputerProduct{
@Override
public void computerInfo() {
System.out.println("华为电脑信息...");
}
}
小米系
//小米手机子类
public class XMPhoneProduct extends PhoneProduct{
@Override
public void phoneInfo() {
System.out.println("小米手机信息....");
}
}
//小米电脑-子类
public class XMComputerProduct extends ComputerProduct{
@Override
public void computerInfo() {
System.out.println("小米电脑信息...");
}
}
产品UML
工厂-父类
//工厂父类
public interface ProductFactory {
//生产手机
PhoneProduct createPhone();
//生产电脑
ComputerProduct createComputer();
}
工厂-子类
华为系
//华为工厂-子类
public class HWProductFactory implements ProductFactory{
@Override
public PhoneProduct createPhone() {
return new HWPhoneProduct();
}
@Override
public ComputerProduct createComputer() {
return new HWComputerProduct();
}
}
小米系
//小米工厂-子类
public class XMProductFactory implements ProductFactory{
@Override
public PhoneProduct createPhone() {
return new XMPhoneProduct();
}
@Override
public ComputerProduct createComputer() {
return new XMComputerProduct();
}
}
工厂UML图
//代工厂
public class FABFactory {
//华为工厂
public static HWProductFactory createHWFactory(){
return new HWProductFactory();
}
//小米工厂
public static XMProductFactory createXMFactory(){
return new XMProductFactory();
}
}
public class App {
public static void main(String[] args) {
//华为工厂
HWProductFactory hwFactory = FABFactory.createHWFactory();
//华为系产品
ComputerProduct hwc = hwFactory.createComputer(); //电脑
PhoneProduct hwp = hwFactory.createPhone(); //手机
hwc.computerInfo();
hwp.phoneInfo();
//小米工厂
XMProductFactory xmFactory = FABFactory.createXMFactory();
//小米系产品
ComputerProduct xmc = xmFactory.createComputer(); //电脑
PhoneProduct xmp = xmFactory.createPhone(); //手机
xmc.computerInfo();
xmp.phoneInfo();
}
}
结合代码跟UML图,可以梳理出产品与工厂体系,主要有2个:1个是华为系,1个是小米系
华为系:
产品:HWPhoneProduct HWComputerProduct
工厂:HWProductFactory
小米系:
产品:XMPhoneProduct XMComputerProduct
工厂:XMProductFactory
此时,回到最初模式定义:
定义:提供一个用于创建一系列相关或相互依赖对象的接口,而不需要明确指定具体类。
一系列相关或相互依赖对象:
这里所说的对象有2种理解角度:
从产品类别上分:手机与电脑 ------ 有些书会讲这个是 产品等级
从产品品牌上分:华为系产品(手机/电脑) ,小米系产品(手机/电脑) --- 有些书会讲这个是 产品族
(个人看法:没必要去扯这很玄乎的概念,能理解到抽象工厂模式设计精髓即可)
而那个接口就是:
华为系工厂 跟 小米系工厂 共同实现接口:ProductFactory
//代工厂
public class FABFactory {
//华为工厂
public static ProductFactory createHWFactory(){
return new HWProductFactory();
}
//小米工厂
public static ProductFactory createXMFactory(){
return new XMProductFactory();
}
}
最后从代工厂里面看出代码全貌,也就是抽象工厂模式精髓:
由待工厂(客户端)构建出不同品牌(产品族)工厂,然后让该工厂生产自己的品牌产品(产品族)。
1>客户端(应用层)不关心产品类实例如何被创建、实现等细节
2>一系列相关产品对象(属于同一个产品族)创建时有大量重复代码
3>提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖具体实现
优点:
1>对客户端遮蔽产品对象的构建过程
2>将一个系列的产品族统一到一起创建
缺点:
1>规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂接口,这会违背开闭原则,所以使用时需要反复衡量使用边界。
2>增加了系统的抽象性和理解难度
这个也可在JDK中找例子-java.sql
工厂:
mysql:
Connection--JdbcConnection--ConnectionImpl
oracle:
Connection--OracleConnectionWrapper--OracleConnection
产品:
mysql / oracle
Statement PreparedStatement CallableStatement
ConnectionImpl可以理解为mysql这个产品族工厂, 可以生产Statement PreparedStatement CallableStatement
@Override
public java.sql.Statement createStatement() throws SQLException {
return createStatement(DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
}
@Override
public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException {
return prepareStatement(sql, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
}
@Override
public java.sql.CallableStatement prepareCall(String sql) throws SQLException {
return prepareCall(sql, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
}
OracleConnection可以理解为oracle这个产品族工厂, 也可以生产Statement PreparedStatement CallableStatement
public Statement createStatement() throws SQLException {
return this.connection.createStatement();
}
public PreparedStatement prepareStatement(String var1) throws SQLException {
return this.connection.prepareStatement(var1);
}
public CallableStatement prepareCall(String var1) throws SQLException {
return this.connection.prepareCall(var1);
}
到这整个工厂相关设计模式全部讲完了,用大白话方式对它们进行概括:
简单工厂:本质为选择实现,不同参数构建不同实例对象
工厂方法:本质还是选择实现,构建方式由直接创建转为由子类/接口实现类延迟实现。
抽象工厂:本质依然是选择实现,构建对象在是一个,而是一个产品族
简单工厂:直接构建对象,一次一个
工厂方法:子类/接口实现类间接构建对象, 一次一个
抽象工厂:子类/接口实现类间接构建对象,一次一个产品族