简体   繁体   English

如何重构与业务对象紧密结合的“功能库”类?

[英]How to refactor a “library of functions” class that is tightly coupled with the business objects?

I have a Calc class that I think was improperly placed in the codebase I am working with. 我有一个Calc类,我认为该类未正确放置在我正在使用的代码库中。 For the class structure see code below. 有关类结构,请参见下面的代码。

Currently 目前

  • Spec class acts as a storage of data, similar to C struct Spec类充当数据存储,类似于C结构
  • Calc class is a library of computational functions class that is instantiated as part of other classes, whenever those classes need to do some computation. Calc类是计算函数类的库,每当这些类需要进行一些计算时,它们便会作为其他类的一部分实例化。 Calc class also houses Spec class, so that it can do computations using variables of Spec . Calc类还包含Spec类,因此它可以使用Spec变量进行计算。
  • Plot class is an example of a business object representing a graph. Plot类是表示图形的业务对象的示例。
  • Controller class is a business object representing a controller of sorts in my application, where some computations are made and are displayed in text for user page "View", and a graph is also created which is also displayed to the user on the "View" page. Controller类是代表我的应用程序中各种控制器的业务对象,其中进行了一些计算并以文本形式显示在用户页面“ View”中,并且还创建了一个图,该图也显示在用户“ View”上页。
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 is used like so: JS的用法如下:

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

Question

I am under impression that the Calc class was not correctly placed (not designed properly), and as such, it is injected into various places just to do computations. 我对Calc类的放置不正确(设计不当)印象深刻,因此,将其注入到各个地方只是为了进行计算。 I am thinking that Calc should be a class with no parameters and that Spec should not be part of Calc . 我认为Calc应该是没有参数的类,而Spec不应成为Calc一部分。 And that Calc must only contain functions that do computations, and callers of Calc will supply their own data and receive results. 并且Calc必须仅包含执行计算的函数,并且Calc调用者将提供自己的数据并接收结果。 Thereby Calc will become a static library of functions to be used by others. 从而Calc将成为供其他人使用的静态函数库。 But then is this the best way? 但这是最好的方法吗?

How can I refactor this to minimize coupling? 我该如何重构以最大程度地减少耦合? Keeping in mind that JSON format is either to be preserved, or being mindful that any changes in code may require changes to JS code as well. 请记住,要保留JSON格式,或者要注意,代码中的任何更改也可能需要更改JS代码。

Before I go knee-deep refactoring this, the design I have now works . 在我进行深入分析之前,我现在使用的设计已经可以使用 Is there a need to refactor at all? 是否需要重构? Just checking. 只是检查。

Okay, based on what I see so far, the Calc class should not exist at all. 好的,根据目前为止我所看到的,Calc类根本不应该存在。 The calcParameter method should be a member of the Spec class. calcParameter方法应为Spec类的成员。

The calcPlot method of Plot should also be a member of the Spec class (it deals entirely with Spec fields as currently written.) You still might want to keep Plot around though if it does other interesting things to its Spec object. PlotcalcPlot方法也应该是Spec类的成员(它完全处理当前编写的Spec字段。)即使它对Spec对象执行其他有趣的操作,您仍然可能想要保留Plot

Like this: 像这样:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM