Embedded Object Oriented Design Tips

来源:百度文库 编辑:神马文学网 时间:2024/04/28 14:22:28
Object Oriented Design Tips
Here is an assortment of tips to keep in mind when using object orienteddesign in embedded systems:
Stay close to problem domain
Object discovery vs. object invention
Pick nouns or noun phrases as classes
Method names should contain a verb
Prefix adjectives when naming inheriting classes
Do not add suffixes to class names
Avoid one-to-one mapping from structured design
Replace multiple get-set methods with operations
Model classes that handle messages as state machines
Use const whenever possible
Restrict header file level dependency
Don't reinvent the wheel; use STL
Design is a process of modeling the problem domain into programming constructs.Object oriented design simplifies the design process by maintaining a one-to-onemapping between problem domain objects and software objects. To succeed in objectoriented design, keep your design as close as possible to problem domain objects.The interactions between your objects should mirror interactions betweencorresponding problem domain objects.
Problem domain objects is basically an object that can be found in theproblem itself. For example, when developing a text editor real-world objectswould be, Paragraph, Sentence, Word, ScrollBar, TextSelection etc. Whiledeveloping a call processing module, the objects might be Call, Ringer,ToneDetector, Subscriber etc.
The first step in object oriented analysis is to discover the objects that can bedirectly identified from the problem itself. In many cases objects can beidentified from the requirements. Objects discovered from the problemstatement are extremely important. These objects will be the core objects in thedesign.
The next stage in object design is to "invent" objects. Theseobjects are needed to "glue" together objects that have beenidentified during object discovery. Invented objects generally do not correspondto anything tangible in the problem domain. They are inventions of programmers to simplifydesign.
Consider the following statement from the requirements:
The circuit controller shall support digitaland analog circuits. The circuit controller shall contain 32 DSPs.When the circuit controller receives a request to setup a circuit, it shallallocate 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 themanagerdesign pattern:
DSPManager: Manages the 32 DSPs on the circuit controller
CircuitManager: Manages the digital and analog circuits
We invent a Circuit base class for DigitalCircuitand AnalogCircuit by filtering properties that arecommon to DigitalCircuit and AnalogCircuitobjects.
The relationship between the classes also follows from the requirement. CircuitControllerclass contains DSPManager and CircuitManagerclasses. The CircuitManager contains an array of Circuitclass pointers. The DSPManager contains an array ofDSP objects.
Identifying objects is easy, they should always be nouns. As we have seen inthe Circuit Controller example, we picked up nouns from the requirements asclasses in our design. Even when you invent classes, keep in mind that theyshould be nouns. Abstract concepts don't qualify as object names.
Naming the objects is extremely important in object oriented design. Chancesare that if you name your object correctly, the designers and maintainers willassign it functionality that fits its name. Also note that, if you have troublenaming an object, you probably have the wrong object. At this point go back andlook at the problem again and see if you can pick an alternative object.
In any language, actions performed by nouns are specified using verbs. Whyshould object oriented programming be any different? Thus make sure all theoperation methods should contain verbs.
Thus the Circuit class we discussed earlierwould 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 tooperations on Circuit.
This one is fairly obvious. When a class inherits from a base class, the namefor the new class can be determined just by prefixing it with the appropriateadjective. For example, classes inheriting from Circuitare called AnalogCircuit and DigitalCircuit.Following this convention leads to class names that convey information about theclasses inheritance.
Do not add suffixes like Descriptor, ControlBlock, Agent to the class names. Forexample,  DigitalCircuit should not becalled DigitalCircuitDescriptor or DigitalCircuitControlBlock. Such names arelonger and do not convey the exact role of the class.
Many developers moving from structured design just continue with structureddesign in C++. The classes developed correspond more to similar structuredconstructs they have used in the past. Similarity between C and C++ confusesdevelopers. Make no mistake, object oriented programming is a completelydifferent technique. The emphasis here is to keep the design process simple byminimizing the difference between the problem domain and software domain.
Developers complain that after moving to object oriented programming, theyspend considerable time writing mindless get and set methods. Here is a simpletip on reducing the get and set methods. Consider the code below:
Circuit Status (Multiple Get-Set)
void CircuitManager::GetStatus(const CircuitStatusMsg *pMsg) const { for (int i= 0; i < MAX_CIRCUITS; i++) { pMsg->circuitInfo[i].circuitId = m_pCircuit[i]->GetId(); pMsg->circuitInfo[i].circuitType = m_pCircuit[i]->GetType(); pMsg->circuitInfo[i].circuitStatus = m_pCircuit[i]->GetStatus(); pMsg->circuitInfo[i].circuitCallId = m_pCircuit[i]->GetCallId(); pMsg->circuitInfo[i].circuitState = m_pCircuit[i]->GetState(); } }
The above code can be replaced by moving the field filling in the message tothe Circuit class. This way you do not need todefine a large number of get operations. Also, any changes in the CircuitInfofield would result only in changes to the Circuitclass. CircuitManager would be transparent as itdoes not look into CircuitInfo.
Circuit Status (Single Operation)
void CircuitManager::GetStatus(const CircuitStatusMsg *pMsg) const { for (int i= 0; i < MAX_CIRCUITS; i++) { m_pCircuit[i]->UpdateStatus(pMsg->circuitInfo[i]); } } void Circuit::UpdateStatus(CircuitInfo &circuitInfo) const { circuitInfo.circuitId = m_id; circuitInfo.circuitType = m_type; circuitInfo.circuitStatus = m_status; circuitInfo.circuitCallId = m_callId; circuitInfo.circuitState = m_state; }
Whenever you encounter a class that has to perform some level of messagehandling, its always better to model it as a state machine. We have discussedthis in the article onhierarchicalstate machines.
C++ provides powerful support for const methods and fields. const should beused 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 atcompile time. So start using const from day one of your project.  If constis not used extensively from the beginning of a project, it will be close toimpossible to add it later.
Complex software requires a careful header filemanagement even when programming in C. When developers move to C++, header filemanagement becomes even more complex and time consuming. Reduce header filedependency by effective use of forward declarations in header files. Sometimesto reduce header file dependency you might have to change member variables fromvalues to pointers. This might also warrant  changing inline functions toout-of-line functions. Every time you use a #include make sure that you have anextremely good reason to do so.
For detailsrefer to theheader file includepatterns article.
The C++ standard template library is extremely powerful. It can savecountless hours of coding and testing of complex containers and queues. Detailscan be found in theSTL designpatterns  andSTL designpatterns II articles.
Related Links
Hierarchical State Machines
Header File Include Patterns
STL Design Patterns
STL Design Patterns II
Object Oriented Tips II
Embedded Object Oriented Design Tips Embedded Object Oriented Design Tips II Liskov Substitution Principle of Object Oriented Design Object Oriented Programming in C 石头札记: CSS Oriented Design Issues in Embedded and Realtime System Design Publish-Subscriber Design Patterns in Embedded Systems STL Design Patterns in Embedded Systems II Object-Oriented Programming with JavaScript, Part II: Methods 面向对象分析方法(Object-Oriented Analysis,OOA) [object] RTPEG-32 - Portable Embedded GUI for Embedded... Windows Embedded 简介 object - HTML元素 什么是object指向? 什么是object指向? [object]北京故宫博物院 HTML 标签 [Bernstein09] 10.5. Service-Oriented Architecture Interviewing Tips Resume Tips 生活tips 20 tips 美美TIPS