Download Beautiful Architecture: Leading Thinkers Reveal the Hidden Beauty in Software Design PDF

TitleBeautiful Architecture: Leading Thinkers Reveal the Hidden Beauty in Software Design
PublisherO'Reilly
ISBN 139780596517984
Author
LanguageEnglish
File Size4.4 MB
Total Pages428
Table of Contents
                            Contents
Foreword
Preface
	How This Book Is Organized
		Part I: On Architecture
		Part II: Enterprise Application Architecture
		Part III: Systems Architecture
		Part IV: End-User Application Architectures
		Part V: Languages and Architecture
	Principles, Properties, and Structures
	Conventions Used in This Book
	Using Code Examples
	Safari® Books Online
	How to Contact Us
	Acknowledgments
Part I. On Architecture
	Chapter 1. What Is Architecture?
		Introduction
			The Role of Architect
			The Role of the Software Architect
			What Constitutes a Software Architecture?
			Architecture Versus Design
		Creating a Software Architecture
		Architectural Structures
			The Information Hiding Structures
			The Uses Structures
			The Process Structures
				Process gives work to
				Process gets resources from
				Process shares resources with
				Process contained in module
			Access Structures
			Summary of Structures
		Good Architectures
		Beautiful Architectures
		Acknowledgments
		References
	Chapter 2. A Tale of Two Systems: A Modern-Day Software Fable
		The Messy Metropolis
			Down the Tubes
				Incomprehensibility
				Lack of cohesion
				Unnecessary coupling
				Code problems
				Problems outside the code
				Clear requirements
			Where Is It Now?
			A Postcard from the Metropolis
		Design Town
			First Steps into Design Town
			The Story Unfolds
				Locating functionality
				Consistency
				Growing the architecture
				Deferring design decisions
				Maintaining quality
				Managing technical debt
				Unit tests shape design
				Time for design
				Working with the design
			Where Is It Now?
		So What?
		Your Turn
		References
Part II. Enterprise Application Architecture
	Chapter 3. Architecting for Scale
		Introduction
		Context
			The First Goal
			The Game World
			Latency Is the Enemy
		The Architecture
			The Macro Structure
			The Basic Services
			Communication Services
			Task Portability
		Thoughts on the Architecture
			Parallelism and Latency
			Betting on the Future
			Simplifying the Programmer’s Job
	Chapter 4. Making Memories
		Capabilities and Constraints
		Workflow
		Architecture Facets
			Modules and Launcher
				ApplicationContext
				Module dependencies
				Launcher
			Kiosk-Style GUI
			UI and UI Model
				Forms
				Properties
				Bindings
				Application facade
			Interchangeable Workstations
				Image repositories
				NIO image transfer
				Fast and robust
			Database Migrations
				Updates as objects
				Regular exercise
				Safety features
				Field results
			Immutable Data and Ubiquitous GUIDs
			Render Farm
				Conway’s Law, applied
				DVD loading
				Render pipeline
				Fail fast
				Scale out
		User Response
		Conclusion
		References
	Chapter 5. Resource-Oriented Architectures: Being
  “In the Web”
		Introduction
		Conventional Web Services
		The Web
		Resource-Oriented Architectures
		Data-Driven Applications
		Applied Resource-Oriented Architecture
		Conclusion
	Chapter 6. Data Grows Up: The Architecture of the Facebook Platform
		Introduction
			Some Application Core Data
			Some Facebook Core Data
			Facebook’s Application Platform
		Creating a Social Web Service
			Data: Creating an XML Web Service
			A Simple Web Service Authentication Handshake
		Creating a Social Data Query Service
			Method Call Batching
			FQL
				Architecture of FQL
		Creating a Social Web Portal: FBML
			Applications on Facebook: Directly Rendering HTML, CSS, and JS
			Applications on Facebook: iframes
			Applications on Facebook: FBML As Data-Driven Execution Markup
				Direct HTML tags
				Data-display tags
				Data-execution tags
				Design-only tags
				Replacement HTML tags
				“Functionality package” tags
				FBML: A small example
			FBML Architecture
				Implementing direct HTML tags in FBML
				Implementing data-display tags in FBML
				Data-execution tags in FBML
				Putting it all together
		Supporting Functionality for the System
			Platform Cookies
			FBJS
			Service Improvement Summary
		Summation
