欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

工厂模式

程序员文章站 2022-07-14 08:55:21
...

当我们获取数据库连接(mysql,oracle,db2)的时候,一般会用到这样的代码:

DbConnection getConnection(String type){
	DbConnection dc;
	if(type.equals("mysql")){
		dc=new MySqlConnection();
	}else if(type.equals("oracle")){
		dc=new OracleConnection();
	}else if(type.equals("db2")){
		dc=new Db2Connection();
	}
	//对连接进行初始化、准备工作、正式连接
	dc.init();
	dc.prepare();
	dc.connect();
	return dc;
}

问题:

当有新的连接类型,或者要去除某些数据库连接,我们需要修改代码。

以上代码没有对修改关闭。

 

解决方法:

在getConnection方法中封装创建连接的代码(createConnection),

把创建连接的代码移到另一个对象中,由这个对象专门创建连接。我们称这个对象为“工厂”。

我们的设计应该:对扩展开放,对修改关闭。

 

简单工厂:无法由子类决定要实例化的类是哪一个,没有依赖抽象。

package com.ez.biz;

import com.ez.DbConnection;
/**
 * @author 窗外赏雪(EZ编程网)
 */
public class FactoryTest {
	public static void main(String[] args) {
		SimpleDbConnectionFactory factory=new SimpleDbConnectionFactory();
		//注入简单工厂
		DbUnit dbUnit=new DbUnit(factory);
		DbConnection connection = dbUnit.getConnection("mysql");
		System.out.println("==============================");
		
		connection = dbUnit.getConnection("oracle");
		System.out.println("==============================");
		
		connection = dbUnit.getConnection("db2");
		System.out.println("==============================");
	}
}

 

package com.ez.biz;

import com.ez.DbConnection;
/**
 * 获取数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class DbUnit {
	SimpleDbConnectionFactory factory;
	
	public DbUnit(SimpleDbConnectionFactory factory) {
		this.factory=factory;
	}
	
	public DbConnection getConnection(String type){
		DbConnection dbConnection;
		//通过传入数据库类型,使用工厂创建对应数据库的连接
		dbConnection=factory.createDbConnection(type);
		
		dbConnection.init();
		dbConnection.prepare();
		dbConnection.connect();
		return dbConnection;
	}
}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.impl.Db2Connection;
import com.ez.impl.MySqlConnection;
import com.ez.impl.OracleConnection;
/**
 * 创建数据库连接的工厂类
 * @author 窗外赏雪(EZ编程网)
 */
public class SimpleDbConnectionFactory {
	public DbConnection createDbConnection(String type){
		DbConnection dbConnection=null;
		if("mysql".equals(type)){
			dbConnection=new MySqlConnection();
		}else if("oracle".equals(type)){
			dbConnection=new OracleConnection();
		}else if("db2".equals(type)){
			dbConnection=new Db2Connection();
		}
		return dbConnection;
	}
}

 

package com.ez;
/**
 * 数据库连接接口,所有数据库连接必须实现该接口 
 * @author 窗外赏雪(EZ编程网)
 */
public abstract class DbConnection {
	public void init(){
		System.out.println("DbConnection init");
	}
	
	public void prepare(){
		System.out.println("DbConnection prepare");
	}
	
