Beautiful Code [69]
[*]Object-Oriented Software Construction, Second Edition, Bertrand Meyer, Prentice Hall, 1997.
Fortunately, two decades of advances in design/implementation techniques and programming languages have made it much easier to write and reuse networked software. In particular, object-oriented (OO) programming languages (such as C++, Java, and C#) combined with patterns (such as Wrapper Facades, []Adapters, and the Template Method []), and frameworks (such as host infrastructure middleware like ACE[§] and the Java class libraries for network programming, [||]and similar host infrastructure middleware) help to encapsulate low-level functional OS APIs and mask syntactic and semantic differences between platforms. As a result, developers can focus on application-specific behavior and properties in their software, rather than repeatedly wrestling with the accidental complexities of programming the low-level networking and OS infrastructure.
[]Pattern-Oriented Software Architecture, Vol. 2: Patterns for Concurrent and Networked Objects, Douglas Schmidt, Michael Stal, Hans Rohnert, and Frank Buschmann, John Wiley and Sons, 2000.
[]Design Patterns: Elements of Reusable Object-Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Addison-Wesley, 1995.
[§] C++ Network Programming, Vol. 2: Systematic Reuse with ACE and Frameworks, Douglas C. Schmidt and Stephen D. Huston, Addison-Wesley Longman, 2003.
[||]Java Network Programming, Third Edition, Elliotte Rusty Harold, O'Reilly, 2004.
A key benefit of applying patterns and frameworks to networked software is that they can help developers craft reusable architectures that (1) capture the common structure and behavior in a particular domain, and (2) make it easy to change or replace various algorithms, policies, and mechanisms selectively without affecting other existing parts of the architecture. While most developers of networked software can apply well-designed OO frameworks to their applications, the knowledge of how to create such a framework remains a black art that has historically been learned only by extensive (and expensive) trial and error.
In addition to the conventional challenges of devising a flexible OO design that can expand and contract to meet new requirements, networked software must often run efficiently and scalably in a range of operating environments. The goal of this chapter is to help demystify the black art of OO frameworks for networked software by using a case study to systematically dissect the design and implementation of a representative networked software application.
In general, the beauty of our solution stems from its use of patterns and OO techniques to balance key domain forces, such as reusability, extensibility, and performance. In particular, our approach enables developers to identify common design/programming artifacts, thereby enhancing reuse. It also provide a means to encapsulate variabilities in a common and parameterizable way, thereby enhancing extensibility and portability.
26.1. Sample Application: Logging Service
The OO software that we use as the basis of our case study is a networked logging service. As shown in Figure 26-1, this service consists of client applications that generate log records and send them to a central logging server that receives and stores the log records for later inspection and processing.
Figure 26-1. Architecture of a networked logging service
The logging server portion (at the center of Figure 26-1) of our networked logging service provides an ideal context for demonstrating the beauty of OO networked software because it exhibits the following dimensions of design-time variability that developers can choose from when implementing such a server:
Different interprocess communication (IPC) mechanisms (such as sockets, SSL, shared memory, TLI, named pipes, etc.) that developers can use to send and receive log records.
Different concurrency models (such as iterative, reactive, thread-per-connection,