2007年4月12日

Design for Change and Reuse

[Abstract] Designing software for change and reuse is a technical process and a project management process as well. The core of modern software programming is “decoupling” – from structured programming, to object oriented programming, to component technology, and to service oriented design approach, software engineering using “divide and conquer” to handle complexity.

Software architecture is a deliberated collaboration of all the software development teams. In this process, software systems engineering is the driving force to create a prescriptive structure in defining the software components and their interdependencies, integrating all aspects of software development into a coherent and effective system. In addition to focusing on the implementation details, software developers have to pay more attention to the structure of systems.

The objectives of this paper are to share the perception of software development, to inspire the effective software development process, and to reduce the resistance of architecture as a product from all levels by providing in-depth analysis of the software development process.

1 Introduction

Software development is an engineering process. Many firms and companies have adopted the agile process to handle project changes and uncertainty. The agile process encourages embracing the changes rather than rejecting them. Because it is effective in improving communications and in increasing productivity and shortening the software lifecycle, the agile process has gained more and more popularity in daily software development business.

But there is at least one aspect of software development, where the agile process as a management methodology could not contribute a lot -- the system architecture, which sustains the software development and determines the software functionalities. Further more, the system architecture is one of the determining factors for software change and reuse. System architecture determines what the resulting systems will be, where the agile process will lead us to achieve the objectives.

Designing software for change and reuse can reduce software development cost in many aspects, such as in software re-factoring process, in handling increased business service requirements of a large enterprise, and in increasing performance and productivity.

2 The Common Interest of Software and Systems Engineering

Following the paths of software and systems engineering advancement, we can see that the two disciplines convergence at one common interest in reducing system complexity and in improving system performance, i.e., defining/modeling system as autonomous, self-descriptive unites, improving their internal communication, and reducing message passing.

2.1 Technical Advancement in Software Engineering

In IT industry, many projects last for years. New features and requirements have been added to the products, often leading the software products into an unmanageable complex monster. Cumulative short-term solutions instead of long-term ones seriously devastate software maintainability. Software re-factoring becomes necessary. For small-scale projects, software re-factoring plays an important role in handling the changing/new requirements and creating a well-performed system. For large projects, it seems that the project management team could not afford the time loss for software re-factoring.

It is a repeated story that software re-factoring is very hard because the management team wants to see the measurable results. The management team has its own concerns, the software re-factoring is a complex process, and does not always create the expected results. Very often re-factoring leads to a development disaster because the software team does not have the required technical and managerial skills. The change and reuse become a topic people discuss everyday but hard to materialize.

Not until software development reaches to a point, when the cost of maintenance far exceeds that of the refactoring efforts, new software lifecycle begins. But not many people could learn lessons from past. The existing company culture often leads the new software development to repeat its history. Software development disciplines continuously struggle to solve this technical and managerial complexity, which leads the technical advancement of software development, from structured programming to object oriented programming, to software component technology, to service oriented architecture.

From the path of software development advancement or evolution, we can see, the technical advancement emphasizes one common issue, i.e., decoupling – the implementation of “divide and conquer”. An optimized software design often has a clear boundary at all levels of software products. Given java programming or c++ as an example, at class level, structured programming technique is used. At component level, object oriented programming technique is used. At system level, service oriented architecture is emphasized. No single technology can lead to sound software architecture – the corner stones of software development.

For change and reuse, a software product ideally has clear boundaries and interfaces at all levels. Software component implements an interface for possible implementation variations. Data type used for message passing implements an interface to avoid dedication, allowing the associated component to participate in system integration. Further more, software components are deployed as products; a well- designed deployment infrastructure often fosters software development for change and reuse, and decouples software components at system level. A well-defined software architecture enables software componentization; leading to incremental development and deployment.

Medtronic Inc is a recognized innovator in medical technology and a Fortune 500 company, which provides the medical devices and services for Cardiac Rhythm Disease Management. There are many software development teams in this medical device company. Sharing the skills and techniques could reduce time and cost in their software development efforts and increase overall quality and productivity, which could be translating to economic gains. However, bridging the software development teams into a common development platform is very difficult due to having no common interfaces at both technical teams and management.

One of the development teams has invented a XML based device language, which started a discussion for a common device language for entire company. However, that language seems to be too complex to the software developers who do not have in-depth device knowledge –higher-level abstraction is required to encapsulate the business logic for common use. By the way, processing large XML document is inherently slow and will introduce potential performance issues.

Common device foundation libraries, which encapsulate business logic inside deployable software components, should be implemented. All software development teams share the libraries without “re-invent the wheel”. This is a more feasible approach, and commonly practiced in computer industries. An example of foundation library is MFC or Adobe API.

Both approaches, the common device language and common device libraries, require re-structuring software development teams. Software development teams should be reorganized into functional units based on their skills and technological focus. An eco-system management structure enables grouping of people by common interest and pipelining the development activities.

Not until the creation of Medtronic Device Foundation Class (MDFC), an architecture defining clear component boundaries is possible. The MDFC could be used in the development teams within Medtronic, it does not matter what kind of application each team is developing.

Software architecture is application specific and created on the top of foundation classes. Boundary class, business class and control class separation reduce the ripple effect and improve extendibility. Business class and control class separation is very important for change and reuse. Business class defines the business logics where the control class controls the workflow of an application. Boundary class can be used to wrap the legacy systems in providing commonly used interfaces and in improving encapsulations. Software design patterns can be implemented to further improve software quality for change and reuse. For example, business façade pattern can be used to cluster existing software components into a functional unit and provide a well-defined interface to encapsulate the complexity of business logics.

Software architectures are domain related. However, the component management and security management are often separated from the business component development efforts in a well-designed architecture. A successfully story of this separation is the java application server products, such as Jboss, WebLogic, etc. Commercial products are available. Software developers can focus on domain component development.

