web-dev-qa-db-ja.com

より一般的なコードを書くのに役立つ

私はコードイグナイターを使用して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つのクラッド関数の実装に固執する必要がありますか?

4
morbidCode

抽象基本クラスと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'
            )
        );
    }
}

使い方は以前と似ています。

4
Dan Armstrong