我该如何解决这个 OOP 设计问题?
我有一个包含 3 个组件的系统:
报告 - 包含用于定义报告在其输出中实际包含的内容的逻辑。示例包括 TopMerchantsReport
和 LowestTransactionsReport
。
ReportRunner - 由于报告仅进行数据收集和生成,因此该类负责运行所有报告并发送结果(例如通过电子邮件)。每个Report
都有自己的ReportRunner
。
ReportProfile - 数据库表的对象镜像,其中包含特定报告的用户设置。
报告
可以具有多种可插入行为,例如可消化
和/或可调度
。由于 PHP 没有 mixin,因此最好用装饰器模式来表示。
我的实际问题是,当关联的 Report
用诸如 Schedulable
之类的内容装饰时,这 3 个对象中的每一个都需要修改其行为。例如,ReportRunner
现在只需要收集计划的报告,而 ReportProfile
将受益于 isScheduled()
方法。
我不想强迫用户必须装饰所有 3 个类。这不仅容易出错,而且我还必须为每个行为创建 3 个装饰器(每个类一个)。还有什么其他解决方案?
I have a system that has 3 components:
Report - Contains logic for defining what a report actually contains in its output. Examples include TopMerchantsReport
and LowestTransactionsReport
.
ReportRunner - As the reports only do data gathering and generating, this class is responsible for running all of the reports and dispatching the results (via email, for example). Each Report
has its own ReportRunner
.
ReportProfile - Object mirror of a database table that contains a user's settings for a specific report.
A Report
can have multiple pluggable behaviors, such as being Digestable
and/or being Schedulable
. Since PHP has no mixins, this is best represented by the decorator pattern.
My actual problem is that each of these 3 objects needs its behavior modified when the associated Report
is decorated with something like Schedulable
. For example, the ReportRunner
now needs to only gather scheduled reports, and ReportProfile
would benefit from a isScheduled()
method.
I don't want to force a user to have to decorate all 3 classes. Not only is that error prone, but then I'd have to create 3 decorators for each behavior (one for each class). What other solution is there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您想要一个具体的类,例如报告其他两个组件中的不同行为,您最终必须装饰它们,所以您无法避免这一点。唯一的问题可能是管理这三个组件的创建,以根据选择的行为(例如可消化)进行装饰。这可以使用工厂方法模式来完成,它允许您创建所有这三个组件的适当类型。
If you want to have for a concrete class of e.g. Report different behaviour in other two components, you have to eventually decorate them, so you cannot avoid that. The only problem migth be managing creation of those three components to be decorated according to choosen behaviour e.g. Digestable. This can be done using a factory method pattern, which allows you to create appropriate kind of all those three components.
如果我正确理解你的痛苦,我唯一能想到的就是使用工厂设计。工厂有责任根据其装饰提供与特定报表相对应的 ReportRunner 和 ReportProfile。
因此,每个 ReportRunner 都有一个类,ReportProfile 也有一个类,非常相似。
ReportRunner Factory 应该有一个方法,该方法接受报表的装饰并返回它的 ReportRunner,因此您可以执行以下操作:
在 FactoryReportRunner 类中,您将有一个 getReportRunner(... )
当然,那么每种装饰类型都必须有一个 getDecorationReportRunner,在本例中:getDigestableReportRunner 和 getSchedulableReportRunner 。 ReportProfile 的工厂也是如此。这样,每当您添加新的装饰类型时,您所要做的就是添加相应的 getDecorationReportRunner 以及与 ReportProfile 一起使用的装饰类型。
The only thing I can think of, if I understand your ordeal properly, is to use the Factory Design. It will be the Factory's responsibility to supply the ReportRunner and ReportProfile that corresponds to a particular Report based on its decoration.
So you'd have a class for each ReportRunner and one for ReportProfile, quite similar.
ReportRunner Factory should have a method that takes in the Report's decoration and returns it's ReportRunner so you'd do something like:
In the FactoryReportRunner class you'd have a method of getReportRunner(...)
Of course, then you'd have to have a getDecorationReportRunner for each decoration type, in this case: getDigestableReportRunner and getSchedulableReportRunner. The same would go for the factory for ReportProfile. This way, any time you add a new decoration type, all you have to is add the corresponding getDecorationReportRunner and the one that goes with ReportProfile too.