0

我有一堆数据库报表需要实现,未来还会更多,所以对构建可扩展代码和避免重复的逻辑和代码特别感兴趣。我正在用 PHP 实现,但问题更笼统。除了 PHP 之外,请随意发布 Java、C++、C# 等的示例。

我面临的问题是报告的不同之处在于我无法轻松组合所有代码来构建 SQL,甚至更困难的是构建 HTML 输出。例如,一个报告包含一列长文本消息,需要 CSS 样式和启用 Javascript 以使鼠标悬停显示整个消息,而其他报告包含将值转换为百分比的列,或有条件地显示为“更少超过 1%”并累积到“其他”类别。

所以我开始使用策略模式。我的班级模型的一个非常简单的草图可以在这里看到:http: //static.inky.ws/image/4044/ClassDiagram.png

我有一个抽象报告,以及每种报告类型的具体实现。报告有几个属性引用封装的功能(通过接口的具体实现),用于不同的 SQL 构建器和每个报告的输出数据格式。但这开始看起来每个报告的课程太多了。还有另一种更好的方法来解决这个问题吗?

实现上述模型的代码草图:

<?php
abstract class Report {
   private $sqlBuilder = null;
   private $dataFormatter = null;
}

class ReportOne extends Report {
   public function __constructor() {
       $this->sqlBuilder = new ReportOneSqlBuilder();
       $this->dataFormatter = new ReportOneDataFormatter();
}
class ReportTwo extends Report {
   // similar to ReportOne
}

interface SqlBuilder {
}
class ReportOneSqlBuilder implements SqlBuilder {
}
class ReportTwoSqlBuilder implements SqlBuilder {
}

interface DataFormatter {
}
class ReportOneDataFormatter {
}
class ReportTwoDataFormatter {
}
?>

这个想法是保留抽象类中的所有公共代码,以及各种具体子类中的具体差异。写这篇文章时我突然想到我还需要用于 SQL 和数据格式化的抽象类,因为接口不能真正携带任何实现细节。

4

1 回答 1

1

有时最好将两个相似但有重要区别的东西完全分开,即使这违反了 DRY(不要重复自己)原则。

事实上,这是有充分理由的。重要的是,如果您尝试重用代码的某些部分,并且稍后您需要修改仅影响其中一个报告的内容,那么无论如何您都必须破坏该通用代码。

设计模式很可爱,当然也有它们的用途,但是,在某些情况下,最好使用可能会部分重复的不同逻辑,并使代码尽可能简单。比 DRY 更重要的是代码的可读性,如果你为了一个真正不需要复杂的功能而复杂化你的代码,你会损害你的可读性而几乎没有收获。

如果你真的认为这两个报告有很强的相似性并且值得你的应用程序复杂化,或者如果你这样做是为了练习你的设计模式实现技能,那就去吧。如果您只是想高效地完成工作并让您的应用程序在以后易于修改,只需保持简单并使用两种不同的逻辑。

于 2013-06-14T23:37:40.923 回答