INTRODUCTION


The Journal of Object-Oriented Programming

Entity/Skill/Reliance: Applying Functional Decomposition Safely to Object-Oriented Design

by 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.

 

Background

Software 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:

  • It must have a reassuring effect. I would like to start my next project with the reassuring feeling that I am just ready, as professionals in other fields do. The team has been through the plan. We know it. We are ready to execute. It need not be a complete plan still, it must have a calming, reassuring effect. Unfortunately, I have found traditional functional-decomposition methods deceiving. The first time you see a structure-chart1 solution (or its present-day successor, the interaction diagram), you may be blinded by the sense of order that it radiates. Then you have your first project and find yourself staring at a blank page. Then you give your first exercise, and you are surprised to find that each student comes out with his or her own solution, and they are all equally valid. Well, some of us, at least, have been through all this.

  • It must be generative. Unfortunately, current functional decomposition tools are descriptive (e.g., structure chart, procedural sequence diagram, collaboration diagram, pseudocode). They allow you to make design decisions at random. They do not participate in the process of design. I expect a generative language of specification to highlight my mistakes and practically pave my way to the solution. A-priori, the product of a generative language also has to be descriptive. Documentation is not an end to itself!
  • It must be strongly related to text. A picture may be worth a thousand words, but I still find myself, occasionally, staring at all those squares and arrows, at a complete loss at grasping the application behind them.
  • It must be timeless. It is commonly agreed that introducing the dimension of time, such as in explicit control structure, in the early design stage, leads to premature design decisions. Can there be such thing as a timeless process functional decomposition without time ordering?
  • It must be aesthetic. The placement of symbols may not be coincidental. I want to get an immediate impression if the system I am dealing with is beautiful or ugly, simple or complicated, centralized or diffused, straightforward or tricky, ordered or chaotic, disciplined or free-form. Good design has character. A good design notation must bring it out!
  • The notation of skill-driven design is an attempt to answer these points, evolved through experience. The decomposed functions are listed on one side, as text. The extended hierarchical structure that is the decomposition is listed in the margin, as a web of wires, coming from source and plugged to target, as in an old-fashioned telephone switchboard. The relationship between text and graphics forces an order on the design. You cannot place the graphics at random. My experience confirms this to be a generative language, but this point may not be demonstrated in the present scope. There are a number of typical examples to demonstrate the aesthetic values.

 

The entity/skill/reliance metaphor

To 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 terms

The 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:

  1. Constructing role definitions.

  2. Understanding processes functionally.

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:

  • A skill of the system, at the disposal of its users. Objects are responsible for doing it (horizontal arc coming from outside, pointing to doing it) (Fig. 1a).

  • Simple reliance construct. The Manager's skill for coordination relies on the skill of some Workers for doing it. The reliance arc hangs from the reliance arc leading to source skill, rather than the skill title. The origin point is marked by a square. The reliance arc drops down, and then turns right to point to the target skill (Fig. 1b).
  • External-control reliance construct. The user of the system is expected to take care of the display. The system's skill for formatting involves only the preparation (Fig. 1c).
  • A "staircase" reliance construct. High-level skill relies on mid-level skill, which relies on low-level skill (Fig. 1d).
  • A "fork" reliance construct. Coordination relies on both simple skill 1 and simple skill 2. The circle at the base is used, to distinguish fork from crossover, on every internal-reliance arc but the last (Fig. 1e).
  • Event-driven reliance construct. Handler is responsible for doing it, relying on Notifier timing it. Reliance type "ev" (of comment status) is for event. The inverted arrowhead states that contrary to expectation the reliance target (dispatch) activates the reliance source (doing it) but assumes no responsibility for the consequences, i.e., it does not rely on it. The dotted external-reliance arc states that the users rely on the skill for doing it, but do not activate it (directly. They rely physically on the notifier's dispatch skill) (Fig. 1f).
  • Asynchronous reliance construct. The skill for Business objective is realized counting on background skill 1 and background skill 2 to perform their function silently. It does not involve synchronizing them. The dotted-reliance arc means "involves but does not activate." The effect of any of them acting "out of sync" is undefined. The skill is defined for descriptive purpose, and is not really assigned to any concrete entity (Fig. 1g).
  • Anonymous polymorphic reliance construct. The set's skill for doing it relies upon the generalized skill promised by the interface common to elements inside, to be fulfilled by the specific version in the specific type of each element. Dotted arc with virtual reliance means "relies on ... but gets ..." The use of stereotype means "don't care for details" (i.e., which derived class). Reliance type "itr" is for iterative, and "v" is for virtual (Fig. 1h).
  • Explicit polymorphic-reliance construct. In the context of the current use case, we know that the skill we practically rely on is doing it specifically. Yet, we order doing it generally, counting on dynamic dispatch. The specific way of doing it can rely on the general way of doing it, because the specialized entity is a base entity (Fig. 1i).

 

Minispec example


Figure 2 is taken from the specification document of a simple video game. The purpose of the chart is to show, at a glance, the distribution of responsibility between the participants. The attached class-diagram minispec shows the setting the static relationships among the participants.

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 Figure 3. Skill-driven rendering of the visitor patternhigh-level specification of the functional aspects of design patterns and full-scale generic applications.

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

Figure 4. Basic data-model involved with an MVC-based graphic editor.A graphic-editing session commences by opening a file and displaying its contents in a formatted, editable form. The user approaches the data indirectly, through operations on the data's displayed counterpart, meaning either browsing the view or manipulating the data behind it. The editor makes the interpretation silently. Editor session ends with closing the file, and saving the updated data. A number of editing sessions may be held at once, in different styles, and even on the same set of data. The effect of editing is synchronized in all views (see Figs. 4 and 5).

 

Solution-related decisions

The functionality involved is distributed among three distinct entities:

Figure 5. Skills required by an MVC-based graphic-editor architecture and their reliance graph.
1. Data model (or "document") a facility for storing data and processing transactions over it. Does not talk to users.

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

Figure 6. Data-model supporting the generic-copy function.The typical algorithm is little more than the repetition of a predefined procedure upon all elements in a given range. Normally, these elements reside in a container, encapsulating the access method to them. Many algorithms involve more then one container, e.g., the copy algorithm extracts elements from one container, and assigns their values to the parallel elements in a second container (see Figs. 6 and 7).

 

Major design decisions4

  • Containers are homogeneous: They contain elements of the same type.

  • Algorithms do not operate on containers: They operate on element ranges. This allows them to handle part of a container or an arbitrary collection of objects that is generated during handling time, process the container in reverse, or insert instead of replace.
  • Figure 7. Skills required by the generic-copy function and their reliance graph.A range is delimited by a pair of iterators.
  • An iterator allows access to elements, one at a time, and progress in the range.
  • The responsibility for terminating the scan is upon the algorithm, not the iterator.
  • A container produces iterator ranges and steps out of the picture. It does not provide navigation services, but indirectly, through iterators.
  • To be capable of copying, the element type supports assignment.

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.

 

CONCLUSION

In 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

  1. DeMarco, T. Structured Analysis and System Specification, Prentice Hall, Englewood Cliffs, NJ, 1978.

  2. Gamma, E. et al. Design Patterns: Elements of Reusable Object-Oriented Software Architecture, Addison-Wesley, Reading, MA, 1995.
  3. UML 1.1. Notation Guide, Rational Software Corporation 1998, www.rational.com.
  4. Stroustrup, B. The C++ Programming Language, 3rd ed., Addison-Wesley, 1997.


Home