動機(Motivation)
在軟體系統中,經常面臨着“一系列互相依賴的對象”的建立工作;同時,由于需求的變化,往往存在更多系列對象的建立工作。
如何應對這種變化?如何繞過正常的對象建立方法(new),提供一種“封裝機制”來避免客戶程式和這種“多系列具體對象建立工作”的緊耦合?
1.在代碼上看什麼是“一系列互相依賴的對象”
//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計
class EmployeeDAO
{
public:
vector<EmployeeDA> GetEmployee()
{
//Sql的連接配接對象
SqlConnection* connection = new SqlConnection();
connection->ConnectionString = "...";
//Sql指令對象
SqlCommand* command = new SqlCommand();
command->CommandText = "...";
command->SetConnection(connection);
//Sql的讀取對象
SqlDataReader* reader = command->ExecuteReader();
while (reader->Read())
{
}
}
};
//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計
//改進--建立一系列的基礎類
//資料庫通路有關的基類
class IDBConnection
{
};
class IDBCommand
{
};
class IDataReader
{
};
//三個工廠特别有相關性,就做成一個工廠,高内聚 松耦合
class IDBFactory
{
public:
virtual IDBConnection* CreateDBConnection() = 0;
virtual IDBCommand* CreateDBCommand() = 0;
virtual IDataReader* CreateDataReader() = 0;
};
//支援Sql的
class SqlDBConnection :public IDBConnection
{
};
class SqlDBCommand :public IDBCommand
{
};
class SqlDBDataReader :public IDataReader
{
};
class SqlDBFactory :public IDBFactory
{
public:
virtual IDBConnection* CreateDBConnection() = 0;
virtual IDBCommand* CreateDBCommand() = 0;
virtual IDataReader* CreateDataReader() = 0;
};
//支援Oracle的
class OracleDBConnect :public IDBConnection
{
};
class OracleDBCommand :public IDBCommand
{
};
class OracleDBDataReader :public IDataReader
{
};
class OraclDBFactory :public IDBFactory
{
public:
virtual IDBConnection* CreateDBConnection() = 0;
virtual IDBCommand* CreateDBCommand() = 0;
virtual IDataReader* CreateDataReader() = 0;
};
//到目前為止,勉強解決問題,暴露出來的問題:
//三個工廠對象必須是同系列的,都是MySql或者都是SqlServer----》解決方式Abstractor Factory抽象工廠(家族工廠)
class EmployeeDAO
{
IDBFactory* dbFactory;
public:
vector<EmployeeDO> GetEmployee()
{
//Sql的連接配接對象 //new有問題--立馬想到 Factory Method方法
IDBConnection* connection = dbFactory->CreateDBConnection();
connection->ConnectionString("...");
//Sql指令對象
IDBCommand* command = dbFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection);//關聯性
//Sql的讀取對象
IDataReader* reader = command->ExecuteReader();//關聯性
while (reader->Read())
{
}
}
};
//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計
//改進--建立一系列的基礎類
//資料庫通路有關的基類
class IDBConnection
{
};
class IDBConnectionFactory
{
virtual IDBConnection* CreateDBConnection() = 0;
};
class IDBCommand
{
};
class IDBCommandFactory
{
virtual IDBCommand* CreateDBCommand() = 0;
};
class IDataReader
{
};
class IDataReaderFactory
{
virtual IDataReader* CreateDataReader() = 0;
};
//支援Sql的
class SqlConnection :public IDBConnection
{
};
class SqlConnectFactory :public IDBConnectionFactory
{
};
class SqlCommand :public IDBCommand
{
};
class SqlCommandFactory :public IDBCommandFactory
{
};
class SqlDataReader :public IDataReader
{
};
class SqlDataReaderFactory :public IDBConnectionFactory
{
};
//支援Oracle的
class OracleConnect :public IDBConnection
{
};
class OracleConnectFactory :public IDBConnectionFactory
{
};
class OracleCommand :public IDBCommand
{
};
class OracleCommandFactory :public IDBCommandFactory
{
};
class OracleDataReader :public IDataReader
{
};
class OracleDataReaderFactory :public IDataReaderFactory
{
};
//到目前為止,勉強解決問題,暴露出來的問題:
//三個工廠對象必須是同系列的,都是MySql或者都是SqlServer----》解決方式Abstractor Factory
class EmployeeDAO
{
IDBConnectionFactory* dbConnectionFactory;
IDBCommandFactory* dbCommandFactory;
IDataReaderFactory* dbReaderFacotory;
public:
vector<EmployeeDO> GetEmployee()
{
//Sql的連接配接對象 //new有問題--立馬想到 Factory Method方法
IDBConnection* connection = dbConnectionFactory->CreateDBConnection();
connection->ConnectionString("...");
//Sql指令對象
IDBCommand* command = dbCommandFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection);
//Sql的讀取對象
IDataReader* reader = command->ExecuteReader();
while (reader->Read())
{
}
}
};
模式定義
提供一個接口,讓該接口負責建立一系列“相關或者互相依賴的對象”,無需指定他們具體的類。
----《設計模式》GoF
要點總結