INTRODUCTION
|
Entity/Skill/Reliance: Applying Functional Decomposition Safely to Object-Oriented Designby Avner Ben. This article originally appeared in the October 1998 issue of JOOP, web-published by permission of SIGS Publications. Some figures have been updated - last update - 14 Dec 2003.
|
|
This article presents a language for the specification of the functional-decomposition aspect of object-oriented system design, and some of the methods behind it. The notation of skill-driven design replaces the traditional extended hierarchy of procedure execution with an extended hierarchy of skills, distributed among participant entities. The language may be used to study and eventually specify low-level algorithmic problems as "timeless processes," as well as the high-level functionality of complete architectures.
|
BackgroundSoftware design involves a number of disciplines, most notably, data modeling and functional decomposition. As to the data model, I have not found it to pose much of a problem. The entity/relationship model even through its derivative, the UML class diagram is a fine language that is both descriptive and, if used skillfully, generative. However, the state-of-the-art of functional decomposition is less secure. In fact, there are still many software developers around who can hold an entire application in their heads and reach the rest by trial and error, and they can't see why anyone would worry about functional decomposition. Still, there are also the rest of us, mortals, who could benefit from sturdier, more predictable tools. Here is my wish list for a functional-decomposition language:
|
The entity/skill/reliance metaphorTo understand the skill-driven design notation, one has to adopt a view of an object-oriented software system as so many objects waiting to participate. The sentence is left incomplete intentionally. Why are these objects there in the first place? What are they waiting for? Enter object-oriented design. Object-oriented design becomes the art of distributing responsibility for executing a job among its participants. (Precisely, among its participant types. Software designers, as opposed to programmers, are seldom preoccupied with instances). Every piece of functionality requires a participant entity. Therefore, in case the job being decomposed requires management, the management stuff as well as the job itself joins the participant list. The sole purpose of the main program is to activate one, two or a handful of major participants and leave the job to them. On the contrary, old-fashioned procedural design slices the job to small procedures, to be coordinated through a single assignment-execution tree. It recognizes only one participant entity the processor. The rest is storage at its disposal. Object-oriented design is, at the same time, the paradigm opposite of procedural design and its historical successor, through dialectical development. Both involve functional decomposition. Object oriented design introduces an additional dimension the participant entities. Incidentally, it also results in shorter procedures, and many more of these. It also gives birth to an additional body of structure and procedure whose purpose is to sustain the object-oriented emphasis. The more profound and professional the object-orientation of the design, the larger and richer this extra level of functionality (e.g., as the result of applying design patterns).2
|
Skill-driven design termsThe terms that we are going to use are entity, skill and reliance. An entity is anything on which information is managed and with which we do something. It is an axiomatic term. Some entities represent the problem domain, and some are introduced by the designer to help in organizing the solution model. An entity is directly mapped to a class in an object-oriented language like C++, either a concrete class or an interface. The latter may be implemented as an abstract base class, non-abstract base class, a protocol for use by a generic function, or an interface definition in languages that support that. The definition of a skill follows. Reliance is a binary-directed relationship between either two entities, or the outside world and an entity. A reliance path is a sub-tree of reliance relationships emanating from one entity. A reliance graph is a map of reliance paths in either part or all of a system. It is used to obtain a comprehensive view of a functional-decomposition scene. Skill: Someone's ability to contribute, directly or indirectly, by action or inaction, towards the achievement of a business objective. We need to define skills for two purposes:
Synonyms for "skill": responsibility and capability. Normally, though not necessarily, a skill involves performing one or more procedures. In object-oriented programming, the functionality of a class is completely described by a list of skills, and each of these is completely implemented (if needed) by a number of member functions. Skill title is a concise role definition. It is made timeless by avoiding the verb over noun construct as in procedural design,1 e.g., "income-tax computation," "code generation," and "message dispatch." It may have additional descriptive features such as the process, descriptive text, intent, preconditions, and postconditions. A dependency between skills reliance path is created when one skill relies upon another. The ability to deliver, represented by the source skill, relies upon the ability to deliver, represented by the target skill. Reliance involves management, rather than mere forwarding. The officer in charge of the source skill is also in charge of coordinating (or even executing) the process involved with the target skill, e.g., the skill of a data file for retrieving records relies upon the skill of its character stream for reading characters, and the skill of its data-record buffer for parsing data. We have here two reliance paths. The file takes the responsibility for retrieving records, but does not do the job. It relies upon other participants (which happen in this case to be under its direct command) to take care of the details. The participants do not know of each other. Where each skill is implemented by a discrete function, the reliance path often implies simple control flow. Therefore, a reliance graph may be used as shorthand for procedural design (i.e., to replace straightforward tools as pseudocode, flowchart, structure chart, and sequence diagram). To prevent confusion with traditional analysis and design methods, we must stress that a reliance path does not necessarily imply data flow, as used in structured analysis.1 In OOD, data often flows from source to target with neither source nor target being aware of the complete process; e.g., the skill for interpretation needs symbols, which the skill for reading produces, but it is not in the interpreter's power to operate the reader. The notifier sequences both operations as part of its dispatch skill and handles parameter passing. Interpretation may expect characters, but it does not rely upon reading. Management entities are an important element in object-oriented design, i.e., entities whose functionality may be completely described in terms of moving data from source to target, with the added value of coordination, sequencing, dispatch, etc. From here, one may view the data model in functional terms (coordination) as well as structural terms (composition). A skill list is a vertical list of skill titles. It describes the functional decomposition of one major skill, subsystem or system, in nonprocedural terms. The list represents all the minor skills that the major skill relies on, on more than one level. Each skill title may optionally be followed by a short process descriptor or another commentary text. Skill lists are often sorted by the entities in charge of individual skills. In this case, the skills are indented under the respective entities. A reliance graph is the collection of reliance paths in a skill list. It is presented by either indenting the list to reflect the dependencies or by a graph at list's margin. The notation of the latter follows&ldots;
(Figure one is obsolete)
|
Reliance graph notation:
|
Minispec example
Try to look at the skill list this way: Cover the graph at the left side and study the skills and their distribution between entities. This is the stuff. In addition, you can see the positions each staff member is trained to assume during the operation its skills. Now, cover the text and look at the graph. This is a piece of the logic of the system. This may be a good design. Does it suggest order? Does it suggest internal beauty? This may be a suspicious design. Does it look convoluted? Does it spell danger? In short, can such a system work? Walk though the chart: The list involves two major skills, left unsynchronized: obtaining valid input, courtesy of the Notifier, and direction-change sensitivity, under the responsibility of Snakes. Obtaining valid input relies on Symbol distribution (also by Notifier) and Symbol reading, courtesy of the Keyboard. Symbol distribution involves iteration on Symbol interpretation, courtesy of the Command channel array. Symbol interpretation affects the skill for direction-change sensitivity indirectly, by setting common data. On the other hand, direction-change sensitivity relies on Symbol interpretation to set the data it acts upon, but it does not activate it. Following are a number of examples for using reliance graphs for The "visitor" pattern Figure 3 is a skill-driven rendering of the functional-decomposition model is involved with the typical application of the familiar "visitor" pattern.2 Press to view animated wirechart [Note: Both skill-driven renderings of the visitor functionality feature the present-day semi-imperative skill-naming convention.] |
"MVC"-based graphic editor architecture (typical application at a glance)(Refer to the full version of the MVC case-study). Application-domain statement
|
Solution-related decisionsThe functionality involved is distributed among three distinct entities:
2. The data view represents the ability to display one model instance of a certain type, in a certain presentation style, in a certain environment. It may involve a complex data structure of its own, in addition to the one already managed by the data model. 3. The controller encapsulates an infrastructure for producing the display and obtaining user feedback. Most of the communication with it occurs through controls (or "widgets") visible entities that obtain user input for a specific view, e.g., menus, pushbuttons, scrollbars, etc.
|
"STL"-based generic algorithm (typical use of copy algorithm)Application-domain statement
|
Major design decisions4
Let us look at the aesthetics of the container/iterator/algorithm architecture. Its signature is an elegant, simple, and ordered graphic pattern, consisting of three interleaved forks.
|
CONCLUSIONIn software design, skill lists may be used to study the dependencies among subsystems. For this end, one must be able to express subsystems as skills of the system, each relying on a handful of major skills. In analysis, skill lists may be used to capture requirements. In principle, the reliance graph and skill-list notation may be adopted to any system that involves dependencies that are essentially hierarchical (i.e., involve fan out) with occasional cases of fanning in. It will break when asked to display a true network, such as an entity/relationship model. This limitation of the skill-driven model is an explicit design decision, used to make it a generative language for applications that may benefit from such treatment.
|
References
|