	public void connect(){
		System.out.println("DbConnection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * DB2数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class Db2Connection extends DbConnection{
	public void connect(){
		System.out.println("Db2Connection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * mysql数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class MySqlConnection extends DbConnection{
	public void connect(){
		System.out.println("MySqlConnection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * oracle数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class OracleConnection extends DbConnection{
	public void connect(){
		System.out.println("OracleConnection connect");
	} 
}

 静态工厂:用静态方法定义一个简单的工厂,静态工厂不能通过继承(多态)来改变创建方法的行为。

 

工厂模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

 

工厂模式能够封装具体类型的实例化

抽象的Dbunit类提供了一个创建对象的抽象方法,也称为“工厂方法”。在抽象的Dbunit中,任何其他实现的方法,如:getConnection(),都可以使用这个工厂方法所制造出来的产品,但是只有子类真正实现这个工厂方法并创建产品。

package com.ez.biz;

import com.ez.DbConnection;
/**
 * 工厂模式测试类
 * @author 窗外赏雪(EZ编程网)
 */
public class FactoryTest {
	public static void main(String[] args) {
		DbUnit dbUnit=new NewDbUnit();
		DbConnection connection = dbUnit.getConnection("mysql");
		connection = dbUnit.getConnection("oracle");
		connection = dbUnit.getConnection("db2");
		System.out.println("==============================");
		
		dbUnit=new OldDbUnit();
		connection = dbUnit.getConnection("mysql");
		connection = dbUnit.getConnection("oracle");
		connection = dbUnit.getConnection("db2");
	}
}

 

package com.ez.biz;

import com.ez.DbConnection;
/**
 * 这是抽象创建者,定义了一个抽象的工厂方法,让子类实现此方法制造产品。
 * @author 窗外赏雪(EZ编程网)
 */
public abstract class DbUnit {
	
	public DbConnection getConnection(String type){
		DbConnection dbConnection;
		//通过传入数据库类型,使用工厂创建对应数据库的连接
		dbConnection=createDbConnection(type);
		
		dbConnection.init();
		dbConnection.prepare();
		dbConnection.connect();
		return dbConnection;
	}
	/**
	 * 抽象的工厂方法,让子类实现此方法制造产品。
	 * @param type
	 * @return
	 */
	public abstract DbConnection createDbConnection(String type);
}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.impl.NewDb2Connection;
import com.ez.impl.NewMySqlConnection;
import com.ez.impl.NewOracleConnection;
/**
 * 新版本的数据库连接,子类实现方法制造产品。
 * @author 窗外赏雪(EZ编程网)
 */
public class NewDbUnit extends DbUnit{

	@Override
	public DbConnection createDbConnection(String type) {
		DbConnection dbConnection = null;
		if("mysql".equals(type)){
			dbConnection = new NewMySqlConnection();
		}else if("oracle".equals(type)){
			dbConnection = new NewOracleConnection();
		}else if("db2".equals(type)){
			dbConnection = new NewDb2Connection();
		}
		return dbConnection;
	}

}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.impl.OldDb2Connection;
import com.ez.impl.OldMySqlConnection;
import com.ez.impl.OldOracleConnection;
/**
 * 老版本的数据库连接,子类实现方法制造产品。
 * @author 窗外赏雪(EZ编程网)
 */
public class OldDbUnit extends DbUnit{

	@Override
	public DbConnection createDbConnection(String type) {
		DbConnection dbConnection = null;
		if("mysql".equals(type)){
			dbConnection = new OldMySqlConnection();
		}else if("oracle".equals(type)){
			dbConnection = new OldOracleConnection();
		}else if("db2".equals(type)){
			dbConnection = new OldDb2Connection();
		}
		return dbConnection;
	}

}

 

package com.ez;
/**
 * 数据库连接接口,所有数据库连接必须实现该接口 
 * @author 窗外赏雪(EZ编程网)
 */
public abstract class DbConnection {
	public void init(){
		System.out.println("DbConnection init");
	}
	
	public void prepare(){
		System.out.println("DbConnection prepare");
	}
	
	public void connect(){
		System.out.println("DbConnection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 新版本的DB2数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class NewDb2Connection extends DbConnection{
	public void connect(){
		System.out.println("NewDb2Connection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 新版本的mysql数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class NewMySqlConnection extends DbConnection{
	public void connect(){
		System.out.println("NewMySqlConnection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 新版本的oracle数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class NewOracleConnection extends DbConnection{
	public void connect(){
		System.out.println("NewOracleConnection connect");
	} 
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 老版本的DB2数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class OldDb2Connection extends DbConnection{
	public void connect(){
		System.out.println("OldDb2Connection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 老版本的mysql数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class OldMySqlConnection extends DbConnection{
	public void connect(){
		System.out.println("OldMySqlConnection connect");
	}
}

 

package com.ez.impl;

import com.ez.DbConnection;
/**
 * 老版本的oracle数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class OldOracleConnection extends DbConnection{
	public void connect(){
		System.out.println("OldOracleConnection connect");
	} 
}

 

我们使用工厂来创建连接,通过传入不同的工厂,可以创建出不同的连接。但是客户端代码始终不变。

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.DbConnectionFactory;
/**
 * @author 窗外赏雪(EZ编程网)
 */
public class FactoryTest {
	
	public static void main(String[] args) throws Exception {
		DbConnectionFactory factory=new SimpleDbConnectionFactory();
		//注入简单工厂
		DbUnit dbUnit=new DbUnit(factory);
		DbConnection connection = dbUnit.getConnection("mysql");
		connection = dbUnit.getConnection("oracle");
		connection = dbUnit.getConnection("db2");
		System.out.println("==============================");
		
		factory=new ComplexDbConnectionFactory();
		dbUnit=new DbUnit(factory);
		connection = dbUnit.getConnection("mysql");
		connection = dbUnit.getConnection("oracle");
		connection = dbUnit.getConnection("db2");
		System.out.println("==============================");
	}
}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.DbConnectionFactory;
/**
 * 获取数据库连接
 * @author 窗外赏雪(EZ编程网)
 */
public class DbUnit {
	DbConnectionFactory factory;
	
	public DbUnit(DbConnectionFactory factory) {
		this.factory=factory;
	}
	
	public DbConnection getConnection(String type){
		DbConnection dbConnection;
		//通过传入数据库类型,使用工厂创建对应数据库的连接
		dbConnection=factory.createDbConnection(type);
		
		dbConnection.init();
		dbConnection.prepare();
		dbConnection.connect();
		return dbConnection;
	}
}

 

 

package com.ez;

public abstract class DbConnectionFactory {
	public abstract DbConnection createDbConnection(String type);
}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.DbConnectionFactory;
import com.ez.impl.ComplexDb2Connection;
import com.ez.impl.ComplexMySqlConnection;
import com.ez.impl.ComplexOracleConnection;
/**
 * 具体工厂
 * @author 窗外赏雪(EZ编程网)
 */
public class ComplexDbConnectionFactory extends DbConnectionFactory{
	
	@Override
	public DbConnection createDbConnection(String type) {
		DbConnection dbConnection=null;
		if("mysql".equals(type)){
			dbConnection=new ComplexMySqlConnection();
		}else if("oracle".equals(type)){
			dbConnection=new ComplexOracleConnection();
		}else if("db2".equals(type)){
			dbConnection=new ComplexDb2Connection();
		}
		return dbConnection;
	}
	
}

 

package com.ez.biz;

import com.ez.DbConnection;
import com.ez.DbConnectionFactory;
import com.ez.impl.Db2Connection;
import com.ez.impl.MySqlConnection;
import com.ez.impl.OracleConnection;
/**
 * 创建数据库连接的工厂类
 * @author 窗外赏雪(EZ编程网)
 */
public class SimpleDbConnectionFactory extends DbConnectionFactory{
	public DbConnection createDbConnection(String type){
		DbConnection dbConnection=null;
		if("mysql".equals(type)){
			dbConnection=new MySqlConnection();
		}else if("oracle".equals(type)){
			dbConnection=new OracleConnection();
		}else if("db2".equals(type)){
			dbConnection=new Db2Connection();
		}
		return dbConnection;
	}
}

 

相关标签: 工厂模式