Part III. Systems Architecture
	Chapter 7. Xen and the Beauty of Virtualization
		Introduction
		Xenoservers
		The Challenges of Virtualization
		Paravirtualization
		The Changing Shape of Xen
		Changing Hardware, Changing Xen
		Lessons Learned
			Paravirtualization
			Open Source Development
		Further Reading
	Chapter 8. Guardian: A Fault-Tolerant Operating System Environment
		Tandem/16: Some Day All Computers Will Be Built Like This
		Hardware
			Diagnosis
			Repair
		Mechanical Layout
		Processor Architecture
			Memory Addressing
			Procedure Calls
			Action of the PCAL and SCAL Instructions
		The Interprocessor Bus
		Input/Output
		Process Structure
			Process Pairs
		Message System
			Process Pairs, Revisited
			Synchronization
			Networking: EXPAND and FOX
				System names
				FOX
		File System
			File Naming
			Asynchronous I/O
			Interprocess Communication
			System Messages
			Device I/O
			Security
			File Access Security
		Folklore
		The Downside
			Performance
			Hardware Limitations
			Missed Opportunities
			Split Brain
		Posterity
		Further Reading
	Chapter 9. JPC: An x86 PC Emulator in Pure Java
		Introduction
		Proof of Concept
			Potential Processor Performance Tests
		The PC Architecture
		Java Performance Tips
		Four in Four: It Just Won’t Go
		The Perils of Protected Mode
		Fighting A Losing Battle
			Microcoding: Less Is More or More Is Less
		Hijacking the JVM
			Compiling: How to Reinvent the Wheel
				Simple code generation
				Handling exceptions
				Bytecode manipulation
			Class Loading and Unloading, but on a Big Scale
				Codeblock replacement
		Ultimate Flexibility
			Flexible Data Anywhere
			Flexible Auditing and Support
			Flexible Computing Anywhere
		Ultimate Security
		It Feels Better the Second Time Around
	Chapter 10. The Strength of Metacircular Virtual Machines: Jikes RVM
		Background
		Myths Surrounding Runtime Environments
			As Runtime Compilers Must Be Fast, They Must Be Simple
			Unlimited Analysis in a Static Compiler Must Mean Better Performance
			Runtime Analysis Uses a Lot of Resources
			Dynamic Class Loading Inhibits Performance
			Garbage Collection Is Slower Than Explicit Memory Management
			Summary
		A Brief History of Jikes RVM
		Bootstrapping a Self-Hosting Runtime
			Object Layout
			Runtime Memory Layout
			Compiling the Primordials and Filling in the JTOC
			The Boot Image Runner and VM.boot
		Runtime Components
			Basic Execution Model
			Adaptive Optimization System
			Optimizing Compilation
				HIR
				LIR
				MIR
				Factored control flow graph
				Scalar and extended array SSA forms
				Partial evaluation
				On-stack replacement
				Summary
			Exception Model
			Magic, Annotations, and Making Things Go Smoothly
			Thread Model
			Native Interface
			Class Loaders and Reflection
			Garbage Collection
				Jikes RVM integration
				Summary
		Lessons Learned
		References
Part IV. End-User Application Architectures
	Chapter 11. GNU Emacs: Creeping Featurism Is a
  Strength
		Emacs in Use
		Emacs’s Architecture
			The Model: Buffers
			The View: Emacs’s Redisplay Engine
			The Controller: Emacs Lisp
		Creeping Featurism
			Creeping Featurism and User Interface Complexity
				How complex is the Model?
				How complex is the command set?
			Creeping Featurism and Maintainability
		Two Other Architectures
			Eclipse
			Firefox
	Chapter 12. When the Bazaar Sets Out to Build
  Cathedrals
		Introduction
		History and Structure of the KDE Project
		Akonadi
			Background
			The Evolution of Akonadi
			The Akonadi Architecture
			The First Release and Beyond
		ThreadWeaver
			Introduction to ThreadWeaver: Or, How Complicated Can It Be to Load a File?
			Core Concepts and Features
			Declarative Concurrency: A Thumbnail Viewer Example
			From Concurrency to Scheduling: How to Implement Expected Behavior Systematically
			A Crazy Idea
Part V. Languages and Architecture
	Chapter 13. Software Architecture: Object-Oriented Versus Functional
		Overview
		The Functional Examples
		Assessing the Modularity of Functional Solutions
			Extendibility Criteria
			Assessing the Functional Approach
			Levels of Modularity
			The Functional Advantage
			State Intervention
		An Object-Oriented View
			Combinators Are Good, Types Are Better
			Using Software Contracts and Genericity
			The Modularization Policy
			Inheritance
			Polymorphism, Polymorphic Containers, and Dynamic Binding
			Deferred Classes and Features
		Assessing and Improving OO Modularity
			Reusing Operations
			Extendibility: Adding Types
			Extendibility: Adding Operations
		Agents: Wrapping Operations into Objects
			The Agent Mechanism
			Scope of Agents
			An Agent-Based Library to Make the Visitor Pattern Unnecessary
			Assessment
		Acknowledgments
		References
	Chapter 14. Rereading the Classics
		Everything Is an Object
		Types Are Defined Implicitly
		Problems
		Brick and Mortar Architecture
		References
