工厂模式

          工厂模式,与单例模式一样,属于创建型模式,而工厂模式还可以细分为:

(1)简单工厂模式,或者称之为静态工厂模式

(2)工厂方法模式

(3)抽象工厂模式

 

一、简单工厂模式

 既然工厂模式的目的是为了创建对象,首先得有要有待创建的对象,假如要生产一辆汽车,定义如下:

public abstract class Car {
    public abstract void run();
}

 这是一个抽象类,假如有两个实现类:

public class BWM extends Car{
    @Override
    public void run() {
        System.out.println("宝马汽车在跑");
    }
}
public class BYD extends Car{
    @Override
    public void run() {
        System.out.println("比亚迪汽车在跑");
    }
}

现在需要根据用户的需求返回不同是实例对象,创建一个工厂类:

public class SimpleFactory {
    public static Car getCar(String type){
        if ("BWM".equals(type)){
            return new BWM();
        }else if ("BYD".equals(type)){
            return new BYD();
        }else {
            System.out.println("输入的类型不正确");
            return null;
        }
    }
}

简单工厂的核心,就是这个工厂类了,实质就是,它根据传入的不同类型,返回不同的对象,由于返回对象的方法,一般都做成静态方法,所有又称之为,静态工厂。在使用时,只需要传入要创建的对象类型即可:

public class TestSimpleFactory {
    public static void main(String[] args) {
        Car car = SimpleFactory.getCar("BWM");
        car.run();
    }
}

 

二、工厂方法模式

工厂方法模式,与简单工厂相比,不同的是,对工厂进一步抽象,由具体的实例工厂创建对象

抽象工厂定义,返回汽车对象:

public interface CarFactory {
    Car getCar();
}

然后,由具体的工厂子类来实例化对象:

public class BWMFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new BWM();
    }
}
public class BYDFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new BYD();
    }
}

 使用也很简单,需要什么类型的汽车,就new一个对应的工厂,再由工厂方法对象即可:

public class TestFactoryMethod {
    public static void main(String[] args) {
        BWMFactory factory = new BWMFactory();
        Car car = factory.getCar();
        car.run();
    }
}

 

三、抽象工厂模式

    抽象工厂模式,与工厂方法模式的区别在于,抽象工厂可以返回多个不同类型的产品,而工厂方法只返回一种类型的产品,如果抽象工厂只返回一种类型的产品,则抽象工厂模式就退化为工厂方法模式。

抽象工厂返回多个类型的产品:

// 抽象工厂
public interface CarFactory {
    // 获取发动机
    CarEngine getCarEngine();
    // 获取方向盘
    CarWheel getCarWheel();
}

具体工厂:

public class BWMFactory implements CarFactory {

    @Override
    public CarEngine getCarEngine() {
        return new BWMEngine();
    }

    @Override
    public CarWheel getCarWheel() {
        return new BWMWheel();
    }
}
public class BYDFactory implements CarFactory {

    @Override
    public CarEngine getCarEngine() {
        return new BYDEngine();
    }

    @Override
    public CarWheel getCarWheel() {
        return new BYDWheel();
    }
}
CarEngine和CarWheel都是产品的抽象类,这样,工程类就可以返回多个不同类型的产品了
public class TestAbsFactory {
    public static void main(String[] args) {
        CarFactory bwmFactory = new BWMFactory();
        CarEngine carEngine = bwmFactory.getCarEngine();
        CarWheel carWheel = bwmFactory.getCarWheel();
        carEngine.engine();
        carWheel.wheel();
        System.out.println("====分割线====");
        CarFactory bydFactory = new BYDFactory();
        CarEngine carEngine2 = bydFactory.getCarEngine();
        CarWheel carWheel2 = bydFactory.getCarWheel();
        carEngine2.engine();
        carWheel2.wheel();

    }
}

 

四、应用实例

         相信大家都用过mybatis,对SqlSessionFactory肯定不会陌生,根据名字就可以知道,它使用了工厂模式:

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和Configuration对象,实现类有两个:

SqlSessionManager,我没有用过,一般都是用DefaultSqlSessionFactory,看看如何返回SqlSession的:
  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();
    }
  }

注意到,它是直接new了一个DefaultSqlSession,因为SqlSessionManager并没有用到,不用判断使用哪个

 return new DefaultSqlSession(configuration, executor, autoCommit);

 

再看DataSourceFactory获取数据源的工厂,也使用了工厂模式:

public interface DataSourceFactory {

  void setProperties(Properties props);

  DataSource getDataSource();

}

它有3个工厂子类:

Jndi用得比较少,我们看下UnpooledDataSourceFactory和PooledDataSourceFactory

 UnpooledDataSourceFactory在构造方法直接new了一个UnpooledDataSource

  public UnpooledDataSourceFactory() {
    this.dataSource = new UnpooledDataSource();
  }

而PooledDataSourceFactory继承于UnpooledDataSourceFactory,将返回的数据源变成PooledDataSource

  public PooledDataSourceFactory() {
    this.dataSource = new PooledDataSource();
  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值