抽象工厂模式


抽象工厂模式

1.基础知识

定义∶

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口

无须指定它们具体的类

类型∶创建型

适用场景

客户端(应用层)不依赖于产品类实例如何被创建、实现等细节

强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码

提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

优点

具体产品在应用层代码隔离,无须关心创建细节

将一个系列的产品族统一到一起创建

缺点

规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,,需要修改抽象工厂的接口

增加了系统的抽象性和理解难度


抽象工厂模式就是解决产品族的问题的

image-20220117220609802


2.实战

总算到这个模式了,一直想用KFC和麦当劳举例子,感觉很有意思,很好玩,走起!

这里的KFC工厂就是一个产品族,生产各式各样的单品,比如华莱士那就是一个新的factory了。

UML如图:

image-20220117225422922

/**
 * @Author LYS
 * @Date 2022/1/17 22:39
 * @Version 1.0
 */
public interface ChickFactory {
    IceCream makeIceCream();

    Hamburger makeHamburger();
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:39
 * @Version 1.0
 */
public abstract class Hamburger {
    public abstract void  getHamburger();
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:40
 * @Version 1.0
 */
public abstract class IceCream {
    public abstract void  getIceCream();

}
/**
 * @Author LYS
 * @Date 2022/1/17 22:48
 * @Version 1.0
 */
public class KFCChickFactory implements ChickFactory{
    @Override
    public IceCream makeIceCream() {
        return new KFCIceCream();
    }

    @Override
    public Hamburger makeHamburger() {
        return new KFCHamburger();
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:41
 * @Version 1.0
 */
public class KFCHamburger extends Hamburger{
    @Override
    public void getHamburger() {
        System.out.println("生产肯德基文和友香辣小龙虾烤鸡汉堡");
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:45
 * @Version 1.0
 */
public class KFCIceCream extends IceCream{
    @Override
    public void getIceCream() {
        System.out.println("生产肯德基北海道冰淇淋");
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:50
 * @Version 1.0
 */
public class McDonaldChickFactory implements ChickFactory{
    @Override
    public IceCream makeIceCream() {
        return new McDonaldIceCream();
    }

    @Override
    public Hamburger makeHamburger() {
        return new McDonaldHamburger();
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:43
 * @Version 1.0
 */
public class McDonaldHamburger extends Hamburger{
    @Override
    public void getHamburger() {
        System.out.println("生产麦当劳安格斯max厚牛培根汉堡");
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:46
 * @Version 1.0
 */
public class McDonaldIceCream extends IceCream{
    @Override
    public void getIceCream() {
        System.out.println("生产麦当劳麦旋风");
    }
}
/**
 * @Author LYS
 * @Date 2022/1/17 22:50
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        ChickFactory chickFactory1 = new KFCChickFactory();
        Hamburger hamburger1 = chickFactory1.makeHamburger();
        IceCream iceCream1 = chickFactory1.makeIceCream();
        hamburger1.getHamburger();
        iceCream1.getIceCream();

        ChickFactory chickFactory2 = new McDonaldChickFactory();
        Hamburger hamburger2 = chickFactory2.makeHamburger();
        IceCream iceCream2 = chickFactory2.makeIceCream();
        hamburger2.getHamburger();
        iceCream2.getIceCream();
    }
}

控制台输出:

image-20220117225545646


3.源码

比如sql的Connection接口,这里的Statement,PreparedStatement都是Connection的产品族

public interface Connection  extends Wrapper, AutoCloseable {


    Statement createStatement() throws SQLException;

    PreparedStatement prepareStatement(String sql)
        throws SQLException;

SqlSessionFactory 返回的SqlSession和Configuration也是一个产品族

import java.sql.Connection;


public interface SqlSessionFactory {

  SqlSession openSession();

  SqlSession openSession(boolean autoCommit);
  SqlSession openSession(Connection connection);
  SqlSession openSession(TransactionIsolationLevel level);

  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);

  Configuration getConfiguration();

}

可以看看这个类的具体实现

SqlSession openSession(ExecutorType execType, boolean autoCommit);

DefaultSqlSessionFactory类实现了这个方法,接口设置的返回类型是SqlSession,但实际返回的是DefaultSqlSession,是其子类

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
  Transaction tx = null;
  try {
    final Environment environment = configuration.getEnvironment();
    final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
    final Executor executor = configuration.newExecutor(tx, execType);
    return new DefaultSqlSession(configuration, executor, autoCommit);
  } catch (Exception e) {
    closeTransaction(tx); // may have fetched a connection so lets call close()
    throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

4.工厂方法和抽象工厂的区别

工厂方法模式解决同一产品等级的问题

抽象工厂模式解决产品族的问题

相关