Object Oriented Design Tips

转载 2006年05月17日 15:34:00


Here is an assortment of tips to keep in mind when using object oriented design in embedded systems:

  1. Stay close to problem domain
  2. Object discovery vs. object invention
  3. Pick nouns or noun phrases as classes
  4. Method names should contain a verb
  5. Prefix adjectives when naming inheriting classes
  6. Do not add suffixes to class names
  7. Avoid one-to-one mapping from structured design
  8. Replace multiple get-set methods with operations
  9. Model classes that handle messages as state machines
  10. Use const whenever possible
  11. Restrict header file level dependency
  12. Don't reinvent the wheel; use STL

Stay close to problem domain

Design is a process of modeling the problem domain into programming constructs. Object oriented design simplifies the design process by maintaining a one-to-one mapping between problem domain objects and software objects. To succeed in object oriented design, keep your design as close as possible to problem domain objects. The interactions between your objects should mirror interactions between corresponding problem domain objects.

Problem domain objects is basically an object that can be found in the problem itself. For example, when developing a text editor real-world objects would be, Paragraph, Sentence, Word, ScrollBar, TextSelection etc. While developing a call processing module, the objects might be Call, Ringer, ToneDetector, Subscriber etc. 

Object discovery vs. object invention

The first step in object oriented analysis is to discover the objects that can be directly identified from the problem itself. In many cases objects can be identified  from the requirements. Objects discovered from the problem statement are extremely important. These objects will be the core objects in the design.

The next stage in object design is to "invent" objects. These objects are needed to "glue" together objects that have been identified during object discovery. Invented objects generally do not correspond to anything tangible in the problem domain. They are inventions of programmers to simplify design.

Consider the following statement from the requirements:

The circuit controller shall support digital and analog circuits. The circuit controller shall contain 32 DSPs. When the circuit controller receives a request to setup a circuit, it shall allocate a DSP to the circuit.

We discover the following objects from the requirement:

  • CircuitController
  • DigitalCircuit
  • AnalogCircuit
  • DSP

We invent the following objects based on our knowledge of the manager design pattern:

  • DSPManager: Manages the 32 DSPs on the circuit controller
  • CircuitManager: Manages the digital and analog circuits

We invent a Circuit base class for DigitalCircuit and AnalogCircuit by filtering properties that are common to DigitalCircuit and AnalogCircuit objects.

The relationship between the classes also follows from the requirement. CircuitController class contains DSPManager and CircuitManager classes. The CircuitManager contains an array of Circuit class pointers. The DSPManager contains an array of DSP objects.

Pick nouns or noun phrases as classes

Identifying objects is easy, they should always be nouns. As we have seen in the Circuit Controller example, we picked up nouns from the requirements as classes in our design. Even when you invent classes, keep in mind that they should be nouns. Abstract concepts don't qualify as object names. 

Naming the objects is extremely important in object oriented design. Chances are that if you name your object correctly, the designers and maintainers will assign it functionality that fits its name. Also note that, if you have trouble naming an object, you probably have the wrong object. At this point go back and look at the problem again and see if you can pick an alternative object.

Method names should contain verbs

In any language, actions performed by nouns are specified using verbs. Why should object oriented programming be any different? Thus make sure all the operation methods should contain verbs.

Thus the Circuit class we discussed earlier would have methods like:

  • Activate
  • Deactivate
  • Block
  • Unblock
  • ChangeStatus

Notice that the methods do not include Circuit in the name (ActivateCircuit, BlockCircuit etc.) as being methods of Circuit its clear that they refer to operations on Circuit.

Prefix adjectives when naming inheriting classes

This one is fairly obvious. When a class inherits from a base class, the name for the new class can be determined just by prefixing it with the appropriate adjective. For example, classes inheriting from Circuit are called AnalogCircuit and DigitalCircuit. Following this convention leads to class names that convey information about the classes inheritance. 

Do not add suffixes to class names

Do not add suffixes like Descriptor, ControlBlock, Agent to the class names. For example,  DigitalCircuit should not be called DigitalCircuitDescriptor or DigitalCircuitControlBlock. Such names are longer and do not convey the exact role of the class.

Avoid one-to-one mapping from structured design

Many developers moving from structured design just continue with structured design in C++. The classes developed correspond more to similar structured constructs they have used in the past. Similarity between C and C++ confuses developers. Make no mistake, object oriented programming is a completely different technique. The emphasis here is to keep the design process simple by minimizing the difference between the problem domain and software domain.

Replace multiple get-set methods with operations

Developers complain that after moving to object oriented programming, they spend considerable time writing mindless get and set methods. Here is a simple tip on reducing the get and set methods. Consider the code below:

