|
Prev: too much OOP ?
Next: Call for Papers Reminder (extended): International MultiConference of Engineers and Computer Scientists IMECS 2008
From: H. S. Lahman on 28 Dec 2007 23:05 Responding to Veloz... > What's the current consensus regarding how you should code the methods > in a class with repsect to the class's fields? > > That is, in class X, if you have private field named privateA, but > also have a public property to wrap it up, named publicA, should > methods in class X be accessing privateA or publicA? > > I have the sense that some people are suggesting that class code > should access its own fields via publicA. I don't think there is a simple answer. In addition to Daniel T.'s point about invariants, another problem is that the public responsibility can be a quite different thing than <part of> its private implementation. That is, the public responsibility may be more complex than a particular aspect of its implementation that happens to be captured in a private property. A classic example would be: [Employee] - salary + getSalary() In the original application context a salary was the base salary without overhead burden. In this case it makes no difference whether one accesses the private salary attribute or the public getter. Now suppose somebody comes along and decides that one must distinguish between burdened salary and base salary. So we now need: [Employee] - salary - burdenRate + getSalary() + getBurdenedSalary() where the goal is to avoid breaking existing clients. But what is the internal definition of 'salary'? case 1: salary is the base salary. getSalary = salary getBurdenedSalary = salary * (1.0 + burdenRate); case 2: salary is the burdened salary. getSalary = salary / (1.0 + burdenRate); getBurdenedSalary = salary; The point is that one of the "getters" in each case is not the same as the attribute 'salary' and which one is different depends upon private implementation context. More to the point, getSalary returns the base salary in both cases but that is not what 'salary' is in the second case. One can argue that we are playing games with the semantics of 'salary'. IOW, in case 1 the Employee method would not access 'salary' if it needed burdened salary. But all that means is that one can't blindly trust naming conventions. The real issue is that in both cases one getter was trivial but the other was not. When the getter is nontrivial, one needs to decide what one really needs to access. Bottom line: for consistency always seek to use the public responsibility because that will tend to be the most stable -- unless the required access depends on the /implementation/ of the object. For example, in the simple example above, any Employee method that needs a base salary value should invoke the public getSalary above. Then that method will not break if one decides to modify the semantics of 'salary' to support unburdened salaries with the case 2 implementation. It is also consistent with the notion that object responsibilities are supposed to be logically indivisible at the object's level of abstraction so one really shouldn't need to access anything else. OTOH, Daniel T.'s example is clearly about an exception that depends upon the way the object is implemented and what the method needs to do. One can also construct more complex examples where, say, there are private intermediate values that might logically be used in the /implementation/ of some other method. IOW, when the implementation of a method depends upon the private implementation of the object, one wants to use that privacy. Otherwise one uses the defined object responsibility through the object's standard interface. -- There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: Daniel Pitts on 29 Dec 2007 15:52
Veloz wrote: > Hi there > > What's the current consensus regarding how you should code the methods > in a class with repsect to the class's fields? > > That is, in class X, if you have private field named privateA, but > also have a public property to wrap it up, named publicA, should > methods in class X be accessing privateA or publicA? > > I have the sense that some people are suggesting that class code > should access its own fields via publicA. > > Michael Let's make sure I understand you're question, and hopefully answer it as well. Say we want to have a Distance class that describes distances: class Distance { private double meters; // implementation detail public double getMeters() { return meters; } } Now, if I understand, your question becomes "should one implement methods in Distance by using getMeters() or meters?" My answer is that you should use getMeters(), here's why. Suppose you have to calculate the square of the distance: class Distance { private double meters; // implementation detail public double getMeters() { return meters; } public Area squared() { return Area.fromSquareMeters(getMeters() * getMeters()); } } Now, I decide later on, that I don't want to store things in meters, but centimeters: class Distance { private double centimeters; // implementation detail public double getMeters() { return centimeters * 100; } public Area squared() { return Area.fromSquareMeters(getMeters() * getMeters()); } } Now, I only had to change the parts of my class that explicitly uses the private information. To put this in another way, public interface shouldn't change much, where private implementation details might change more frequently. If you use more of the public interface, and less of the private implementation, then changes to that private implementation will affect fewer places. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> |