私はコードイグナイターを使用してphp MVCプロジェクトをやっています。 aとbの2つのモデルがあります。
各クラスには4つの関数(挿入、削除、更新、表示)が含まれており、それらの実装は互いにほとんど同じです。友人は、4つの関数の汎用バージョンをユーティリティクラス内に置くことを提案し、2つのモデルはそれらの関数にアクセスできます。たとえば、挿入の一般的な実装は次のとおりです。
public function insert($tableName, $columns, $preds = null)
{
// call code igniter's insert function
}
// do the same with delete, update and view
しかし、以前に データ指向プログラミング を導入し、最近phpを見つけたことが関数の配列を持つことができるので、これを改善できると思います。
私がやりたいことは:各クラスで、キー「挿入」、「追加」、「削除」、「更新」を持つクラスに固有の4つのコードイグナイターCRUD関数を保持するグローバル配列を作成します。
CRUD操作ごとに4つの関数を作成するのではなく、クラスごとに1つのユーティリティ関数と1つの一般的な実行関数を作成します。
注:私はphpを非常に初めて使用しているため、phpコードの一部が機能しない可能性があります。これはまだ直接実装していません。
// in the utility class
public function execute($dataFunctions, $op, $tableName, $columns)
{
// this will not work, I am not yet familiar with putting functions inside an array
$dataFunctions['op']($tableName,$columns);
}
// on class a
public function execute($op, $columns)
{
// dataFunctions is the name of the global array
utils->execute($dataFunctions,$op,"a",$colums)
}
// same with class b
事は、私がこれが良い考えであることを完全に確信していません。私はこれを以前にやったことがありません。私はどんな欠点にも気づいていないかもしれません。関数の配列を使用した方がいいですか?それとも、4つのクラッド関数の実装に固執する必要がありますか?
抽象基本クラスと2つの具象派生クラスがあります。何が違うのか教えてくれませんでしたが、「それらの実装はほとんど同じです」とだけ言っていました。違いはデータベース名だけだとしましょう:
abstract class Model_base {
public function insert($tableName, $columns, $preds = null) {
$db = $this->getDB();
// call code igniter's insert function on $db
}
// Gets the database to operate on
abstract function getDB();
}
class a extends Model_base {
function getDB() {
return $this->load->database('db_a', TRUE);
}
}
class b extends Model_base {
function getDB() {
return $this->load->database('db_b', TRUE);
}
}
以下も参照してください。
https://ellislab.com/codeigniter/user-guide/database/connecting.html 複数のデータベースへの接続
https://ellislab.com/codeigniter/user-guide/database/configuration.html データベース構成
編集:使用例:
次の2つのインスタンスを作成できます。
$modelA = new a():
$modelB = new b():
$modelA->insert(...);
$modelB->insert(...);
または、モデルセレクターを使用することもできます。
$model = $useA ? new a() : new b();
$model->insert(...);
ところで、実際に選択したデータベースのみが異なる場合は、データベース名(db_aまたはdb_b)またはCode Igniterデータベースオブジェクトを単一のクラスのコンストラクターに渡すだけで、抽象クラスや派生クラスは必要ありません。それはすべて、クラス間の違いに依存します。
編集2:「実際には唯一の違いはテーブルと列の名前であり、どちらも1つのデータベース内にあります」
テーブルと列の名前のみが変更されると仮定します。
class Model_base {
private $tableName1;
private $tableName2;
private $colName1;
private $colName2;
function __construct(
$tableName1,
$tableName2,
$colName1,
$colName2
) {
$this->tableName1 = $tableName1;
$this->tableName2 = $tableName2;
$this->colName1 = $colName1;
$this->colName2 = $colName2;
}
public function insert($preds = null) {
// call code igniter's insert function using table and column names given in constructor
// ...($this->tableName1, $this->colName2, ...);
}
}
class Model_a extends Model_base {
function __construct() {
parent::__construct(
'table1_a',
'table2_a',
'col1_a',
'col2_a'
);
}
}
class Model_b extends Model_base {
function __construct() {
parent::__construct(
'table1_b',
'table2_b',
'col1_b',
'col2_b'
);
}
}
使い方は以前と似ています。
編集3:テーブル名がたくさんある場合は短い方法ですが、「コンパイラ」のヘルプは少なくなります:
class Model_base {
private $tableNames;
private $colNames;
function __construct(array $tableNames, array $colNames) {
$this->tableNames = $tableNames;
$this->colNames = $colNames;
}
public function insert($preds = null) {
// call code igniter's insert function using table and column names given in constructor
// ...($this->tableNames['table_1'], $this->colNames['col_2'], ...);
}
}
class Model_a extends Model_base {
function __construct() {
parent::__construct(
array(
'table_1' => 'table_1a',
'table_2' => 'table_2a'
),
array(
'col_1' => 'col_1a',
'col_2' => 'col_2a'
)
);
}
}
class Model_b extends Model_base {
function __construct() {
parent::__construct(
array(
'table_1' => 'table_1b',
'table_2' => 'table_2b'
),
array(
'col_1' => 'col_1b',
'col_2' => 'col_2b'
)
);
}
}
使い方は以前と似ています。