SRP没有违反封装

时间:2012-11-19 23:06:46

标签: language-agnostic encapsulation single-responsibility-principle

我无法将单一责任原则与封装协调一致。似乎在类之间分配责任需要暴露大量数据。例如,考虑一些名为DataPoints的对象。 DataPoints填充了x和y坐标等。我可以创建一个填充DataPoints的Generator类。现在,假设我想绘制这些数据点。显然,这是一个单独的责任,可能来自一个名为DataPointsPlotter的类。但是为了绘制数据,我需要知道内部x和y坐标是什么。只需一个处理两个类,这没问题。 x和y是内部变量,但create()和print()方法都可以访问这些变量。我可以暴露x和y(可能通过getter / setter - ugh)或者我可以将DataPoints结构传递给Plotter类,但它仍然需要进入内部来获取x和y。我可以在我发送x和y的DataPoints类中声明一个Plotter实例。但这仍然是曝光。

我在这个例子中如何使用绘图仪绘制x和y而不违反封装?

1 个答案:

答案 0 :(得分:3)

class DataPoint {

    protected x, y

    public function construct(theX, theY) {
        x = theX
        y = theY
    }

    public function getX {
        return x
    }

    public function getY {
        return y
    }

}

这封装了以已知格式表示数据点的责任。假设还有一些健全性检查确认xy具有良好的值,这是一个在此处封装的责任。

class Plotter {

    public function plot(DataPoint dp) {
        x = dp.getX
        y = dp.getY

        ... plot ...
    }

}

绘图仪接受DataPoint的实例并绘制它。这也是一个责任:绘制DataPoint的实例。 Plotter不需要DataPoint了解Plotter内部结构。它只需要一个定义且稳定的界面DataPoint如何从getX获取必要的数据。哪些是获取者getYDataPoint。只要接口保持不变,您就可以根据需要更改DataPoint的内部结构。 DataPoint的责任是保持数据点并以定义的方式让其他代码访问其数据。如果没有办法从{{1}}中获取数据,那么它的存在将毫无用处。

所以不,SRP和封装相互之间并不矛盾。你只需要明确责任到底是什么。