Skip to content

Latest commit

 

History

History
30 lines (25 loc) · 2 KB

File metadata and controls

30 lines (25 loc) · 2 KB

Back to questions

Solution to 937d: Flawed rectangle

See code at solutions/code/tutorialquestions/question937d

The Rectangle class should enforce an invariant that the value of area must be equal to width*height. The methods setWidth, setHeight and setArea allow this invariant to be broken: clients. (A client of a class A is a class B that uses methods or fields provided by A.) Note that it is possible for A to be a client of B and B a client of A} can arbitrarily change width, height and area using these methods. The clients of Rectangle should not have to worry about its invariants; therefore the clients are likely to change the value of width or height without updating the value of area. This will invalidate the invariant of Rectangle and is likely to cause bugs.

The easiest solution is to simply get rid of the area field from Rectangle, and to make getArea freshly compute a rectangle's area each time it is invoked. This is clearly robust to changes in width and height. This solution is presented in the afterfixingandrefactoring sub-package. The disadvantage of this approach is that it leads to redundant computation if we ask for the area of a rectangle many times without changing its fields in-between. For such a simple method call this almost certainly does not matter, but this may be a concern if this design issue arises in a more complex scenario, where the equivalent of area is a more expensive operation. The solution also requires removing the setArea method, but arguably this method made little sense: given a new area, how should a corresponding width and height be chosen in a meaningful way?

Another possibility is to ensure that the fields cannot be changed, by making Rectangle immutable as discussed in the lectures and demonstrated in the fixedrectangle2 sub-package. Clearly this solution is not applicable if the fields must be changed during a rectangle's lifetime.