# Good Software Architecture

February 20, 1998 - Jack Harich - happyjac@mindspring.com
C:\jp\org\jcon\GoodSoftArch.html

> > Notes for the Java Second Language all day clinic on System Architecture.

###

## Strategic Considerations

> One must remember the "Iron Triangle" of cost, time and quality. A change in one is offset by an equal and opposite change in another. For example reducing time to market requires an increase in cost or reduction in quality or features. Software architecture follows this same law. There are always tradeoffs as you try to make one portion of your architecture or project better.

> There is no one perfect architecture. Where there is agreement on trends and best practices, each industry, corportation, system, subsystem, application and development team is different. One must strive for what suffices, what is appropriate for the situation at hand. Since your architecture cannot be perfect, it must be flexible.

> Serious software that is not architecture driven is tomorrow's legacy. Somewhere in the back of your subconsciousness a little bird should always be chirping "every step, every decision is architecture driven."

> It is a myth that "there's no time for modeling". From my personal experience, anything over 4 hours or involving two or more classes goes significantly faster with modeling. My rule of thumb is that modeling doubles my productivity with Java, and for systems over 300 classes makes the difference between project success and failure. Those who vow "there's no time for modeling" have probably not learned how to apply OOAD with modeling effectively. Approximately 80% of America's developers do not model before they code. Nuff said.

> Architecture is needed at the enterprise, subsystem and application levels. Each takes a different approach but there can be much reuse.

> ## What is software architecture?

> A definition:

> > "Architecture defines the static organization of software into subsystems, interconnected through interfaces, and defines how those nodes interact. An architecture conforms to one or several styles." - Ivar Jacobson

> Note how Ivar implies that a class model is not architecture. He's right on the button. Architecture applies to thinking about a system in terms of its many subsystems, and staying at that level of abstraction until you've organized the concept into subsystems, and nailed down a sound approach to how those subsystems will collaborate effectively.

> How is software architecture best expressed? In a small number of one page models giving different views, such as the conceptual view, subsystem partitions view, deployment view and data flow view.

> ## Benefits

> - Lower life cycle cost
> - Faster time to market
> - Lower defects
> - More robustness
> - Easier evolution
> - More understandable
> - Longer lifetime
> - Higher reuse
> - More enjoyable to work on

> ## Leading Architectural Styles

> Layered - The subsystems are partitioned according to generality into groups called layers. These are arranged on a page with the layers running from top to bottom, with the most specific one at the top and the most general at the bottom. The best material I know of on Layered Architecture is Chapter 7 in Software Reuse, by Ivar Jacobson. His standard layers are:

> > - Application
> > - Business specific (aka domain)
> > - Middleware
> > - System Software (platform specific, eliminated with Java)

> There are more subsystems and churn the higher up you go in the model, which looks like an inverted pyramid. The layers can be from 2 to about 7, and named anything descriptive. Subsystems can be layered as well.

> An ironclad rule is that a layer cannot use anything above that layer. This guarentees loose coupling. The result is that a subsystem in one layer can be changed or even removed without impacting lower layers. Since the lower a layer is, the harder it is to change and the more dependencies its involved in. This is A Good Thing.

> If a layer does need call upward an event should be used. The event class and listener interface should be in the lower layer. The upper layer would add a class as a listener to an event in the lower layer, such as notification that a fax has arrived. The event mechanism preserves loose coupling.

> Partitioned - The most common (but not most appropriate) architecture is dividing a system into two or more subsystems with various relationships. Ivar recommends 2 to 4 partitions maximum. This sounds small but in practice is fine.

> For example a standard partitioned architecture is User Interface, Business Logic, Persistence and System Interface. Until the last year or so this was the leading generic system architecture.

> Service Oriented - This is the hottest architecture going. You divide a system into Applications and Services. Any app (or Applications subsystem) can use any service, which is often remote. The services are application neutral and are heavily used to perform routine tasks that many apps need. Examples of services are:

> - Events (listening or sending events, synchronous or asynchronous)
> - Naming (registering or getting an object by name)
> - Transaction Management (crucial and difficult for distributed systems)
> - Persistence (difficult to handle transparently)
> - Object Identity
> - Object Locking

> CORBA was the first popular attempt to standardize service architecture at the enterprise level, which was called an Object Request Broker (ORB). This is now being superceded by Object Transaction Monitors (OTM), which perform far more difficult services than CORBA was envisioned for, so CORBA must evolve.

> OTMs will become the dominant services manager for distributed systems over the next few years. In the simplest case, each server will have an OTM. This is really just a transaction oriented ORB or component oriented Tranaction Processing Monitor. Important services are distributed transaction management, load balancing, object lifetime management, events, security, reliability and general management. The expected main players for this kind of middleware are Microsoft Transaction Manager, CORBA/Java, and IBM's Component Broker. All this means that the dominant architecture for distributed systems must include Service Oriented.

> Pipes - Here the system is partioned into a series of connected processes, with input and output at the ends. Inter-system software can use this scheme very effectively, the best example being TCP/IP.

> ## Architectural Requirements Factors

> These vary wildly and determine the most appropriate architecture for a particular system. Some are:

> - Transaction load
> - Non-transaction load
> - Homogenous nature of peers
> - Distribution topology
> - Security needs
> - Expected lifetime of applications and systems
> - Persistence needs
> - Dominance of the GUI
> - System size and complexity
> - Sophistication of developers and management
> - Time, Cost and Quality pressure
> - Reuse goals

##

## Techniques

> There are plenty of "best practices" to use to achieve the ever elusive "good architecture" and design of systems and subsystems. Here's some of the most important:

> - Use a tried and true Architecture Pattern(s).
> - Component driven throughout
> - Plug points - A property determines a class or entire subsystem.
> - Low coupling
> - High cohesion
> - Correct abstractions
> - Reductiion of apparent and actual complexity, ie simplicity
> - Patterns
> - Events
> - Properties
> - Roles
> - Isolation of business rules
> - Parameter driven
> - Optimal relationships
> - Proper and minimal dependencies
> - Recursive decomposition
> - Different model views
> - Internal architecture is consistent with its visual presentation

> ## Checklist

> The more of these you can say YES to the better:

> 1. Standard architecture patterns have been used
> 2. A current, clear high level model exists for the system and all subsystems
> 3. Easy interface to other systems
> 4. The system is easily configurable for reuse as a different product
> 5. It looks too simple but it works
> 6. It looks easy to design and implement
> 7. Everybody who sees it understands it instantly
> 8. The system is re-entrant, ie it can be reused in the same process
> 9. No model takes more than one page
> 10. Each subsystem is reusable
> 11. It's platform, database, IDE, browser and middleware independent
> 12. Any dependent system is easily replacable, especially middleware
> 13. The architecture is at least the 3rd iteration of real implementations
> 14. There's really nothing new here