Chapters 6: System Design. System design is transforming the analysis model into a system design model. The design goals of the project are defined and the system decomposed into subsystem (categories). Also, strategies are selected for building the system including the hardware/software platform, access control policy, management strategy, data management, etc. According to the authors, “System design is not algorithmic. Developers have to make trade-offs among many design goals that often conflicts with each other. System design is decomposed into several activities with each addressing a part of the overall problem of decomposition: 1. Identify the design goals: Developers identify and prioritize the qualities of the system that they should optimize. 2. Design the initial subsystem decomposition - decompose the system into smaller parts based upon the use cases and analysis model. 3. Refine the subsystem decomposition to address all of the design goals (dealt with in Chapter 7). An Overview of System Design: Analysis resulted in the following products: 1. A set of nonfunctional requirements and constraints such as maximum response time, OS platform, reliability, etc. 2. A use case model describing the system functionalities from the actors’ point of view. 3. An object model describing the entities manipulated by the system. 4. A sequence diagram for each use case showing the sequence of interactions among the objects participating in each use case. So the analysis model describes the system completely from the actors’ point of view and serves as a communication tool between the developers and the users. This model does not contain information about the internal structure of the system example the hardware configuration or how the system should be realized, which is where system design takes over to produce the following products: 1. Design goals, describing the qualities of the system that developers should optimize. 2. Software architecture describing the system decomposition in terms of subsystem responsibilities, etc. 3. Boundary use cases describing the system startup, shut down exception handling, etc. The design goals are derived from the non-functional requirements which can lead to decisions when trade-offs are considered, e.g. a trade off decision between more speed 1 and less memory, or to use more detailed graphic icons thus slowing loading and use of more memory, etc. System Design Concepts: Subsystems (made up of solution domain classes) are defined according to the operations they provide. It encapsulates a part of the system that has a well defined interface(s) and can be handled by either a single developer or a team of developers. Na example of such a decomposition of the accident management is given on pp 229 along with Figure 6-4. Two properties of subsystems are coupling and coherence. Coupling with regards to how well two subsystems classes can integrate (dependent on each other) and coherence looks at the integration within the subsystem. These are normally known as inter and intra categories integration respectively. The former is done via layering and partitioning – layering pertains to a hierarchy of subsystems (which subsystem provide a higher level of service and which is dependent on such services); and partitioning refers to a peer distribution (which subsystems mutually provide different services for each other). Upon modeling, the idea is to break the system into subsystems and iteratively do this until the entire system is broken into manageable and simpler subsystems. Now we take the subsystems and model them by classes. Also, these models should consist of an application programmer interface (API) that shows the operations, their parameters, types and return values. That is, services that they provide to other subsystems. Another aspect is coupling – coupling should be as loose as possible, yet maintaining a relationship with other subsystems. This is because if changes are required in the future, then such changes will have minimal effects on the other subsystems. If on the other hand, they are closely coupled, changes of one subsystem may affect the other subsystem in a way that may be detrimental to the entire system. Generally sharing data via attributes increases coupling and should be avoided. The best way is to share data via operations (use methods rather than attributes). (Figures 6.6 pp 232, gives an example of low coupling by making an extra class – storage to allow for interaction between the other 3 subsystems and the database subsystem. and 6.7 and 6.8 on pages 233-234 gives a very good example of both coupling between subsystem and cohesion within a single subsystem.) On the other hand, a high coherence is recommended for the classes within a subsystem. We want the objects within a particular subsystem to attain this same high level of coherence found within a class. All of the objects within the subsystem must be “highly related” to each other, else they should not have been inside of that subsystem. Anytime we need a solution to a problem, one of the best way to achieve this is to use the divide and conquer method, especially if it is a complex problem. In fact, in most computer application, this method is encouraged because it breaks the problem into smaller more manageable parts that can be handled easily. Also, this approach would lead 2 to a hierarchical break down – very suitable to the OO paradigm and which leads to Layering. A layer is a grouping of subsystems providing related services, possibly realized using services from another layer. There are two types of architecture that results from this approach – a closed architecture (where a layer can only depend on layers immediately below it) and an open architecture (where a layer can also have access to layers at a deeper level). Example: the OSI (Open System Interconnection) closed architecture model (pages 235237). 1. The Physical layer - is the hardware interface with the network. 2. The DataLink layer – responsible for transmitting data frame using the services from the Physical layer. 3. The Network – transmitting and routing packages within the network. 4. The Transport – responsible for reliably transmitting data from end to end. This is the layer seen by UNIX programmers/users when transmitting data over TCP/IP (Transmission Connection Protocol/Internet Protocol) sockets between processes. 5. The Session – responsible for the initialization of a connection. 6. The Presentation – performs data transformation such as byte swapping or encryption. 7. The Application – the layer that is designed which may also consist of subsystem layers itself. Until recently, only the 4 bottom layers of the OSI model were well standardized. For example, UNIX and many desktop operating systems provide the interfaces with TCP/IP (Transmission Control Protocol/Internet Protocol) that implemented the Transport, Network and Datalink layers that connects to the Physical (generally implemented via an Eternet card) layer. The application developer still had to implement the Session and Presentation layers along with the Application layer. However, with the growing amount of distributed systems, this gap (between the Transport and Application layers) has been filled with such middleware as CORBA and Java RMI. These enable messages to be sent back and forth hence allowing us to effectively implement the Session and Presentation layers. (Figure 6-10 on page 236 shows this distribution) Closed layered is advantageous because it provides low coupling between subsystems hence allowing the development and testing of individual subsystems and eventually integration of progressive subsystem. The disadvantage is that it may require more storage and reduces speed. It may also lead to difficulties in implementing nonfunctional requirements. 3 An example of open architecture is Java Swing user interface toolkit. In this case the operating system provides the lowest level with the next higher level being the AWT component followed up the ladder by the Swing component then the Application. Any Application can effectively bypass the Swing component and utilize only the AWT component. That is the idea behind the open system. Another approach outside of layering is to partition n the system into peer subsystems. The other method is to use partition – each subsystem responsible for a different class of services. This is where each subsystem depends upon each other loosely, but they can still operate in isolation. Of course, these two approaches could be used in the same application. Software Architecture: There are different software architectures to be considered when developing a system. This should be done at the system design level because we want not to wait until after coding only to realize that the architecture that was chosen at the beginning does not support, for example, a database. Repository architecture: There is a single data structure that exist called a repository. The subsystems interact only through the repository, otherwise they are fairly independent. This is typical for DBMS used in large companies such as a bank or insurance company, etc. This facilitate not only maintenance of data integrity, but such other aspects of the system as security, etc. The repository itself may control the flow of data or the subsystems may control the flow of data via locks in the repository that needs to be synchronized. Model/View/Controller architecture: Classified into 3 different types: Figure 6.15, 6.16 & 6.17 pages 240 – 242. 1. Model subsystems – responsible for maintaining domain knowledge. 2. View subsystems – responsible for display to user. 3. Controller subsystems – responsible for managing the sequence of interactions with user. This is also a type of repository architecture. It is used mostly in interactive systems, especially when multiple views of the same model are needed. Client/Server architecture: In this case a subsystem, the server, provides services to other subsystems, the client. 4 The client interact with the user via a remote call or by CORBA (common object broker). The control flow between these two are independent except when synchronization is required to manage requests or to receive results. This sort of architecture is well suited for managing large databases. Well suited for the internet. Peer-to-peer architecture: Similar to a client/server architecture except that each subsystem can act as a server as well as a client. Three-tier: This style organizes the subsystem into three layers: Figure 6-22 pp 245. 1. The interface layer – includes all boundary objects that deal with the user including windows, web pages, forms, etc. 2. The application logic layer – includes all control and entity objects realizing the processing and checking the rules, etc. 3. The storage layer – realizes the storage of the data, retrieval of data, etc. Four-tier: This is actually a three-tier but the interface layer is modified to be a presentation client layer and a presentation server layer. Pipe and filter architecture: In this type of architecture, subsystems process data from a set of inputs and send results to other subsystems via a set of outputs. The subsystems are called filters and the associations between the subsystems are called pipes. Only the content and format of the data is known by each filter received via the pipe. The filters are executed concurrently and synchronization is done by the pipes. This type of architecture is modifiable. That is, they could be reconfigured to achieve different purposes. The best example is the UNIX shell. UML Deployment diagrams: These are used to depict the relationship between run-time components and hardware nodes. The components are supposed to be self contained entities that will provide services to other component. Example diagrams of page 189 figs. 6.24 and 6.25. In these diagrams, nodes are represented by boxes and dependencies by dashed arrows. System design activities: The activities for design model are: 1. Identify design goals from the nonfunctional requirements. 5 2. Design an initial subsystem decomposition. 3. Map subsystems to processors and components. 4. Decide storage. 5. Define access control policies. 6. Select control flow mechanism. 7. Identify boundary conditions. The authors used the MyTrip example to go through these processes. They first describe the analysis model by using use cases. They gave two use cases describing PlanTrip and ExecuteTrip. They also elaborate nonfunctional requirements (p.p. 249). From analyzing the nonfunctional requirements, they came up with the following design goals for MyTrip: 1. Reliability: (nonfunctional requirement #2). 2. Fault Tolerance: (nonfunctional requirement #2). 3. Security: (deduced from application domain). 4. Modifiability: (anticipation of change by developers). Note that design goals can be select from a list of desirable qualities grouped into five categories: 1. Performance Criteria: Includes the speed and space requirements for the system response time, throughput, and memory. 2. Dependability Criteria: Address the amount of effort expended on minimization of crashes and security - Robustness, Reliability, Availability, Fault Tolerance, Security and safety. 3. Cost Criteria: Considers the cost for developing, deploying and administering the system. Development cost, Deployment cost, Upgrade cost, Maintenance cost and Administration cost. 4. Maintenance Criteria: How difficult it will be to change the system after deployment. Extensibility, Modifiability, Adaptability, Portability, Readability and Traceability of requirements. 5. End User Criteria: Qualities that are desirable from a users’ point of view. Utility (How well does the system support the user’s work?) and usability (How difficult the software is to use and learn?). 6 One must understand that when designing software, all of these criteria cannot figure in a single software. Trade offs will occur and must always be a key factor in the designing process. Some trade offs are given in table 6.7 p.p. 252. Identifying Subsystems: Heuristics for grouping objects into subsystems: 1. Assign objects identified in one use case into the same subsystem. 2. Create a dedicated subsystem for objects used for moving data among subsystem. 3. Minimize the number of associations crossing subsystem boundaries. 4. All objects in the same subsystem should be functionally related. Initial subsystem decomposition should be derived from the functional requirements. Note: revision could always be made and subsystems could be combined as well as divided into more subsystems. Also, new subsystems could be added as the need arises. The example from the book shows the Trip using two subsystems. The objects from Fig. 6.29 (p.p. 254) grouped into the two subsystems –1. RoutingSubsystem and 2. PlanningSubsystem. Also note that the only crossing between these two subsystem is between the objects RoutingSubsystem:RouteAssistant and PlanningSubsystem:Trip. This produces a loose coupling (which is looked for in coupling between subsystems). In OO, the use of a Façade Pattern is encouraged. This provides encapsulation whereby the details are hidden and only a simple user interface is provided. This effectively reduces coupling between subsystems. 7