`

工厂模式

阅读更多

当我们获取数据库连接(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;
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics