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.