//-------------------------------- OORULE.TXT --------------------------------- FEW TIPS on OBJECT ORIENTED DESIGN && PROGRAMMING in C++ //----------------------------------------------------------------------------- Prepared for: UNIX-C/C++ S.I.G. Orange Coast PC User Group (OCIPUG) P.O. Box 6100-211 Costa Mesa Ca 92628 by: Patrick R. Nicolas NETWORK INTEGRATED SERVICES, Inc. Date: Dec 12th, 1989 Original file: OOP_RULE.TXT /Members B.B.S./ OCIPUG //----------------------------------------------------------------------------- TIP1: Static classification: Classes should be categorized as Container, Node, Parents, Friend, Child, Reference,... in the early stage of the Design phase, because such 'static' classification is independant of the states. TIP2: Object Property definition When an Obj. has a property you cannot define, this property may be well a new object_class. TIP3: Privacy of the reciever Never let an object tell another how to handle its job (respond to the sender's message) TIP4: Exceptions Exceptions and special cases have to be ignored in the early design phase and postponed until the implementation. TIP5: Global structures. Avoid global structures, data or functions. TIP6: Optimized number of attributes to describe statically an object. The number of attributes of an object has to be restricted to the minimal set required to define all its possible state ( Object-Attribute-Value) TIP7: Optimized number of methods to describe dynamically an object. The number of methods of an object has to be restricted to the minimal set required to generate all its possible action (== response to all possible messages). Methods, defined to manipulate attributes, may be designed at a lower level and at a later stage in the design phase. TIP8: Reusability: System objects are always reusable. Application objects may not be reusable. TIP9: Class definition. A class definition must be flexible enough to handle all possible states of its instances even those defined at run-time. The logic or rules encapsulated in the class should provide these instances with such a flexibility. TIP10:Common Attributes: Creating attributes which are shared between objects (static member of a class in C++) improve the class hierarchy cohesion, reduce the granularity of the overall code as well as the time spent for testing 'special case of behavior'. TIP11:Optimized class overhead If you have to increase the overhead of a class, chances you need to to create a child class. TIP12:Scope of a class Object Oriented Design prevents the user from dealing with all data at once, but only the ones relevant to the object you are currently manipu- lating. Logical paths and global dataflow will be reduced.(:: in C++) TIP13:Dynamic Composition Plug-in composition provides programmers with powerful late-binding capabilities. It's also an open invitation to the 'end-user fantasy !!' (Rigourous testing is a must). TIP14:Object Domain boundaries. Run-time constructs require a good knowledge of the application domain and its boundaries. TIP15:Inheritance If the purpose of inheritance is to encapsulate the different behaviors of the instances, only methods (public member functions in C++) may be added. TIP16:Dynamic Reference Flow The 'reference flow' is determine at run time (plug-in composition). making an E/R representation fairly inadequate. TIP17:Prototyping Prototyping in C++ means also stopping at a right hierarchy level of specialization, test.Specialization may resume at a later stage if neccessary. TIP18:V && V Syntactical verification is the compiler's responsability. Semantic verification is the developper's responsability TIP19:Limitation of Dev. tools Development tools provide some guarantees regarding the code behavior for the static-bound variables, not for late-bound variables. TIP20:Relationships between objects. Static relationship between objects in C++ may described by class Derivation, Composition, Abstraction or Factorization. Dynamic relationship between objects in C++ are better described by class Plug-in composition or Circular references. TIP21:References. Objects refer to other objects, not contain them. Classes may contain objects. These links are established by reference not by value. TIP22:Messages and Answers Messages are requests not guaranties of actions (answer). TIP23:Functions vs. Messages Function calls twiddle bits, message twiddle data structures( a good one from M. Mullin) In case of error, the receiver may return a NIL object or the reference to itself (*this in C++). TIP24:Correct of arguments of a function. If the length of a function implementing a message (Objptr->func()), is longer than the 80 col. display screen,... it's probably too long. Large public functions are to be decomposed (calls) into several smaller private functions, each one of them manipulating a specific data. TIP25:Purpose of message mechanism The message mechanism supports query, retrieval and manipulation of data members. TIP26:Granularity and Message decomposition In order to improve a class instantiation (granularity and number of arguments passed in the constructor), the constructor may relay messages to several private methods which may depend on the state of the instance. (also TIP24) TIP27:External Events Some messages may be delayed by external events. TIP28:Scope of classes within an hierarchy. Working down the hierarchy tree, you must check if the scope of the children classes is smaller then its parent. TIP29:Domain extension for sender and reciever A more 'globally known' object is responsible for sending an message to a less 'known' object. Not the other way round. TIP30:Containers Container object must supply logical routines (demons in AI) to verify the correct manipulation of contained (or node) objects. Add, retrieve, delete,... TIP31:Delegation You should always consider delegation of the responsability of one object to more specialized objects that are referenced by that object or to the users of that specialized object. TIP32:Interactive Prototyping premier question: Q: Am I changing something bigger than what I am dealing now? A: YES the existing hierarchy is robust enough for an extra level of specialization A: NO redesign from the root. TIP33:Composite objects When an object contained references to other objects, it can safely delegate its responabilities to these 'sub-objects'. But, it's still in charge of relaying and managing messages to these 'sub-object'. TIP34:Inheritance vs. Delegation Inheritance is a static relationship (defined at compile time). Delegation(reference to another object) is both a static and a dynamic relation. TIP35:Copy-Initialization and Shallow-Deep Copy To make sure the reciever cannot alter the original copy (refered object), you must explicitly copy the reference object to the new memory allocation A copy initializer converts calls by reference into calls by value. TIP36:Retroactive design of a base class If a base class (or the root) does something that a derived one must undo, the base class do too much. TIP37:Binding. 'Binding' means binding a virtual member function to an object. TIP38:Object Definition. Object definition is the process of stating what you know, not an attempt to figure out what you don't know. TIP39:Private vs. public Methods that return data are usually public. Methods that modify data are usually private (safety net). TIP40:Abstraction pitfall It's easier to specialize a general class than to abstract a specialized class. TIP41:Aggregation: Methods operating on the same data abstraction have to be grouped together. TIP42:Active entities Oobjects which operate on the data flow have to be considered in the Analysis phase, the others may be built in the Design phase. TIP43:Bijectivity An instance of an object has exactly one value for each attribute. TIP44:Non-fragmentation of attributes When an object has several member variables (attributes), each attributes must represent a characteristic of the entire object, not part of it. TIP45:Overlaid attributes Each attribute must represent (or model) a characteristic of the instance not a characteristic of another attribute or member object. TIP46 Multiple Inheritance Multiple inheritance becomes a valuable alternative when the analysis requires that an 'application' object to interact with 'system' objects like Window, Files, Mouse, ... TIP47:Profiling C++ code: Hidden calls Try to reduce hidden calls to constructors and destructors. TIP48:Profiling C++ code: Memory allocation from the heap Use the standard library memory allocation routines (malloc().,...) for creating built-in data type instead the shells new and delete which are 20% slower. TIP49:Profiling C++ code: Virtual Tables Double check that all overloaded functions cannot be declared virtual, and the virtual ones cannot be overloaded before testing. TIP50:Profiling C++ code Dynamic constructs Run-time constructs are very handy for C- programmers coming to C++. Their abuse will slow your code between 5 to 25%. Readings, references and acknowledgements: "Object Oriented Program Design with Example in C++" M. Mullin Addison Wesley 1989 "Object Oriented Systems Design: Modeling the World in Data" S. Shlaer, S Mellor Yourdon Press 1988 "An Object-Oriented Requirements Specification Method" S. Bailin Communication of the ACM May 1989 "Thoughts on Object Oriented Design" M. Vilot C++ at WORK'89 1989 "The Object Oriented Structured Design for Software Design representation" A. Wassermann, P Pircher, R. Muller IEEE computer March 1990 //--------------Note to CompuServe readers --------------------------------- These "Hints and Tips' are to be considered a starting point for a broad and constructive discussion. They were compiled for a 'non-profit and sharing' purpose and should not be regarded as formal guidelines. They also were intended for an audience of C-programmers and does not fully encompass the lastest C++ Ve2.0 updates, specially for those who do think that language specification may influences design. My ideas regarding the benefits of Object Oriented Design methodology have slighlty matured since the original presentation. Patrick E.O.F.