Here is a short list of special hints on good objectoriented software design. These emerged from my own software development work, and are here because I did not yet read them in anything I read on OO design:
- Natural class interfaces. Let every class have its “natural” interface, i.e. offering methods and returning data types that conform to the class’ abstraction level and to the type of things this class is intended to represent and to handle. For example, one class might handle the detailed data structures for a binary storage format; it should not at the same time have methods with an interface to store objects into these data structures. That belongs into a class of a higher abstraction level, that will represent a whole file and call this low-level class for the technical details.
- Use abstractionn levels in classes. If you have more then one level of proxying (where proxying is forwarding calls from one class to a similar interface of another one), then something is wrong on your analysis. Because, your classes are too redundant then. If each class has a proper abstraction level and its natural interface, there will be cascades of interfacing: each class realizes its iterface by using classes exactly one abstraction level below. So each class has something to do, but not too much: the code is well understandable, as only and exactly one abstraction level is dissolved.
- Top-down interface analysis. To write well abstracted, readable code esp. in highly technical sections (like complex GUI code), and to heed the “implement by using classes exactly one abstraction level below” principle (see above), it seems necessary to define the interface top-down. Otherwise, many methods of cryptic names and with cryptic, non-intuitively understandable parameters will have to be implemented, as these names and parameters belong to other abstraction levels, brought in “for technical reasons only”, bringing in unnecessary complexity.
- Set or List? When programming in Java, classes Set and List can often be used both in a particular case. But you should use a criterion to decide which to use in what case, as without it you will constantly need to convert between them in methods that use code with both Set and List. Proposal: use List anywhere except where it hurts. This would be a uniform solution.