Circuit Status (Multiple Get-Set)


The above code can be replaced by moving the field filling in the message to the Circuit class. This way you do not need to define a large number of get operations. Also, any changes in the CircuitInfo field would result only in changes to the Circuit class. CircuitManager would be transparent as it does not look into CircuitInfo.

Circuit Status (Single Operation)


Model classes that handle messages as state machines

Whenever you encounter a class that has to perform some level of message handling, its always better to model it as a state machine. We have discussed this in the article on hierarchical state machines.

Use const whenever possible

C++ provides powerful support for const methods and fields. const should be used in the following cases:

  • Methods that do not change the value of any variable in the class should be declared const methods.
  • If a function is supposed to just read information from a class, pass a const pointer or reference to this function. The called function would be restricted to calling const methods and using the classes fields only on the right side of an expression.

Proper and consistent use of const will help you catch several bugs at compile time. So start using const from day one of your project.  If const is not used extensively from the beginning of a project, it will be close to impossible to add it later.

Restrict header file level dependency

Complex software requires a careful header file management even when programming in C. When developers move to C++, header file management becomes even more complex and time consuming. Reduce header file dependency by effective use of forward declarations in header files. Sometimes to reduce header file dependency you might have to change member variables from values to pointers. This might also warrant  changing inline functions to out-of-line functions. Every time you use a #include make sure that you have an extremely good reason to do so.

For details refer to the header file include patterns article.

Don't reinvent the wheel; use STL

The C++ standard template library is extremely powerful. It can save countless hours of coding and testing of complex containers and queues. Details can be found in the STL design patterns  and STL design patterns II articles. 

Object-Oriented Analysis and Design Using UML 翻译与学习 (十一)

Introducing Architectural Concepts and Diagrams 介绍架构概念和架构图 目标 完成这一模块(章),你可以: 1、区别架构和设计 2、描述阶层,层,...
  • CB44606
  • CB44606
  • 2016年11月27日 20:57
  • 600

Object-Oriented Analysis and Design Using UML 翻译与学习 (六)

Determining the Key Abstractions  确定重要的抽象 目标 完成这个模块,你可以 1、定义一组候选的重要的抽象 2、使用CRC分析来定义重要的抽象 进程阶...
  • CB44606
  • CB44606
  • 2016年10月22日 22:20
  • 290

OOAD(Object-Oriented Analysis and Design)介绍

OOAD方法论的定义:      1) 面向对象是一种系统建模技术;    2) 将系统描述为许多相互作用的有关系对象;    3) 系统中相互作用的对象被组织成类;    4) OO方法论由以...
  • yjptu
  • yjptu
  • 2013年10月10日 20:49
  • 848

Object Oriented Design -- Data and Algorithm Separation (1)


Object Oriented Design Pricinple

What is object oriented design? What is it all about? What are it's benefits? What are it's costs? I...

C++ Chapter 6. Inheritance and Object-Oriented Design

1. Public inheritance means "is-a." Everything that applies to base classes must also apply to deriv...
  • wyc1230
  • wyc1230
  • 2012年04月27日 13:19
  • 468

Object-Oriented Design Heuristics (zz)

Object-Oriented Design Heuristics //z 2012-4-18 10:17:10 AM IS2120@CSDN 第二章 类和对象:面向对象泛型的建材 经验原则...
  • is2120
  • is2120
  • 2012年04月18日 10:15
  • 508

Object-Oriented Analysis and Design Using UML 翻译与学习 (七)

Constructing the Problem Domain Model  构建问题的领域模型 目标 完成这个模块(章节),你可以: 1、定义UML类图中的必要元素 2、使用类图构建领域模...
  • CB44606
  • CB44606
  • 2016年10月27日 00:52
  • 850

Object-Oriented Analysis and Design Using UML 翻译与学习 (M-B)

构建软件解决方案 目标 完成这个模块(章节),你可以: 1、为解决模型定义一个Java技术包层级树 2、识别满足精心设计的领域模型的Java技术代码 进程图 为解决方案定义包结构...
  • CB44606
  • CB44606
  • 2017年04月09日 19:18
  • 155

Object-Oriented Analysis and Design Using UML 翻译与学习 (十五)

回顾架构 目标 完成这个模块(章节),你可以: 1、定义一个框架 2、描述使用框架的优势和劣势 3、定义多种常用的框架 4、你创建你业务领域框架的概念 框架的描述 一个软件框架是一个可重用...
  • CB44606
  • CB44606
  • 2017年03月23日 22:27
  • 126
您举报文章:Object Oriented Design Tips