概述
工厂方法(FactoryMethod)模式的定义:
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
这满足创建型模式中所要求的“创建与使用相分离”的特点。
工厂方法模式分为三种:
简单工厂模式:
定义:一个工厂方法,依据传入的参数,工厂生成对应的产品对象;
创建一个接口:
public interface IDataSource {
public String getConnection();
}
它有三个实现类,分别为:
public class C3p0DataSourceImpl implements IDataSource {
public String getConnection () {
return "c3p0";
}
}
public class DruidDataSourceImpl implements IDataSource {
public String getConnection () {
return "druid";
}
}
public class PooledDataSourceImpl implements IDataSource {
public String getConnection () {
return "pooled";
}
}
然后,在创建一个工厂类:
public class SingleBeanFactory {
public static IDataSource getDataSource(String name){
name = name.toLowerCase();
if ("pooled".equals(name)){
return new PooledDataSourceImpl();
}else if ("druid".equals(name)){
return new DruidDataSourceImpl();
}else if ("c3p0".equals(name)){
return new C3p0DataSourceImpl();
}
return null;
}
}
编写测试方法:
@Test
public void testSingleBeanFactory(){
IDataSource dataSource = SingleBeanFactory.getDataSource("c3p0");
String connection = dataSource.getConnection();
System.out.println(connection);
}
但是每当我们需要添加新的数据源的时候,就必然要修改工厂类,这显然违反了开闭原则,不太可取。
工厂方法模式:
定义:将工厂提取成一个接口或抽象类,具体生产什么产品由子类决定,根据需要创建对应的工厂然后生成对象。
创建一个工厂接口:
public interface IDataSourceFactory {
public IDataSource createDataSource();
}
它有三个实现类,分别为:
public class C3p0DataSourceFactoryImpl implements IDataSourceFactory {
public IDataSource createDataSource () {
return new C3p0DataSourceImpl();
}
}
public class DruidDataSourceFactoryImpl implements IDataSourceFactory {
public IDataSource createDataSource () {
return new DruidDataSourceImpl();
}
}
public class PooledDataSourceFactoryImpl implements IDataSourceFactory {
public IDataSource createDataSource () {
return new PooledDataSourceImpl();
}
}
编写测试方法:
@Test
public void testFactoryMethod(){
IDataSourceFactory c3p0Factory = new C3p0DataSourceFactoryImpl();
IDataSource dataSource = c3p0Factory.createDataSource();
String connection = dataSource.getConnection();
System.out.println(connection);
IDataSourceFactory druidFactory = new DruidDataSourceFactoryImpl();
dataSource = druidFactory.createDataSource();
connection = dataSource.getConnection();
System.out.println(connection);
IDataSourceFactory pooledFactory = new PooledDataSourceFactoryImpl();
dataSource = pooledFactory.createDataSource();
connection = dataSource.getConnection();
System.out.println(connection);
}
工厂方法模式虽然解耦了,也遵循了开闭原则,但是需要的产品很多的话,需要创建非常多的工厂,所以这种方式的缺点也很明显。
抽象工厂模式:
定义:抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类。
创建一个产品接口:
public interface IDataSource {
public String getConnection();
}
它有两个实现类,分别为:
public class C3p0DataSourceImpl implements IDataSource {
public String getConnection () {
return "c3p0";
}
}
public class DruidDataSourceImpl implements IDataSource {
public String getConnection () {
return "druid";
}
}
新增一个产品接口:
public interface IPropertyFile {
public String readPropertyFile();
}
它有两个实现类,分别为:
public class MysqlPropertyFileImpl implements IPropertyFile {
public String readPropertyFile () {
return "mysql配置文件";
}
}
public class OraclePropertyFileImpl implements IPropertyFile {
public String readPropertyFile () {
return "oracle配置文件";
}
}
创建一个抽象工厂接口:
public interface IDataSourceAndPropertiesFactory {
public IDataSource createDataSource();
public IPropertyFile readPropertyFile();
}
它有两个实现类,分别为:
public class MysqlAndC3p0DataSourceImpl implements IDataSourceAndPropertiesFactory {
public IDataSource createDataSource () {
return new C3p0DataSourceImpl();
}
public IPropertyFile readPropertyFile () {
return new MysqlPropertyFileImpl();
}
}
public class OracleAndDruidDataSourceImpl implements IDataSourceAndPropertiesFactory {
public IDataSource createDataSource () {
return new DruidDataSourceImpl();
}
public IPropertyFile readPropertyFile () {
return new OraclePropertyFileImpl();
}
}
编写测试方法
@Test
public void testAbstractFactoryMethod() {
IDataSourceAndPropertiesFactory oracleAndDruidDataSource = new OracleAndDruidDataSourceImpl();
IDataSource dataSource = oracleAndDruidDataSource.createDataSource();
String connection = dataSource.getConnection();
System.out.println(connection);
IPropertyFile iPropertyFile = oracleAndDruidDataSource.readPropertyFile();
String s = iPropertyFile.readPropertyFile();
System.out.println(s);
IDataSourceAndPropertiesFactory mysqlAndC3p0DataSource = new MysqlAndC3p0DataSourceImpl();
IDataSource dataSource1 = mysqlAndC3p0DataSource.createDataSource();
String connection1 = dataSource1.getConnection();
System.out.println(connection1);
IPropertyFile iPropertyFile1 = mysqlAndC3p0DataSource.readPropertyFile();
String s1 = iPropertyFile1.readPropertyFile();
System.out.println(s1);
}