Appendix . Afterword
Appendix . Contributors
Index
                        
Document Text Contents
Page 214

Asynchronous I/O

One of the important features of the file system interface is the strong emphasis on
asynchronous I/O. We’ve seen that the message system is intrinsically asynchronous in nature,
so this is relatively simple to implement.

Processes can choose synchronous or asynchronous (“no wait”) I/O at the time they open a
file. When a file is opened no-wait, an I/O request will return immediately, and only errors
that are immediately apparent will be reported—for example, if the file descriptor isn’t open.
At a later time the user calls awaitio to check the status of the request. This gives rise to a
programming style where a process issues a number of no-wait requests, then goes into a
central loop to call awaitio and handle the completion of the requests, typically issuing a new
request.

Interprocess Communication

At a file system level, interprocess communication is a relatively direct interface to the message
system. This causes a problem: the message system is asymmetrical. The requestor sends a
message and may receive a reply. There’s nothing that corresponds to a file system read
command. On the server side, the server reads a message and replies to it; there’s nothing that
corresponds to a write command.

The file system provides read and write procedures, but read only works with I/O processes,
which map them to message system requests. read doesn’t work for the interprocess
communication level, and in practice write also is not used much. Instead, the requestor uses
a procedure called writeread to first write a message to the server and then get a reply from it.
Either the message or the reply can be null (zero length).

These messages find their way to the server’s message queue. At a file system level, the message
queue is a pseudofile called $RECEIVE. The server opens $RECEIVE and normally uses the
procedure readupdate to read a message. At a later point it can reply with the procedure reply.

System Messages

The system uses $RECEIVE to pass messages to processes. One of the most important is the startup
message, which passes parameters to a newly started process. The following example is written
in TAL, Tandem’s low-level system programming language (though the name stands for
“Tandem Application Language”). TAL is derived from HP’s SPL, and it is similar to Pascal and
Algol. One of the more unusual characteristics is the use of the caret (^) character in identifiers;
the underscore ( _ ) character is not allowed. This example should be close enough to C to be
intelligible. It shows a process that starts a child server process and then communicates with it.

The first piece shows the parent process (requestor):

call newprocess (program^file^name,,,,,, process^name); -- start the server process
call open (process^name, process^fd); -- open process

192 C H A P T E R E I G H T

Page 215

call writeread (process^fd, startup^message, 66); -- write startup message
while 1 do
begin
read data from terminal
call writeread (process^fd,
data, data^length, -- write data
reply, max^reply, -- read data back
@reply^length); -- return real reply length
if reply^length > 0
write data back to terminal
end;

The following shows the child process (server):

call open (receive, receive^fd);
do
call read (receive^fd, startup^message, 66);
until startup^message = -1; -- first word of startup message is -1.
while 1 do
begin
call readupdate (receive^fd, message, read^count, count^read);
process message received, replacing buffer contents
call reply (message, reply^length);
end;

The first messages that the child receives are system messages: the parent open of the child sends
an open message to the child, and then the first call to writeread sends the startup message. The
child process handles these messages and replies to them. It can use the open message to keep
track of requestors or receive information passed in the last 16 bytes of the file name. Only
then does the process receive the normal message traffic from the parent. At this point, other
processes can also communicate with the child. Similarly, when a requestor closes the server,
the server receives a close system message.

Device I/O

It’s important to remember that device I/O, including disk file I/O, is handled by I/O processes,
so “opening a device” is really opening the I/O process. Still, I/O to devices and files is
implemented in a slightly different manner, though the file system procedures are the same.
In particular, the typical procedures used to access files are the more conventional read and
write, and normally disk I/O is not no-wait.

Security

In keeping with the time, the T/16 is not an overly secure system. In practice, this hasn’t caused
any serious problems, but one issue is worth mentioning: the transition from nonprivileged to
privileged procedures is based on the position of the procedure entry point in the PEP table
and the value of the priv bit in the E register. Early on, exploits became apparent. If you could
get a privileged procedure to return a value via a pointer and get it to overwrite the saved E
register on the stack in such a way that the priv bit was set, the process would remain privileged

G U A R D I A N : A F A U L T - T O L E R A N T O P E R A T I N G S Y S T E M E N V I R O N M E N T 193

Page 427

C O L O P H O N

The cover image is a nautilus shell from Veer. The cover fonts are Akzidenz Grotesk and

Orator. The text font is Adobe’s Meridien; the heading font is ITC Bailey.

Similer Documents