草庐IT

php - 奇怪的多重继承的优雅替代品

coder 2024-04-13 原文

我不能说这是一个问题,但更多的是征求意见,我相信许多其他人可以从澄清这个问题中受益。

这是我的实际案例:

我有一个名为 DataExchangeService 的抽象类和许多扩展这个类的子类(这是我的 MVC 框架中的基 CONTROLLER 类)。处理数据定义(用户、类型、部分等)的管理模块在大多数情况下都具有 100% 相似性的添加、编辑、删除、列表方法。我知道这一点,因为我只使用搜索和替换来复制它们。现在问题不是我所有的 DateExchangeService 子类都处理数据定义,所以在足够多的情况下我不需要 CRUD 方法。

多重继承将在另一个类中定义这些 CRUD 方法及其行为,并在需要的地方扩展这两个类,但我确实认为这是棘手的事情,我不使用它(+PHP 没有这样的功能)。那么最佳做法是什么?

以下是我想到的方法:

案例A

  1. 定义一个将所有这些方法参数化的 CRUDHandler 类。

  2. 在需要的地方创建一个 CRUDHandler 类型的属性,并实现将强制我使用这些方法的 CRUD 接口(interface)。

  3. 在实现方法的主体中,我添加了如下内容:

public function edit($params) {
    $this->params = $params;
    $this->CRUDHandler->handle("edit", $this);
}

(在 PHP 中,这可以通过 __call() 魔术方法完成。)

案例B

  1. 将类 CRUDHandler 定义为扩展基础 DataExchangeService。

  2. 定义特定类型的 DataExchangeService 时(例如 UsersExchangeService)而不是扩展 DataExchangeService 你扩展 CRUDHandler, 这样你就可以在需要的时候得到你想要的一切。

那么,对于这种多重继承方法还有其他意见吗?

谢谢

最佳答案

目前有一种流行的思维方式是“favour composition over inheritance”。 Google 上的信息太多,无法在此一一列举,但我只想说,除了偶尔出现的抽象基类之外,我已经 2-3 年没有使用继承了。

主要思想是任何给定的类,而不是扩展允许它提供所需功能的基类,都将依赖于其他类。其实保持东西SOLID ,它将依赖于接口(interface),这些接口(interface)提供了一个约定,表明它们将执行一个功能。

然后您会到达您的 Controller 类已传入服务/组件的位置,它委托(delegate)给这些服务/组件以完成特定工作。

请注意,反之亦然。如果您有一个依赖于大量外部服务的类,尤其是如果不是类中的每个公共(public)方法最终都使用所有这些服务,那么您实际上可能毕竟有两个类。 IE。您的 Controller 通过做不止一项工作来“违反”单一责任原则。使用 Web 框架中的 Controller 时,这特别容易意外地做到,因为它们鼓励这样做。

在这一点上,我认为阅读以下内容是明智的:

关于php - 奇怪的多重继承的优雅替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4734406/

有关php - 奇怪的多重继承的优雅替代品的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. ruby-on-rails - 更好的替代方法 try( :output). try( :data). try( :name)? - 2

    “输出”是一个序列化的OpenStruct。定义标题try(:output).try(:data).try(:title)结束什么会更好?:) 最佳答案 或者只是这样:deftitleoutput.data.titlerescuenilend 关于ruby-on-rails-更好的替代方法try(:output).try(:data).try(:name)?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  3. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  4. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  5. ruby - 获取数组中的值并最小化某个类属性的最优雅的方法是什么? - 2

    假设我有以下类(class):classPersondefinitialize(name,age)@name=name@age=ageenddefget_agereturn@ageendend我有一组Person对象。是否有一种简洁的、类似于Ruby的方法来获取最小(或最大)年龄的人?如何根据它对它们进行排序? 最佳答案 这样做会:people_array.min_by(&:get_age)people_array.max_by(&:get_age)people_array.sort_by(&:get_age)

  6. ruby-on-rails - 优雅的 Rails : multiple routes, 相同的 Controller Action - 2

    让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来

  7. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  8. ruby - 允许主机名包含下划线的 URI.parse 的替代方法 - 2

    我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用:

  9. ruby-on-rails - 浮点乘法的 Ruby 奇怪问题 - 2

    有没有人用ruby​​解决这个问题:假设我们有:a=8.1999999我们想将它四舍五入为2位小数,即8.20,然后乘以1,000,000得到8,200,000我们是这样做的;(a.round(2)*1000000).to_i但是我们得到的是8199999,为什么?奇怪的是,如果我们乘以1000、100000或10000000而不是1000000,我们会得到正确的结果。有人知道为什么吗?我们正在使用ruby​​1.9.2并尝试使用1.9.3。谢谢! 最佳答案 每当你在计算中得到时髦的数字时使用bigdecimalrequire'bi

  10. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

随机推荐