We're working on a BugTracking system and are still in the learning process.
A BugReport has a title, description, (...) and also a tag. A tag represents the progess of the BugReport, e.g.
- New : Freshly created BugReport
- Under Review : A fix has been made and is under review.
- Duplicate : The BugReport is a duplicate of another BugReport (i.e. it's about the same bug)
In the latter case, only one BugReport should be marked as a duplicate and it should store the BugReport of which it is a duplicate.
There's a use case where a BugReport should be able to be inspected : "The system shows a detailed overview of the selected bug report (...)"
Among peers, there's a discussion about which design is best.
Consider following two designs. Only relevant parts of the system is shown. The UI isn't necessarily part of the system.
Design 1
Pros:
In this design, the user receives an instance of IBugReport interface in which relevant inspectors are defined (getTitle(), getDescription(), ...). So, the user is able to retrieve only the information he requires.
Cons:
This design implies that every business object will need an interface that defines methods that may be used by the user. Also, when getDuplicate() is called on a BugTag, the user may retrieve a null from it if the BugTag is not a Duplicate. If, in the future, e.g. Under Review is required to have a field (e.g. a User field that indicates who is reviewing the BugReport), additional methods will have to be defined and implemented in all BugTag classes which most of them will return null, similarly to getDuplicate().
The peers who are in favor of this design have similar ideas for other design decisions i.e. when applicable, return an interface of a business object.
Design 2
[NOTE: in BugReport, inspectState() should be named inspectBugReport()]
Pros:
When BugTags gain additional fields, only inspectState() method will have to be changed accordingly. There's no need for interfaces for the business objects. the system does exactly what the use case asks: inspect the BugReport (i.e. return a String representing its representation).
Cons: The user gets a String in which all all information from the BugReport is concentrated. If the user only wanted the title, he will still receive the full BugReport information.
The peers who are in favor of this design have similar ideas for other design decisions i.e. parse the information to a String and expose that to the outside world.
We're a small group of three people in which myself came up with the second design and someone else with the first design. We're heavily discussing about this and we're both firmly standing our ground. The third person tries to evaluate both designs and give pros and cons.
We're trying to apply GRASP principles. Coupling and cohesion are very important principles in our design. Extensibility is important as well as the project undergoes several iterations. Each iteration requires additional functionality. Because of all this, I argue that the second design is much better. It is, for one, much more extensible.
What are additional pros and cons not mentioned above? Are both designs ok or are one/both designs not-done?
This question arose after this.
inspectedState
? Also, interfaces should describe behavior. I don't see a benefit from introducing interfaces that are a one-to-one mapping to concrete classes. Just return the class.IBugTag
. When I'm using it inBugReport
it's nice not to even know that I'm talking to an interface.