我们有一个基于 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 创建一个符号名称。现在调用likeReferral::ITEM_TYPE_PRODUCT
很方便,改成Yii-flavoredItemType::model()->findByAttributes(array('name' => 'Product'))
是完全不能接受的。
我想避免在其中维护相同的类常量列表(现在通过我们的代码库复制),ItemType
因为每次添加新类型都需要添加新常量,这只是等待发生的不同步问题。
因此,问题如下:如何使查找表的 ActiveRecord 与类似“枚举”的数字常量集同样有用?
我使用 ItemType 的子类提供了以下一些漂亮的解决方案:
ProductItemType::id(); // returns lazy-loaded ID for 'Product' item type
BrandItemType::id(); // the same for 'Brand' item type
// ... and so on
但是如果现在需要单个基类的五个子类,以后可能需要另外六个。有没有可行的架构解决方案?
编辑
重复的问题是:声明类型 ID 的类常量在每个需要以某种方式区分不同项目类型的类中重新定义。我知道最“真实”的解决方案是将其从里到外反转并将取决于对象类型的功能移动到对象本身,但是我们有没有任何测试覆盖的遗留代码,这个解决方案现在只是一个梦想. 现在我想做的就是删除这个重复。还有常数。