【问题标题】:How to refactor a "library of functions" class that is tightly coupled with the business objects?如何重构与业务对象紧密耦合的“函数库”类?
【发布时间】:2015-07-16 23:42:34
【问题描述】:

我有一个 Calc 类,我认为它被不正确地放置在我正在使用的代码库中。对于类结构,请参见下面的代码。

目前

  • Spec类充当数据的存储,类似于C struct
  • Calc 类是一个计算函数类库,当这些类需要进行一些计算时,它被实例化为其他类的一部分。 Calc 类还包含Spec 类,因此它可以使用Spec 的变量进行计算。
  • Plot 类是表示图形的业务对象的示例。
  • Controller 类是一个业务对象,代表我的应用程序中的各种控制器,其中进行了一些计算并以文本形式显示在用户页面“视图”中,并且还创建了一个图形,该图形也显示给用户“查看”页面。
class Spec
{
    public $a;
    public $b;
    public $c;
}

class Calc
{
    public $spec;

    function __construct()
    {
        $this->spec = new Spec();
    }

    function calcParameter()
    {
        $this->spec->c = $this->spec->a + $this->spec->b;
    }
}

class Plot
{
    public $calc;

    function __construct()
    {
        $this->calc = new Calc();
    }

    function calcPlot()
    {
        $this->calc->spec->c = $this->calc->spec->a * $this->calc->spec->b;
    }
}


class Controller
{
    public $calc;
    public $plot;

    function __construct()
    {
        $this->calc = new Calc();
        $this->plot = new Plot();
    }

    function doBusinessLogic()
    {

        //calc for local
        $this->calc->spec->a = 5;
        $this->calc->spec->b = 5;
        $this->calc->calcParameter();
        print "total is {$this->calc->spec->c}<br>\n";

        //later this format is used by JS to display computational results
        $plotJSON = json_encode($this->calc); 


        //calc for plot
        $this->plot->calc->spec->a = 7;
        $this->plot->calc->spec->b = 143;
        $this->plot->calcPlot();
        print "total is {$this->plot->calc->spec->c}<br>\n";

        //later this format is used by JS to display a plot
        $plotJSON = json_encode($this->plot); 
        print "
        <div id='plot' style='display:none'>$plotJSON</div>
        <script>
            var plot = JSON.parse(document.getElementById('plot').innerHTML);
            document.write('JS says - there are ' + plot.calc.spec.c + ' plot points<br>');
        </script>
        ";
    }  
}

//runs the above
(new Controller())->doBusinessLogic();

JS 是这样使用的:

var plot = JSON.parse(document.getElementById('plot').innerHTML);
document.write('JS says - there are ' + plot.calc.spec.c + ' plot points<br>');

问题

我的印象是 Calc 类没有正确放置(设计不正确),因此,它被注入到各个地方只是为了进行计算。我在想Calc 应该是一个没有参数的类,Spec 不应该是Calc 的一部分。而Calc 必须只包含进行计算的函数,Calc 的调用者将提供自己的数据并接收结果。因此Calc 将成为一个静态函数库,供其他人使用。但这是最好的方法吗?

如何重构它以最小化耦合?请记住,要么保留 JSON 格式,要么注意代码中的任何更改都可能需要更改 JS 代码。

在我深入重构之前,我现在的设计可以工作。有没有必要重构?只是检查。

【问题讨论】:

  • 绘图的 calcParameter 看起来不正确。它指的是 this->spec 但它没有规范,它有一个计算...这是代码中的错误吗?
  • 谢谢,已修复(绘图功能无法访问)
  • CalcSpec 具有相同的功能 ryt?
  • 什么是'ryt'? Spec 没有函数,但 Calc 和 Plot 可能有不同的函数。要改变它..

标签: php oop refactoring decoupling


【解决方案1】:

好的,根据我目前看到的情况,Calc 类根本不应该存在。 calcParameter 方法应该是 Spec 类的成员。

PlotcalcPlot 方法也应该是 Spec 类的成员(它完全处理当前编写的 Spec 字段。)您仍然可能希望保留 Plot,尽管它可以做其他有趣的事情到它的Spec 对象。

像这样:

class Spec {
    public $a;
    public $b;
    public $c;

    function calcParameter() {
        $this->c = $this->a + $this->b;
    }

    function calcPlot() {
        $this->c = $this->a * $this->b;
    }
}

class Plot {
    public $spec;

    function __construct() {
        $this->spec = new Spec();
    }

    function calcPlot() {
        $this->spec->calcPlot()
    }
}


class Controller {
    public $spec;
    public $plot;

    function __construct() {
        $this->spec = new Spec();
        $this->plot = new Plot();
    }

    function doBusinessLogic() {
        //spec for local
        $this->spec->a = 5;
        $this->spec->b = 5;
        $this->spec->calcParameter();
        print "total is {$this->spec->c}<br>\n";

        //later this format is used by JS to display computational results
        $plotJSON = json_encode($this->spec); 

        //spec for plot
        $this->plot->spec->a = 7;
        $this->plot->spec->b = 143;
        $this->plot->calcPlot();
        print "total is {$this->plot->spec->c}<br>\n";

        //later this format is used by JS to display a plot
        $plotJSON = json_encode($this->plot); 
        print "
        <div id='plot' style='display:none'>$plotJSON</div>
        <script>
            var plot = JSON.parse(document.getElementById('plot').innerHTML);
            document.write('JS says - there are ' + plot.spec.c + ' plot points<br>');
        </script>
        ";
    }  
}

//runs the above
(new Controller())->doBusinessLogic();

【讨论】:

  • 作为一般规则...如果您有一个只有一个字段的类,并且该类不限制其字段的可能值,那么该类不应该存在。
  • 谢谢。 “限制其字段的值”是什么意思?
  • 所以,总的来说,我认为这是将函数从Calc 移到各自的类中,最终摆脱Calc。我认为Spec 绝对可以使用一些对其数据进行操作的函数,并且还可以重命名以更好地表示一个对象(因为它在重构工作中变得更加清晰)。例如,在我的完整代码库中,Spec 可以代表产品或电机,并且对于每个特定的产品线都可能不同。我不是 100% 确定 Plot-anything 需要在 Spec 中。 Plot 是一个对图数据进行存储和操作的实体,大概可以解耦。
  • 例如,如果类确保其字段始终大于 0,或者该字段的类无法确保的其他不变量。
猜你喜欢
  • 1970-01-01
  • 2011-05-24
  • 2012-05-14
  • 2018-11-19
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-03
  • 2010-12-04
相关资源
最近更新 更多