class DataPoint {
protected x, y
public function construct(theX, theY) {
x = theX
y = theY
}
public function getX {
return x
}
public function getY {
return y
}
}
This encapsulates the responsibility of representing a datapoint in a known format. Assuming there's also some sanity checking going on to confirm that x
and y
have good values, this is one responsibility which is being encapsulated here.
class Plotter {
public function plot(DataPoint dp) {
x = dp.getX
y = dp.getY
... plot ...
}
}
The plotter accepts an instance of DataPoint
and plots it. That's also one responsibility: plot an instance of DataPoint
. It does not require Plotter
to have any knowledge of the internal structure of DataPoint
. It just requires a defined and stable interface how Plotter
can get the necessary data from DataPoint
. Which are the getters getX
and getY
. You can change the internals of DataPoint
around however you want as long as its interface stays the same. And the responsibility of DataPoint
is to hold a datapoint and give other code access to its data in a defined way. If there was no way to get data out of DataPoint
, its existence would be quite useless.
So no, SRP and encapsulation are not at odds with each other. You just need to be clear about what exactly the responsibility is.