The separation of control class from business class also improves system extendibility. Control classes often change in a slower pace than business classes – only business classes have to be changed when including a new feature. For example, in Medtronic Patient Management software products, only the presentation logics/components have to be changed to support a new device, assuming the device library is available from other software teams.

2.2 The Atomic Nature of Systems

Systems engineering approach emphasize the systems as a whole; each subsystem has its own independent identity, provides its unique functionality, and depends on and communicates with other subsystems. All of the interdependent subsystems as a whole provide the required functionalities. In this environment, each subsystem is self-contained, autonomous, performs independently. The atomic nature of each subsystem determines that each subsystem has a clear boundary of its own and can be re-deployed to other systems.

It is the system engineers’ responsibility to define the system boundary and to model the system. System analysis and modeling are part of systems engineering training. Theoretically, system model is a reflection of the real world systems. System engineers divide real word system into subsystems – manageable entities, simplifying the resulting systems using minimum set of parameters, and defining system boundaries, systems behavior, their interdependencies, and communications.

System engineers are concerned with the lifecycle of subsystems, defining business contract, management contract and security contract between systems. From systems engineering point of view, a class, a component, or an application is a realization of a system model.

System engineers are the primary interface between management, customers, suppliers, and specialty engineers in system development process. Whereas other engineering disciplines concentrate on the details of individual aspects of a system (electronics, mechanics, software, etc.), system engineers are concerned with the integration of all of those aspects into a coherent and effective system [1].

System engineers and software engineers discuss software architectural problems using the same terminology. But they deal with software architectural problems from different angles. System engineers design product architecture where software engineers implement the details.

System engineers often play an important role in software refactoring. Instead of focusing on implementation details, software system engineers deal with software development process at component level and are the major force of driving software architecture and its evolution through domain analysis and engineering.

Domain analysis involves identifying the basic entities, relations, and operations of an application domain and its boundaries. A typical outcome of domain analysis is a domain-dependent specification that embodies the domain objects and operations on those objects. System engineers are the driving force for software architectural clarity.

Domain engineering consists of building “clusters” of classes, starting with the lowest level – the foundation classes which are most likely needed no matter what the final system design is.

Objects having the same properties and exhibiting the same behavior are grouped in classes. Class hierarchies are established where classes that share domain-significant data and domain-meaningful external behaviors are grouped under more generic classes – domain-independent classes.

The foundation class hierarchies close to domain analysis level object hierarchies enhance trace-ability, conceptual clarity, reuse of interfaces, and potential for reuse.

Software systems engineering is based on foundation classes, moving up to domain-dependent and application-specific components, and resolve problems by further system analysis to define architecture.

Reusable components can be developed using synchronous or asynchronous development process, either concurrently or separately from specific software development.

Combined with the component-based development and product architecture, abstraction can occur at a higher level to maximize reuse leverage. The interdependency and message passing among components can be managed to minimum. Software components are portable at any level.

The data persistent and distributed computation issues are out of system engineers’ concerns. The structure to store and retrieve data is natural formed through object to data mapping. Data persistent and distributed computation techniques are used when necessary.

2.3 Software Components for Change and Reuse

Software architecture is a deliberated collaboration of all the development team; it could not be true that a good architecture leads to bad implementation, or vice versa. The boundary of responsibility between systems engineering and software development often blurs at component level. Software components are re-deployable as products, and participate in higher-level component construction. System engineers use these components to define product architecture, where software engineers implement the components to provide the required functionalities. In this process, system engineers focus on domain-specific component abstraction and product architecture and leave enough space for software engineers to be innovative in software development for system performance.

It is hard for software developers to control the overall architecture of software architecture without the involvement of system engineers. Software engineers often focus on implementation details and specific technologies, such as distributed computation or communication using telemetry C technology. Overall architecture definition naturally becomes system engineers’ responsibility. A descriptive architecture is far less than adequate to deliver software products for change and reuse. System engineers have to deal with the details of software development at component level. A prescriptive architecture can ease the development efforts but requires systems engineering professionals not only have in-depth domain knowledge but also software design experience. Because of the importance of software architecture in determining software performance, software engineers often provide more details for architectural improvement.

In some firms, software deployment is a separate process. Creating deployable software components for change and reuse requires more coordination and education, in both development and deployment process. Configuration management often performs at component level and leaves the business details to software developers.

Only well-planed re-deployable software components can be reused without demanding too many dependencies on external, unrelated resources. An extreme example of external dependency is a single method call, which could be implemented in 100 lines of code, ends up using a 100M dynamic library of another unrelated system.

Optimized software product is created through the coordination of entire development team and disciplined software implementation based on software product architecture.

Software design for change and reuse is not achievable until the science and philosophy of software design for change and reuse is understood and gained supports from all development levels. It is an education process.

Software development is not only a science, but also a process, a culture of a company. The perception change is the first step toward the right direction.

3 Conclusion

Software re-factoring is a painful process; it costs a lot of development and testing efforts for unchanged functionalities. However, the current “quick and dirty” approach almost always leads software product into overwhelming complexity.

Design for change and reuse can improve software quality because we do not have to change the foundation in every release. Design for change and reuse can minimize the development efforts, because only the new components have to be developed and deployed. Design for change and reuse can minimize the testing efforts, because the change is minimized. Design for change and reuse can improve system performance, because developers can easily identify the problems and focus on the root cause.

4 Reference

[1] http://www.incose.org/educationcareers/careersinsystemseng.aspx
[2] Paul Allen, etc., Sun Certified Enterprise Architect for J2EE, the McGraw-Hill Company, 2003, p23-24

没有评论: