managing complexity

advertisement
Managing Complexity
People encounter complex situations all of the time. Most people deal with them
successfully; although that doesn’t mean that it is easy. Some forms of mental illness are
connected with the inability to deal with complex situations.
Understanding, or managing, or creating a complex system certainly can be very
stressful. As IT/IS professionals we constantly encounter complex systems or complex
situations. Because of this the IT/IS field can be very exciting, challenging, and
rewarding but also very stressful. Fortunately there are a few tools that help manage the
complexity and relieve the stress.
The most basic tool is abstraction, the purposeful suppression of detail in order to
emphasize a few fundamental features. Information hiding describes the part of
abstraction in which we intentionally choose to ignore some features so that we can
concentrate on others.
Abstraction is often combined with a division into components. For example, we can
divide an automobile into the engine, the transmission, etc. Components are carefully
chosen so that they encapsulate certain key features and interact with other components
through a simple and fixed interface.
The division into components means that we can divide a large problem into smaller
problems that can then be worked on more or less independently. It is the responsibility
of the developer of a component to provide an implementation that satisfies the
protocols specified by the interface.
A very useful metaphor in developing a complex system is the concept of service
provider. A component provides a service to other components with which it interacts.
We often characterize people by the services they provide. A teacher teaches, a letter
carrier delivers letters, etc. This metaphor allows us to think about a complex system in
the same way we think about a complex system of people.
Another form of division into parts is repetition. With repetition, we have several
components of the same type working together. Repetition therefore allows us to
understand a system by considering it on two levels: as a single component in isolation
and also as a collection of similar components.
Another powerful tool for creating complex systems out of simple parts is composition.
Composition begins with a small set of primitive components and rules for creating new
components out of existing ones. Composition then allows new artifacts to be created
from existing elements. These new artifacts then become available for further use, and
thus complex systems are constructed layer by layer.
Another form of layering is taxonomy (classification or catalog). In OOP this concept is
called inheritance hierarchy. Here the layers are more detailed representatives of a
general category. An example is the set of biological categories. For example Living
Thing Animal Mammal Cat. Each level is a more specialized version of the
previous one. This division simplifies understanding, as knowledge of more general
levels is applicable to more specific categories. When applied to system components, this
technique also simplifies the creation of new components because if a new component
inherits from an existing category, all of the functionality in the older category comes
along for free.
Another tool used in the understanding of complex systems is the concept of multiple
perspectives or views. The idea is that we can consider the same entity in different ways
at different times, using abstraction to bring out certain details one time and to bring out
other details the next time.
Patterns
A very important tool is the pattern. A pattern is a recognized relationship .The
relationship is between components making up a problem and components making up a
possible solution. A pattern is simply a generalized description of a problem and a
possible solution to that problem that has been observed to occur in many places and in
many forms. The pattern describes what the problem is and how the problem can be
addressed and the reasons both for adopting the solution and for considering other
alternatives. A pattern is simply a particularly good solution to a common problem. The
idea is to use the skill and experience of other developers rather than starting from
scratch. In this sense every data structure is a well thought out and well used solution to a
common data management problem.
Note that one must first recognize the pattern of the problem before one can apply the
pattern of the solution. Recognizing patterns requires being familiar with the
development literature and plenty of experience discovering what does and does not
work.
Seeing patterns and using them is a very important step to learning them and becoming
proficient with them. This is what we have done in this class. Spinning your wheels down
blind alleys, although sometimes necessary and useful, usually only encourages bad
design because one is forced in desperation to hack together something that works but not
as well as it should. Much worse it creates the illusion that one is a developer because one
can clabber together a program by force fitting pieces in an ad hoc undisciplined way.
However, not every solution to a problem is equally good and in no way could this
monstrosity of a program be called a system. Learning to build anything means not just
being given the tools and be expected to use them but also being shown and mastering
how to properly use the tools.
We have seen examples of solutions which are recognized by a large development
community as particularly good. One very fundamental pattern is the MVC pattern in
which the three major parts of any program – the business logic (Model), input /intention
(Controller), and output /display (Viewer) are separated. This makes the system easier to
design, code, debug, and maintain. In more complex projects we would continue the
process and separate each of the MVC components as needed into smaller pieces
according to recognized patterns. We have also used several other patterns throughout the
system. We have used the Singleton and Iterator pattern repeatedly. We have also used
such patterns as Reflection, Abstract Parent , Command, Action, Dispatch, Interpret,
Generic, Indexed, and variations of several others.
We have developed (certainly simple of course) systems in a disciplined manner and
choosing as appropriate well recognized design techniques and testing techniques. At no
time did we simply just use the first design that happened to come to mind.
This is an important first step.
Becoming a Master Designer involves an attitude that seeks to identify alternatives
(which means being familiar with many possible solutions) and intelligently choose an
appropriate course of action. Good design involves analysis, knowledge, careful choices,
and the development of insight.
Download