さまざまなタイプのオブジェクトに対していくつかの一般的なアクション (ソーシャル ネットワークで「共有」する、または内部 Web ショップで「購入する」など) を実行する Yii ベースの PHP アプリケーションがあります。
現在、開発者はクラス定数を使用して、異なる型のオブジェクトを分離しています。そのようです:
モデル内:
class Referral extends CActiveRecord {
//... a lot more stuff here...
const ITEM_TYPE_PRODUCT = 'product';
const ITEM_TYPE_DESIGN = 'design';
const ITEM_TYPE_BRAND = 'brand';
const ITEM_TYPE_INVITE = 'invite';
const ITEM_TYPE_DESIGNER = 'designer';
//... a lot more stuff here...
}
その後、いくつかのコントローラーで:
// calling static method of Referral and pass a type IDs to change it's behavior
$referral_params = Referral::buildReferallParams(
Referral::TYPE_PINTEREST,
Referral::ITEM_TYPE_PRODUCT
)
このようにクラス定数を使用すると、コードが大幅に重複するため、削除したいと考えています。
個人的には、次のようにタイプのルックアップ テーブルを追加する必要があると思います。
CREATE TABLE `item_type` (
id int primary key auto_increment,
name varchar(255)
);
ItemType
そして、テーブルから ID を抽出する名前の Yii モデル クラスを作成します。
しかし、それは別の問題につながります: とにかくコード内でこの型 ID を使用する必要があり、長期間使用する必要があります。何らかの方法で ID の記号名を作成する必要があります。今のところ like の呼び出しReferral::ITEM_TYPE_PRODUCT
は非常に便利であり、Yii 風に変更することItemType::model()->findByAttributes(array('name' => 'Product'))
はまったく受け入れられません。
ItemType
新しい型を追加するたびに新しい定数を追加する必要があり、発生するのを待っている非同期の問題であるため、クラス定数の同じリスト (現在はコードベースを通じて複製されています) を維持することは避けたいと考えています。
では、問題は次のとおりです。ルックアップ テーブルの ActiveRecord を、'enum' のような数値定数のセットと同等に役立つようにするにはどうすればよいでしょうか?
ItemType のサブクラスを使用して、次のやや美しいソリューションを作成しました。
ProductItemType::id(); // returns lazy-loaded ID for 'Product' item type
BrandItemType::id(); // the same for 'Brand' item type
// ... and so on
しかし、現在は単一の基本クラスの 5 つのサブクラスが必要であり、後でさらに 6 つ以上のサブクラスが必要になる場合があります。実行可能なアーキテクチャ上のソリューションはありますか?
編集
重複の問題は次のとおりです。タイプ ID を宣言するクラス定数は、さまざまな項目タイプを何らかの方法で区別する必要があるすべてのクラスで再定義されます。最も「真の」解決策は、これを裏返しにして、オブジェクトのタイプに依存する機能をオブジェクト自体に移動することであることは知っていますが、テストカバレッジのないレガシーコードがあり、この解決策は今のところ夢にすぎません. 今私がしたいのは、この重複を取り除くことだけです。そして定数も。