carlAlex
8/10/2016 - 9:47 AM

OO Design Checklist - Stackoverflow

OO Design Checklist - Stackoverflow


 
•Objects do things. (Most important point in the whole of OOP!) Don't think about them as "data holders" - send them a message to do something. What verbs should my class have? The "Responsibility-Driven Design" school of thinking is brilliant for this. (See Object Design: Roles, Responsibilities, and Collaborations, Rebecca Wirfs-Brock and Alan McKean, Addison-Wesley 2003, ISBN 0201379430.)
•For each thing the system must do, come up with a bunch of concrete scenarios describing how the objects talk to each other to get the job done. This means thinking in terms of interaction diagrams and acting out the method calls. - Don't start with a class diagram - that's SQL-thinking not OO-thinking.
•Learn Test-Driven Development. Nobody gets their object model right up front but if you do TDD you're putting in the groundwork to make sure your object model does what it needs to and making it safe to refactor when things change later.
•Only build for the requirements you have now - don't obsess about "re-use" or stuff that will be "useful later". If you only build what you need right now, you're keeping the design space of things you could do later much more open.
•Forget about inheritance when you're modelling objects. It's just one way of implementing common code. When you're modelling objects just pretend you're looking at each object through an interface that describes what it can be asked to do.
•If a method takes loads of parameters or if you need to repeatedly call a bunch of objects to get lots of data, the method might be in the wrong class. The best place for a method is right next to most of the fields it uses in the same class (or superclass ...)
•Read a Design Patterns book for your language. If it's C#, try "Design Patterns in C#" by Steve Metsker. This will teach you a series of tricks you can use to divide work up between objects.
•Don't test an object to see what type it is and then take action based on that type - that's a code smell that the object should probably be doing the work. It's a hint that you should call the object and ask it to do the work. (If only some kinds of objects do the work, you can simply have "do nothing" implementations in some objects... That's legitimate OOP.)
•Putting the methods and data in the right classes makes OO code run faster (and gives virtual machines a chance to optimise better) - it's not just aesthetic or theoretical. The Sharble and Cohen study points this out - see http://portal.acm.org/citation.cfm?doid=159420.155839 (See the graph of metrics on "number of instructions executed per scenario")
 
Can I answer yes to all of these? 
•Do my classes represent the nouns I am concerned with?
•Do my classes provide methods for actions/verbs that it can perform?

Can I answer no to all of these?
•Do I have global state data that could either be put into a singleton or stored in class implementations that work with it?
•Can I remove any public methods on a class and add them to an interface or make them private/protected to better encapsulate the behavior?
•Should I use an interface to separate a behavior away from other interfaces or the implementing class?
•Do I have code that is repeated between related classes that I can move into a base class for better code reuse and abstraction?
•Am I testing for the type of something to decide what action to do? If so can this behavior be included on the base type or interface that the code in question is using to allow more effect use of the abstraction or should the code in question be refactored to use a better base class or interface?
•Am I repeatedly checking some context data to decided what type to instantiate? If so can this be abstracted out into a factory design pattern for better abstraction of logic and code reuse?
•Is a class very large with multiple focuses of functionality? If so can I divide it up into multiple classes, each with their own single purpose?
•Do I have unrelated classes inheriting from the same base class? If so can I divide the base class into better abstractions or can I use composition to gain access to functionality?
•Has my inheritance hierarchy become fearfully deep? If so can I flatten it or separate things via interfaces or splitting functionality?
•I have worried way too much about my inheritance hierarchy?
•When I explain the design to a rubber ducky do I feel stupid about the design or stupid about talking to a duck?