Php “分享”;统计类“;在许多班级之间

Php “分享”;统计类“;在许多班级之间,php,codeigniter,Php,Codeigniter,我有我的手机类,它将定义玩家,敌人,以及手机。。。 我有一个item类,这是不言自明的 让我们假设为了这个例子,我们有三个统计数据 -> Strength -> Dexterity -> Intelligence 我计划在我的手机和我的物品上有这些统计数据,如果在我的物品上它们不同于0,那么它们就是我手机的修改器 我应该如何将这些存储在我的类中 如果是这样的话: MY_Item { var $stats_dex; var $stats_int; var $s

我有我的手机类,它将定义玩家,敌人,以及手机。。。 我有一个item类,这是不言自明的

让我们假设为了这个例子,我们有三个统计数据

-> Strength
-> Dexterity
-> Intelligence
我计划在我的手机和我的物品上有这些统计数据,如果在我的物品上它们不同于0,那么它们就是我手机的修改器

我应该如何将这些存储在我的类中

如果是这样的话:

MY_Item
{   
  var $stats_dex;
  var $stats_int;
  var $stats_str;
}
或者可能有另一个类,“统计类”,每个其他类也会有

MY_Item
{
  var $stats = new MY_Stats;
}
我的手机也一样吗

因为在我的手机里,我还要计算装备的物品。。。所以我最终会得到这样的结果:

class MY_Mobile
{   
  var $stats_dex;
  var $stats_int;
  var $stats_str;
  var $modifier_stats_dex;
  var $modifier_stats_int;
  var $modifier_stats_str;
}

现在我正在处理第一个原型,但我已经感到不安了……

我认为一个简单的答案是,这就是方法派上用场的地方。如果您的“业务规则”是移动设备的stat是本机stat和items将进行的所有修改的总和,那么我的建议是将stats同时提供给移动设备和items(稍后将详细介绍),然后为您的移动类提供一个方法,例如负责求和的
getStat($statName)
。这可能被称为“facade”设计模式(您向外部世界提供了一个干净的界面,掩盖了条目修改统计信息的细节)。要彻底解决这个问题,请将您的成员属性标记为protected或private,并且只允许应用程序的其他部分使用getter

关于给多个类赋予许多相同的属性/行为的问题,有几种选择。最基本的(在本例中可能是错误的)是给他们一个共同的祖先,例如“statableEntity”。这是一个糟糕的选择,因为PHP是一种继承语言,并且可存储性不是类固有的

第二个选择是PHP相对较新的特性Traits。这比类继承要好一点,因为它开始感觉像多重继承。如果无论哪个类需要该特性,行为都完全相同,那么这是一个很好的选择

第三种选择是使用接口。在该选项中,实现接口的所有类都需要具有相同的方法,但它们不都需要在方法体中使用相同的代码。当依附于接口的类可能希望实现稍微不同的行为时,这是一个很好的选择


我认为在您的情况下,我建议使用接口,因为与物品上的相同属性相比,一个人的属性可能会以不同的方式响应上下文(例如,物品属性的当前值可能会降低,因为物品“旧”或“需要修复”,或者一个人的属性会因饥饿而改变,等等)

你有没有考虑过使用
trait
s这似乎是适合这份工作的工具。我目前不知道你提到的“traits”是什么。我会做一些搜索。我想我会选择一个单独的stats类,继承CI_模型(或者我的CI_模型,如果您已经用自己的扩展了CI_模型),然后让其他类继承stats类。对于一组非“叶”类固有的行为,继承可能是一个糟糕的选择。例如,我有一个速度(stat),我的新Nike鞋有一个+1速度(stat)。然而,我继承了“演员”或“动物”的血统,而我的鞋子却没有这种血统。Traits、Decorator设计模式或界面都是很好的选择。谢谢你,我读了一些Traits的相关文章,认为它会奏效。但既然你们提到了界面,我也要看看它们。至于你关于protected、private、getstats等的观点,它们实际上在项目中是这样的,但是,由于这是第一次测试,我没有“正确地”完成它。进入阅读界面!我还不太确定接口。。。他们只是定义了我的类必须具备的一些“必须做的事情”吗?我正在阅读/发现的所有例子似乎都是这样的。定义接口,解释接口中的方法和常量,然后在实现接口的每个类中,我们重新定义方法并使用它?谢谢。@Santaclaus,没错。应用程序需要以一致的方式处理类(通过依赖“必有”方法),但这些类可以自行决定实现这些方法意味着什么。特性是否会填满接口必有方法?虽然这两个都有可能是愚蠢的?我认为是这样。但是拥有接口的“契约”性质是通过拥有特性来实现的。也就是说,traits在PHP中是编译时的,因此该接口实际上没有额外的好处。在这两种情况下,您都可以在对象上键入hint和/或reflect,以确定它是否具有所需的方法。区别更多的是关于“它们是否只共享接口?还是共享相同的实现?”