Building Evolutionary Architectures Automated
Software Governance 2nd Edition Neal Ford
download
https://ebookbell.com/product/building-evolutionary-
architectures-automated-software-governance-2nd-edition-neal-
ford-50008164
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
Building Evolutionary Architectures Support Constant Change 1st
Edition Neal Ford
https://ebookbell.com/product/building-evolutionary-architectures-
support-constant-change-1st-edition-neal-ford-6724076
Building Evolutionary Architectures Support Constant Change Neal Ford
Rebecca Parsons Patrick Kua
https://ebookbell.com/product/building-evolutionary-architectures-
support-constant-change-neal-ford-rebecca-parsons-patrick-
kua-230924664
Odontodes The Developmental And Evolutionary Building Blocks Of
Dentitions 1st Edition Donglei Chen
https://ebookbell.com/product/odontodes-the-developmental-and-
evolutionary-building-blocks-of-dentitions-1st-edition-donglei-
chen-53166774
Evolutionary Optimisation Of Faade Design A New Approach For The
Design Of Building Envelopes 1st Edition Giovanni Zemella
https://ebookbell.com/product/evolutionary-optimisation-of-faade-
design-a-new-approach-for-the-design-of-building-envelopes-1st-
edition-giovanni-zemella-4661712
Building A Revolutionary State The Legal Transformation Of New York
17761783 Howard Pashman
https://ebookbell.com/product/building-a-revolutionary-state-the-
legal-transformation-of-new-york-17761783-howard-pashman-51438000
Building The Revolutionary Party Jim Percy Selected Writings 198087
Jim Percy
https://ebookbell.com/product/building-the-revolutionary-party-jim-
percy-selected-writings-198087-jim-percy-2124078
State Building In Revolutionary Ukraine A Comparative Study Of
Governments And Bureaucrats 19171922 Stephen Velychenko
https://ebookbell.com/product/state-building-in-revolutionary-ukraine-
a-comparative-study-of-governments-and-bureaucrats-19171922-stephen-
velychenko-51961506
State Building In Revolutionary Ukraine A Comparative Study Of
Governments And Bureaucrats 19171922 Stephen Velychenko
https://ebookbell.com/product/state-building-in-revolutionary-ukraine-
a-comparative-study-of-governments-and-bureaucrats-19171922-stephen-
velychenko-43222732
Building Bone Vitality A Revolutionary Diet Plan To Prevent Bone Loss
And Reverse Osteoporosiswithout Dairy Foods Calcium Estrogen Or Drugs
1st Edition Amy Lanou
https://ebookbell.com/product/building-bone-vitality-a-revolutionary-
diet-plan-to-prevent-bone-loss-and-reverse-osteoporosiswithout-dairy-
foods-calcium-estrogen-or-drugs-1st-edition-amy-lanou-2368600
Building Evolutionary Architectures Automated Software Governance 2nd Edition Neal Ford
Building Evolutionary Architectures Automated Software Governance 2nd Edition Neal Ford
Building Evolutionary Architectures
2ND EDITION
Automated Software Governance
Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage
Building Evolutionary Architectures
by Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage
Copyright © 2023 Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage. All rights
reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online
editions are also available for most titles (http://oreilly.com). For more information, contact our
corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.
Acquisitions Editor: Melissa Duffield
Development Editor: Virginia Wilson
Production Editor: Christopher Faucher
Copyeditor: Audrey Doyle
Proofreader: Piper Editorial Consulting, LLC
Indexer: WordCo Indexing Services, Inc.
Interior Designer: David Futato
Cover Designer: Karen Montgomery
Illustrator: O’Reilly Media, Inc.
October 2017: First Edition
December 2022: Second Edition
Revision History for the Second Edition
2022-11-22: First Release
See http://oreilly.com/catalog/errata.csp?isbn=9781492097549 for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Building Evolutionary
Architectures, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc.
The views expressed in this work are those of the authors and do not represent the publisher’s
views. While the publisher and the authors have used good faith efforts to ensure that the
information and instructions contained in this work are accurate, the publisher and the authors
disclaim all responsibility for errors or omissions, including without limitation responsibility for
damages resulting from the use of or reliance on this work. Use of the information and
instructions contained in this work is at your own risk. If any code samples or other technology
this work contains or describes is subject to open source licenses or the intellectual property
rights of others, it is your responsibility to ensure that your use thereof complies with such
licenses and/or rights.
978-1-492-09754-9
[LSI]
Foreword to the First Edition
For a long time, the software industry followed the notion that architecture was something that
ought to be developed and completed before writing the first line of code. Inspired by the
construction industry, it was felt that the sign of a successful software architecture was
something that didn’t need to change during development, often a reaction to the high costs of
scrap and rework that would occur due to a re-architecture event.
This vision of architecture was rudely challenged by the rise of agile software methods. The
preplanned architecture approach was founded on the notion that requirements should also be
fixed before coding began, leading to a phased (or waterfall) approach where requirements were
followed by architecture which itself was followed by construction (programming). The agile
world, however, challenged the very notion of fixed requirements, observing that regular
changes in requirements were a business necessity in the modern world and providing project
planning techniques to embrace controlled change.
In this new agile world, many people questioned the role of architecture. And certainly the
preplanned architecture vision couldn’t fit in with modern dynamism. But there is another
approach to architecture, one that embraces change in the agile manner. In this perspective,
architecture is a constant effort, one that works closely with programming so that architecture
can react both to changing requirements and to feedback from programming. We’ve come to call
this evolutionary architecture, to highlight that while the changes are unpredictable, the
architecture can still move in a good direction.
At Thoughtworks, we’ve been immersed in this architectural worldview. Rebecca led many of
our most important projects in the early years of this millennium and developed our technical
leadership as our CTO. Neal has been a careful observer of our work, synthesizing and
conveying the lessons we’ve learned. Pat has combined his project work with developing our
technical leads. We’ve always felt that architecture is vitally important and can’t be left to idle
chance. We’ve made mistakes, but we’ve learned from them, growing a better understanding of
how to build a codebase that can respond gracefully to the many changes in its purpose.
The heart of doing evolutionary architecture is to make small changes and put in feedback loops
that allow everyone to learn from how the system is developing. The rise of Continuous Delivery
has been a crucial enabling factor in making evolutionary architecture practical. The authorial
trio use the notion of fitness functions to monitor the state of the architecture. They explore
different styles of evolvability for architecture and emphasize the issues around long-lived data
—often a topic that gets neglected. Conway’s Law towers over much of the discussion, as it
should.
While I’m sure we have much to learn about doing software architecture in an evolutionary style,
this book marks an essential road map for the current state of understanding. As more people are
realizing the central role of software systems in our 21st-century human world, knowing how
best to respond to change while keeping on your feet will be an essential skill for any software
leader.
Martin Fowler
martinfowler.com
September 2017
Foreword to the Second Edition
A metaphor attempts to describe similarities between two unrelated things in order to clarify
their essential elements. A good example of this is with software architecture. We commonly
attempt to describe software architecture by comparing it to the structure of a building. The
things that make up the structure of a building—its outer walls, inner walls, roof, room size,
number of floors, even the location of the building—all relate to structural elements of software
architecture—databases, services, communication protocols, interfaces, deployment location
(cloud, on-premises), and so on. The old view is that in both cases these are things that, once in
place, are very hard to change later. And that’s exactly where the building metaphor breaks
down.
Today, the building metaphor for software architecture is no longer a valid one. While it’s still
useful to explain what software architecture is to a nontechnical person in terms of comparing the
structure of a system, software architecture must be malleable enough to change quickly, which
is very different from a physical building. Why must software architecture be so malleable?
Because businesses are in a constant state of rapid change, undergoing mergers, acquisitions,
new business lines, cost-cutting measures, organizational structures, and so on. However, so is
technology, with new frameworks, technical environments, platforms, and products. To properly
align with the business and technology environment, software architecture must change as well,
and at the same rapid pace. A good example is a major acquisition by a large company. Aside
from the myriad business concerns and changes, the software architectures supporting the major
business applications must be able to scale to meet the additional customer base and must be
both adaptable and extensible to accommodate new business functionality and practices.
Many companies already know this but struggle with one thing: how do you make software
architecture malleable enough to withstand a fast rate of business and technology change? The
answers are found in this book you are about to read. This second edition builds on the concepts
of guided and incremental change introduced in the first edition to provide you with the latest
techniques, knowledge, and tips on fitness functions, automated architectural governance, and
evolutionary data to make sure your software architectures are agile enough to keep up with the
constant change we are all experiencing today.
Mark Richards
developertoarchitect.com
October 2022
Preface
When we wrote the first edition of Building Evolutionary Architectures in 2017, the idea of
evolving software architecture was still somewhat radical. During one of her first presentations
about the subject, Rebecca was approached afterward by someone accusing her of being
professionally irresponsible for suggesting that software architecture can evolve over time—after
all, the architecture is the thing that never changes.
However, as reality teaches us, systems must evolve to meet new demands of their users and to
reflect changes in the constantly shifting software development ecosystem.
When the first edition was published, few tools existed to take advantage of the techniques we
describe. Fortunately, the software development world keeps evolving, including many more
tools to make building evolutionary architectures easier.
The Structure of This Book
We changed the structure from the first edition to more clearly delineate the two main topics: the
engineering practices for evolving software systems and the structural approaches that make it
easier.
In Part I, we define the various mechanisms and engineering practices that teams can use to
implement the goals of evolutionary architecture, including techniques, tools, categories, and
other information readers need to understand this topic.
Software architecture also involves structural design, and some design decisions make evolution
(and governance) easier. We cover this in Part II, which also includes coverage of architecture
styles as well as design principles around coupling, reuse, and other pertinent structural
considerations.
Virtually nothing in software architecture exists in isolation; many principles and practices in
evolutionary architecture involve the holistic entanglement of many parts of the software
development process, which we cover in Part III.
Case Studies and PenultimateWidgets
We highlight a number of case studies in this book. All four authors were (and some still are)
consultants while working on the material in this book, and we used our real-world experience to
derive many of the case studies that appear here. While we can’t divulge the details for particular
clients, we wanted to provide some relevant examples to make the topic less abstract. Thus, we
adopted the idea of a surrogate company, PenultimateWidgets, as the “host” for all our case
studies.
In the second edition, we also solicited case studies from our colleagues, which further highlight
examples of applying the techniques we discuss. Throughout the book, each case study appears
as one from PenultimateWidgets, but each comes from a real project.
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program elements such as
variable or function names, databases, data types, environment variables, statements, and
keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values determined by
context.
TIP
This element signifies a tip or suggestion.
NOTE
This element signifies a general note.
WARNING
This element indicates a warning or caution.
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
http://evolutionaryarchitecture.com.
If you have a technical question or a problem using the code examples, please send email to
bookquestions@oreilly.com.
This book is here to help you get your job done. In general, if example code is offered with this
book, you may use it in your programs and documentation. You do not need to contact us for
permission unless you’re reproducing a significant portion of the code. For example, writing a
program that uses several chunks of code from this book does not require permission. Selling or
distributing examples from O’Reilly books does require permission. Answering a question by
citing this book and quoting example code does not require permission. Incorporating a
significant amount of example code from this book into your product’s documentation does
require permission.
We appreciate, but generally do not require, attribution. An attribution usually includes the title,
author, publisher, and ISBN. For example: “Building Evolutionary Architectures, 2nd edition, by
Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage (O’Reilly). Copyright 2023
Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage, 978-1-492-09754-9.”
If you feel your use of code examples falls outside fair use or the permission given above, feel
free to contact us at permissions@oreilly.com.
O’Reilly Online Learning
NOTE
For more than 40 years, O’Reilly Media has provided technology and business training, knowledge, and insight to
help companies succeed.
Our unique network of experts and innovators share their knowledge and expertise through
books, articles, and our online learning platform. O’Reilly’s online learning platform gives you
on-demand access to live training courses, in-depth learning paths, interactive coding
environments, and a vast collection of text and video from O’Reilly and 200+ other publishers.
For more information, visit https://oreilly.com.
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at https://oreil.ly/evolutionary-arch-2e.
Email bookquestions@oreilly.com to comment or ask technical questions about this book.
For news and information about our books and courses, visit https://oreilly.com.
Find us on LinkedIn: https://linkedin.com/company/oreilly-media.
Follow us on Twitter: https://twitter.com/oreillymedia.
Watch us on YouTube: https://youtube.com/oreillymedia.
Additional Information
The authors maintain a companion website for this book at http://evolutionaryarchitecture.com.
Acknowledgments
The authors would like to give vociferous thanks to our colleagues who provided the outlines
and inspirations for the many fitness function case studies presented within. In no particular
order, thanks to Carl Nygard, Alexandre Goedert, Santhoshkumar Palanisamy, Ravi Kumar
Pasumarthy, Indhumathi V., Manoj B. Narayanan, Neeraj Singh, Sirisha K., Gireesh Chunchula,
Madhu Dharwad, Venkat V., Abdul Jeelani, Senthil Kumar Murugesh, Matt Newman, Xiaojun
Ren, Archana Khanal, Heiko Gerin, Slin Castro, Fernando Tamayo, Ana Rodrigo, Peter Gillard-
Moss, Anika Weiss, Bijesh Vijayan, Nazneen Rupawalla, Kavita Mittal, Viswanath R., Dhivya
Sadasivam, Rosi Teixeira, Gregorio Melo, Amanda Mattos, and many others whose names we
failed to capture.
Neal would like to thank all the attendees of the various conferences at which he has spoken over
the last few years to help hone and revise this material in person and especially online, due to the
unusual circumstances of a global pandemic. Thanks to all the front-line workers who stepped up
bravely to help us all through this difficult time. He would also like to thank the technical
reviewers who went above and beyond to provide excellent feedback and advice. Neal would
also like to thank his cats, Amadeus, Fauci, and Linda Ruth, for providing useful distractions that
often led to insights. Cats never dwell on the past or future; they are always in the current
moment, so he uses his time with them to join their presence in the here and now. Thanks also to
our outdoor neighborhood “cocktail club,” which started as a community way to see friends and
has evolved into the neighborhood brain trust. And finally, Neal would like to thank his long-
suffering wife, who endures his travel, and then the abrupt absence of travel, and other
professional indignities with a smile.
Rebecca would like to thank all the colleagues, conference attendees and speakers, and authors
who have, over the years, contributed ideas, tools, and methods and asked clarifying questions
about the field of evolutionary architecture. She echoes Neal’s thanks to the technical reviewers
for their careful reading and commentary. Further, Rebecca would like to thank her coauthors for
all the enlightening conversations and discussions while working together on this book. In
particular, she thanks Neal for the great discussion, or perhaps debate, they had several years ago
regarding the distinction between emergent and evolutionary architecture. These ideas have
come a long way since that first conversation.
Patrick would like to thank all his colleagues and customers at ThoughtWorks, who have driven
the need and provided the test bed to articulate the ideas in building evolutionary architecture. He
also would like to echo Neal’s and Rebecca’s thanks to the technical reviewers, whose feedback
helped to improve the book immensely. Finally, he would like to thank his coauthors for the past
several years and for the opportunity to work closely together on this topic, despite the numerous
time zones and flights that made meeting in person the rare occasion.
Pramod would like to thank all his colleagues and clients who have always provided the space
and time to explore new ideas and to push new ideas and thinking. He would like to thank his
coauthors for thoughtful discussions ensuring that all aspects of architecture are considered. He
also would like to thank the reviewers—Cassandra Shum, Henry Matchen, Luca Mezzalira, Phil
Messenger, Vladik Khononov, Venkat Subramanium, and Martin Fowler—for thoughtful
comments that helped the authors immensely. And finally, he would like to thank his daughters,
Arula and Arhana, for the joy they bring into his life, and his wife, Rupali, for all her love and
support.
Part I. Mechanics
Evolutionary architecture consists of broad areas of inquiry: mechanics and structure.
The mechanics of evolutionary architecture concern the engineering practices and verification
that allow an architecture to evolve, which overlap architectural governance. This covers
engineering practices, testing, metrics, and a host of other moving parts that make evolving
software possible. Part I defines and presents numerous examples of the mechanics of
evolutionary architecture.
The other aspect of Building Evolutionary Architectures concerns the structure or topology of
software systems. Do some architecture styles better facilitate building systems that are easier to
evolve? Are there structural decisions in architecture that should be avoided to make evolution
easier? We answer these and other questions in Part II, which concerns structuring architecture
for evolution.
Many of the facets of building evolutionary architectures combine both mechanics and structure;
Part III of the book is titled “Impact.” It includes many case studies, provides advice, and covers
patterns and antipatterns as well as other considerations architects and teams need to be aware of
to make evolution possible.
Chapter 1. Evolving Software
Architecture
Building systems that age gracefully and effectively is one of the enduring challenges of
software development generally and software architecture specifically. This book covers two
fundamental aspects of how to build evolvable software: utilizing effective engineering practices
derived from the agile software movement and structuring architecture to facilitate change and
governance.
Readers will grow to understand the state of the art in how to manage change in architecture in a
deterministic way, unifying previous attempts at providing protection for architecture
characteristics and actionable techniques to improve the ability to change architecture without
breaking it.
The Challenges of Evolving Software
bit rot: also known as software rot, code rot, software erosion, software decay, or software
entropy, is either a slow deterioration of software quality over time or its diminishing
responsiveness that will eventually lead to software becoming faulty.
Teams have long struggled with building high-quality software that remains high quality over
time, including adages that reflect this difficulty, such as the varied definitions of bit rot shown
above. At least two factors drive this struggle: the problems of policing all the various moving
parts in complex software, and the dynamic nature of the software development ecosystem.
Modern software consists of thousands or millions of individual parts, each of which may be
changed along some set of dimensions. Each of those changes has predictable and sometimes
unpredictable effects. Teams that attempt manual governance eventually become overwhelmed
by the sheer volume of parts and combinatorial side effects.
Managing the myriad interactions of software would be bad enough against a static backdrop,
but that doesn’t exist. The software development ecosystem consists of all the tools, frameworks,
libraries, and best practices—the accumulated state of the art in software development at any
given snapshot in time. This ecosystem forms an equilibrium—much like a biological system—
that developers can understand and build things within. However, that equilibrium is dynamic—
new things come along constantly, initially upsetting the balance until a new equilibrium
emerges. Visualize a unicyclist carrying boxes: dynamic because the unicyclist continues to
adjust to stay upright, and equilibrium because they continue to maintain balance. In the software
development ecosystem, each new innovation or practice may disrupt the status quo, forcing the
establishment of a new equilibrium. Metaphorically, we keep tossing more boxes onto the
unicyclist’s load, forcing them to reestablish balance.
In many ways, architects resemble our hapless unicyclist, constantly both balancing and adapting
to changing conditions. The engineering practices of Continuous Delivery represent such a
tectonic shift in the equilibrium: incorporating formerly siloed functions such as operations into
the software development lifecycle enabled new perspectives on what change means. Enterprise
architects can no longer rely on static, five-year plans because the entire software development
universe will evolve in that time frame, rendering every long-term decision potentially moot.
Disruptive change is hard to predict even for savvy practitioners. The rise of containers via tools
like Docker is an example of an unknowable industry shift. However, we can trace the rise of
containerization via a series of small, incremental steps. Once upon a time, operating systems,
application servers, and other infrastructure were commercial entities, requiring licensing and
great expense. Many of the architectures designed in that era focused on efficient use of shared
resources. Gradually, Linux became good enough for many enterprises, reducing the monetary
cost of operating systems to zero. Next, DevOps practices like automatic machine provisioning
via tools like Puppet and Chef made Linux operationally free. Once the ecosystem became free
and widely used, consolidation around common portable formats was inevitable: thus, Docker.
But containerization couldn’t have happened without all the evolutionary steps leading to that
end.
The software development ecosystem constantly evolves, which leads to new architectural
approaches. While many developers suspect that a cabal of architects retreat to an ivory tower to
decide what the Next Big Thing will be, the process is much more organic. New capabilities
constantly arise within our ecosystem, providing new ways to combine with existing and other
new features to enable new capabilities. For example, consider the recent rise of microservices
architectures. As open source operating systems became popular, combined with Continuous
Delivery–driven engineering practices, enough clever architects figured out how to build more
scalable systems that they eventually needed a name: thus, microservices.
WHY WE DIDN’T HAVE MICROSERVICES IN THE YEAR 2000
Consider an architect with a time machine who travels back in time to the year 2000 and
approaches the head of operations with a new idea.
“I have a great new concept for an architecture that allows fantastic isolation between each of
the capabilities—it’s called microservices; we’ll design each service around business
capabilities and keep things highly decoupled.”
“Great,” says the head of operations. “What do you need?”
“Well, I’m going to need about 50 new computers, and of course 50 new operating system
licenses, and another 20 computers to act as isolated databases, along with licenses for those.
When do you think I can get all that?”
“Please leave my office.”
While microservices might have seemed like a good idea even back then, the ecosystem
wasn’t available to support it.
A portion of an architect’s job is structural design to solve particular problems—you have a
problem, and you’ve decided that software will solve it. When considering structural design, we
can partition it into two areas: the domain (or requirements) and architecture characteristics, as
illustrated in Figure 1-1.
Figure 1-1. The entire scope of software architecture encompasses requirements plus architecture characteristics: the “-ilities”
of software
The requirements shown in Figure 1-1 represent whatever problem domain the software solution
addresses. The other parts are variously known as architecture characteristics (our preferred
term), nonfunctional requirements, system quality attributes, cross-cutting requirements, and a
host of other names. Regardless of the name, they represent critical capabilities required for
project success, both for initial release and long-term maintainability. For example, architecture
characteristics such as scale and performance may form success criteria for a market, whereas
others such as modularity contribute to maintainability and evolvability.
THE MANY NAMES OF ARCHITECTURE CHARACTERISTICS
We use the term architecture characteristics throughout the book to refer to nondomain
design considerations. However, many organizations use other terms for this concept, among
them nonfunctional requirements, cross-cutting requirements, and system quality attributes.
We don’t have a strong preference for one term over another—feel free to translate our term
to yours anywhere you see it in the book. These are not distinct concepts.
Software is rarely static; it continues to evolve as teams add new features, integration points, and
a host of other common changes. What architects need are protection mechanisms for
architecture characteristics, similar to unit tests but focused on architecture characteristics, which
change at a different rate and are sometimes subject to forces that are different from the domain.
For example, technical decisions within a company may drive a database change that is
independent of the domain solution.
This book describes the mechanisms and design techniques for adding the same kind of continual
assurance about architectural governance that high-performing teams now have about other
aspects of the software development process.
Architectural decisions are ones in which each choice offers significant trade-offs. Throughout
this book, when we refer to the role of architect, we encompass anyone who makes architectural
decisions, regardless of their title in an organization. Additionally, important architecture
decisions virtually always require collaboration with other roles.
DO AGILE PROJECTS NEED ARCHITECTURE?
This is a common question asked of those who have utilized agile engineering practices for a
while. The goal of agility is to remove useless overhead, not necessary steps such as design.
As in many things in architecture, the scale dictates the level of architecture. We use the
analogy of building—if we want to build a dog house, we don’t need an elaborate
architecture; we just need materials. On the other hand, if we need to build a 50-story office
building, design must occur. Similarly, if we need a website to track a simple database, we
don’t need an architecture; we can find materials that enable us to piece it together. However,
we must carefully consider many trade-offs to design a highly scalable and available website,
such as a high-volume concert ticketing website.
Rather than the question Do Agile projects need architecture?, the question for architects lies
in how little unnecessary design they can afford, while building the ability to iterate on early
designs to work toward more suitable solutions.
Evolutionary Architecture
Both the mechanisms for evolution and the decisions architects make when designing software
derive from the following definition:
An evolutionary software architecture supports guided, incremental change across multiple
dimensions.
The definition consists of three parts, which we describe in more detail below.
Guided Change
Once teams have chosen important characteristics, they want to guide changes to the architecture
to protect those characteristics. For that purpose, we borrow a concept from evolutionary
computing called fitness functions. A fitness function is an objective function used to summarize
how close a prospective design solution is to achieving the set aims. In evolutionary computing,
the fitness function determines whether an algorithm has improved over time. In other words, as
each variant of an algorithm is generated, the fitness functions determine how “fit” each variant
is, based on how the designer of the algorithm defined “fit.”
We have a similar goal in evolutionary architecture: as architecture evolves, we need
mechanisms to evaluate how changes impact the important characteristics of the architecture and
prevent degradation of those characteristics over time. The fitness function metaphor
encompasses a variety of mechanisms we employ to ensure architecture doesn’t change in
undesirable ways, including metrics, tests, and other verification tools. When an architect
identifies an architectural characteristic they want to protect as things evolve, they define one or
more fitness functions to protect that feature.
Historically, a portion of architecture has often been viewed as a governance activity, and
architects have only recently accepted the notion of enabling change through architecture.
Architectural fitness functions allow decisions in the context of the organization’s needs and
business functions, while making the basis for those decisions explicit and testable. Evolutionary
architecture is not an unconstrained, irresponsible approach to software development. Rather, it
is an approach that balances the need for rapid change and the need for rigor around systems and
architectural characteristics. The fitness function drives architectural decision making, guiding
the architecture while allowing the changes needed to support changing business and technology
environments.
We use fitness functions to create evolutionary guidelines for architectures; we cover them in
detail in Chapter 2.
Incremental Change
Incremental change describes two aspects of software architecture: how teams build software
incrementally and how they deploy it.
During development, an architecture that allows small, incremental changes is easier to evolve
because developers have a smaller scope of change. For deployment, incremental change refers
to the level of modularity and decoupling for business features and how they map to architecture.
An example is in order.
Let’s say that PenultimateWidgets, a large seller of widgets, has a catalog page backed by a
microservices architecture and modern engineering practices. One of the page’s features enables
users to rate different widgets with star ratings. Other services within PenultimateWidgets’
business also need ratings (customer service representatives, shipping provider evaluation, etc.),
so they all share the star rating service. One day, the star rating team releases a new version
alongside the existing one that allows half-star ratings—a small but significant upgrade. The
other services that require ratings aren’t required to move to the new version but to gradually
migrate as convenient. Part of PenultimateWidgets’ DevOps practices include architectural
monitoring of not only the services but also the routes between services. When the operations
group observes that no one has routed to a particular service within a given time interval, they
automatically disintegrate that service from the ecosystem.
This is an example of incremental change at the architectural level: the original service can run
alongside the new one as long as other services need it. Teams can migrate to new behavior at
their leisure (or as need dictates), and the old version is automatically garbage collected.
Making incremental change successful requires coordination of a handful of Continuous
Delivery practices. Not all of these practices are required in all cases; rather, they commonly
occur together in the wild. We discuss how to achieve incremental change in Chapter 3.
Multiple Architectural Dimensions
There are no separate systems. The world is a continuum. Where to draw a boundary around
a system depends on the purpose of the discussion.
—Donella H. Meadows
Classical Greek physicists gradually learned to analyze the universe based on fixed points,
culminating in classical mechanics. However, more precise instruments and more complex
phenomena gradually refined that definition toward relativity in the early 20th century. Scientists
realized that what they previously viewed as isolated phenomena in fact interact relative to one
another. Since the 1990s, enlightened architects have increasingly viewed software architecture
as multidimensional. Continuous Delivery expanded that view to encompass operations.
However, software architects often focus primarily on technical architecture—how the software
components fit together—but that is only one dimension of a software project. If architects want
to create an architecture that can evolve, they must consider all the interconnected parts of the
system that change affects. Just like we know from physics that everything is relative to
everything else, architects know there are many dimensions to a software project.
To build evolvable software systems, architects must think beyond just the technical architecture.
For example, if the project includes a relational database, the structure and relationship between
database entities will evolve over time as well. Similarly, architects don’t want to build a system
that evolves in a manner that exposes a security vulnerability. These are all examples of
dimensions of architecture—the parts of architecture that fit together in often orthogonal ways.
Some dimensions fit into what are often called architectural concerns (the list of “-ilities”
referred to earlier), but dimensions are actually broader, encapsulating things traditionally outside
the purview of technical architecture. Each project has dimensions the architect role must
consider when thinking about evolution. Here are some common dimensions that affect
evolvability in modern software architectures:
Technical
The implementation parts of the architecture: the frameworks, dependent libraries, and
implementation language(s).
Data
Database schemas, table layouts, optimization planning, and so on. The database
administrator generally handles this type of architecture.
Security
Defines security policies and guidelines, and specifies tools to help uncover deficiencies.
Operational/System
Concerns how the architecture maps to existing physical and/or virtual infrastructure: servers,
machine clusters, switches, cloud resources, and so on.
Each of these perspectives forms a dimension of the architecture—an intentional partitioning of
the parts supporting a particular perspective. Our concept of architectural dimensions
encompasses traditional architectural characteristics (“-ilities”) plus any other role that
contributes to building software. Each of these forms a perspective on architecture that we want
to preserve as our problem evolves and the world around us changes.
When architects think in terms of architectural dimensions, it provides a mechanism by which
they can analyze the evolvability of different architectures by assessing how each important
dimension reacts to change. As systems become more intertwined with competing concerns
(scalability, security, distribution, transactions, etc.), architects must expand the dimensions they
track on projects. To build an evolvable system, architects must think about how the system
might evolve across all the important dimensions.
The entire architectural scope of a project consists of the software requirements plus the other
dimensions. We can use fitness functions to protect those characteristics as the architecture and
the ecosystem evolve together through time, as illustrated in Figure 1-2.
Figure 1-2. An architecture consists of requirements and other dimensions, each protected by fitness functions
In Figure 1-2, the architects have identified auditability, data, security, performance, legality,
and scalability as the additional architectural characteristics important for this application. As the
business requirements evolve over time, each of the architectural characteristics utilizes fitness
functions to protect its integrity as well.
While the authors of this text stress the importance of a holistic view of architecture, we also
realize that a large part of evolving architecture concerns technical architecture patterns and
related topics like coupling and cohesion. We discuss how technical architecture coupling affects
evolvability in Chapter 5 and the impacts of data coupling in Chapter 6.
Coupling applies to more than just structural elements in software projects. Many software
companies have recently discovered the impact of team structure on surprising things like
architecture. We discuss all aspects of coupling in software, but the team impact comes up so
early and often that we need to discuss it here.
Evolutionary architecture helps answer two common questions that arise among architects in the
modern software development ecosystem: How is long-term planning possible when everything
changes all the time? and Once I’ve built an architecture, how can I prevent it from degrading
over time? Let’s explore these questions in more detail.
How Is Long-Term Planning Possible When Everything
Changes All the Time?
The programming platforms we use exemplify constant evolution. Newer versions of a
programming language offer better APIs to improve the flexibility of or applicability to new
problems; newer programming languages offer a different paradigm and different set of
constructs. For example, Java was introduced as a C++ replacement to ease the difficulty of
writing networking code and to improve memory management issues. When we look at the past
20 years, we observe that many languages still continually evolve their APIs while totally new
programming languages appear to regularly attack newer problems. The evolution of
programming languages is demonstrated in Figure 1-3.
Figure 1-3. The evolution of popular programming languages
Regardless of the particular aspect of software development—the programming platform,
languages, operating environment, persistence technologies, cloud offerings, and so on—we
expect constant change. Although we cannot predict when changes in the technical or domain
landscape will occur, or which changes will persist, we know change is inevitable. Consequently,
we should architect our systems knowing the technical landscape will change.
If the ecosystem constantly changes in unexpected ways, and if predictability is impossible, what
is the alternative to fixed plans? Enterprise architects and other developers must learn to adapt.
Part of the traditional reasoning behind making long-term plans was financial; software changes
were expensive. However, modern engineering practices invalidate that premise by making
change less expensive through the automation of formerly manual processes and other advances
such as DevOps.
For years, many smart developers recognized that some parts of their systems were harder to
modify than others. That’s why software architecture is defined as “the parts that are hard to
change later.” This convenient definition partitioned the things you can modify without much
effort from truly difficult changes. Unfortunately, this definition also evolved into a blind spot
when thinking about architecture: developers’ assumption that change is difficult becomes a self-
fulfilling prophecy.
Several years ago, some innovative software architects revisited the “hard to change later”
problem: what if we build changeability into the architecture? In other words, if ease of change
is a bedrock principle of the architecture, then change is no longer difficult. Building evolvability
into architecture in turn allows a whole new set of behaviors to emerge, upsetting the dynamic
equilibrium again.
Even if the ecosystem doesn’t change, what about the gradual erosion of architectural
characteristics that occurs? Architects design architectures but then expose them to the messy
real world of implementing things atop the architecture. How can architects protect the important
parts they have defined?
Once I’ve Built an Architecture, How Can I Prevent It from
Degrading Over Time?
An unfortunate decay, often called bit rot, occurs in many organizations. Architects choose
particular architectural patterns to handle the business requirements and “-ilities,” but those
characteristics often accidentally degrade over time. For example, if an architect has created a
layered architecture with presentation at the top, persistence at the bottom, and several layers in
between, developers who are working on reporting will often ask permission to directly access
persistence from the presentation layer, bypassing the other layers, for performance reasons.
Architects build layers to isolate change. Developers then bypass those layers, increasing
coupling and invalidating the reasoning behind the layers.
Once they have defined the important architectural characteristics, how can architects protect
those characteristics to ensure they don’t erode? Adding evolvability as an architectural
characteristic implies protecting the other characteristics as the system evolves. For example, if
an architect has designed an architecture for scalability, they don’t want that characteristic to
degrade as the system evolves. Thus, evolvability is a meta-characteristic, an architectural
wrapper that protects all the other architectural characteristics.
The mechanism of evolutionary architecture heavily overlaps with the concerns and goals of
architectural governance—defined principles around design, quality, security, and other quality
concerns. This book illustrates the many ways that evolutionary architecture approaches enable
automating architectural governance.
Why Evolutionary?
A common question about evolutionary architecture concerns the name itself: why call it
evolutionary architecture and not something else? Other possible terms include incremental,
continual, agile, reactive, and emergent, to name just a few. But each of these terms misses the
mark. The definition of evolutionary architecture that we state here includes two critical
characteristics: incremental and guided.
The terms continual, agile, and emergent all capture the notion of change over time, which is
clearly a critical characteristic of an evolutionary architecture, but none of these terms explicitly
captures any notion of how an architecture changes or what the desired end-state architecture
might be. While all the terms imply a changing environment, none of them covers what the
architecture should look like. The guided part of our definition reflects the architecture we want
to achieve—our end goal.
We prefer the word evolutionary over adaptable because we are interested in architectures that
undergo fundamental evolutionary change, not ones that have been patched and adapted into
increasingly incomprehensible accidental complexity. Adapting implies finding some way to
make something work regardless of the elegance or longevity of the solution. To build
architectures that truly evolve, architects must support genuine change, not jury-rigged solutions.
Going back to our biological metaphor, evolutionary concerns the process of having a system
that is fit for purpose and can survive the ever-changing environment in which it operates.
Systems may have individual adaptations, but as architects, we should care about the overall
evolvable system.
Another useful comparison architects can make is between evolutionary architecture and
emergent design, and why there is not such a thing as an “emergent architecture.” One common
misconception about agile software development is the alleged lack of architecture: “Let’s just
start coding and the architecture will emerge as we go.” However, this depends on how simple
the problem is. Consider a physical building. If you need to build a dog house, you don’t need an
architecture; you can go to the hardware store and buy lumber and bang it together. If, on the
other hand, you need to build a 50-floor office building, architecture is definitely required!
Similarly, if you are building a simple catalog system for a small number of users, you likely
don’t need a lot of up-front planning. However, if you are designing a software system that needs
strict performance for a large number of users, planning is necessary! The purpose of agile
architecture isn’t no architecture; it’s no useless architecture: don’t go through bureaucratic
processes that don’t add value to the software development process.
Another complicating factor in software architecture is the different types of essential complexity
architects must design for. When evaluating trade-offs, it’s often not the easy simple versus
complex system distinction but rather systems that are complex in different ways. In other words,
each system has a unique set of criteria for success. While we discuss architectural styles such as
microservices, each style is a starting point for a complex system that grows to look like no
other.
Similarly, if an architect builds a very simple system, they can afford to pay little attention to
architectural concerns. However, sophisticated systems require purposeful design, and they need
a starting point. Emergence suggests that you can start with nothing, whereas architecture
provides the scaffolding or structure for all the other parts of the system; something must be in
place to begin.
The concept of emergence also implies that teams can slowly crescendo their design toward the
ideal architectural solution. However, like building architecture, there is no perfect architecture,
only different ways architects deal with trade-offs. Architects can implement most problems in a
wide variety of different architecture styles and be successful. However, some of them will fit the
problem better, offering less resistance and fewer workarounds.
One key to evolutionary architecture is the balance between how much structure and governance
is necessary to support long-term goals and needless formality and friction.
Summary
Useful software systems aren’t static. They must grow and change as the problem domain
changes and the ecosystem evolves, providing new capabilities and complexities. Architects and
developers can gracefully evolve software systems, but they must understand both the necessary
engineering practices to make that happen and how best to structure their architecture to facilitate
change.
Architects are also tasked with governing the software they design, along with many of the
development practices used to build it. Fortunately, the mechanisms we uncover to allow easier
evolution also provide ways to automate important software governance activities. We take a
deep dive into the mechanics of how to make this happen in the next chapter.
Chapter 2. Fitness Functions
The mechanics of evolutionary architecture cover the tools and techniques developers and
architects use to build systems that can evolve. An important gear in that machinery is the
protection mechanism called a fitness function, the architectural equivalent of a unit test for the
domain part of an application. This chapter defines fitness functions and explains the categories
and usage of this important building block.
An evolutionary architecture supports guided, incremental change across multiple
dimensions.
As noted in our definition, the word guided indicates that some objective exists that architecture
should move toward or exhibit. We borrow a concept from evolutionary computing called fitness
functions, which are used in genetic algorithm design to define success.
Evolutionary computing includes a number of mechanisms that allow a solution to gradually
emerge via mutation—small changes in each generation of the software. The evolutionary
computing world defines a number of types of mutations. For example, one mutation is called a
roulette mutation: if the algorithm utilizes constants, this mutation will choose new numbers as if
from a roulette wheel in a casino. For example, suppose a developer is designing a genetic
algorithm to solve the traveling salesperson problem to find the shortest route between a number
of cities. If the developer notices that smaller numbers supplied by the roulette mutation yield
better results, they may build a fitness function to guide the “decision” during mutation. Thus,
fitness functions are used to evaluate how close a solution is to ideal.
What Is a Fitness Function?
We borrow this concept of fitness functions from the evolutionary computing world to define an
architectural fitness function:
An architectural fitness function is any mechanism that provides an objective integrity
assessment of some architectural characteristic(s).
Architectural fitness functions form the primary mechanisms for implementing evolutionary
architecture.
As the domain part of our solution evolves, teams have developed a wide variety of tools and
techniques to manage integrating new features without breaking existing ones: unit, functional,
and user acceptance testing. In fact, most companies bigger than a certain size have an entire
department dedicated to managing domain evolution, called quality assurance: ensuring that
existing functionality isn’t negatively affected by changes.
Thus, well-functioning teams have mechanisms for managing evolutionary change to the
problem domain: adding new features, changing behaviors, and so on. The domain is typically
written in a fairly coherent technology stack: Java, .NET, or a host of other platforms. Thus,
teams can download and use testing libraries suited to their combination of technology stacks.
Fitness functions are to architecture characteristics as unit tests are to the domain. However,
teams cannot download a single tool for the wide variety of validations possible for architecture
characteristics. Rather, fitness functions encompass a wide variety of tools in different parts of
the ecosystem, depending on the architecture characteristics the team is governing, as illustrated
in Figure 2-1.
Figure 2-1. Fitness functions encompass a wide variety of tools and techniques
As shown in Figure 2-1, architects can use many different tools to define fitness functions:
Monitors
DevOps and operational tools such as monitors allow teams to verify concerns such as
performance, scalability, and so on.
Code metrics
Architects can embed metrics checks and other verifications within unit tests to validate a
wide variety of architecture concerns, including design criteria (many examples follow in
Chapter 4).
Chaos engineering
This recently developed branch of engineering practices artificially stresses remote
environments by injecting faults to force teams to build resiliency into their systems.
Architecture testing frameworks
In recent years, testing frameworks dedicated to testing architecture structure have appeared,
allowing architects to encode a wide variety of validations into automated tests.
Security scanning
Security—even if supervised by another part of the organization—affects design decisions
that architects make and thus falls under the umbrella of concerns that architects want to
govern.
Before we define the categories of fitness functions and other factors, an example will help make
the concept less abstract. The component cycle is a common antipattern across all platforms with
components. Consider the three components in Figure 2-2.
Figure 2-2. A cycle exists when components have a cyclic dependency
Architects consider the cyclic dependency shown in Figure 2-2 an antipattern because it presents
difficulties when a developer tries to reuse one of the components—each of the entangled
components must also come along. Thus, in general, architects want to keep the number of
cycles low. However, the universe is actively fighting the architect’s desire to prevent this
problem via convenience tools. What happens when a developer references a class whose
namespace/package they haven’t referenced yet in a modern IDE? It pops up an auto-import
dialog to automatically import the necessary package.
Developers are so accustomed to this affordance that they swat it away as a reflex action, never
actually paying attention. Most of the time, auto-importing is a great convenience that doesn’t
cause any problems. However, once in a while, it creates a component cycle. How do architects
prevent this?
Consider the set of packages illustrated in Figure 2-3.
Figure 2-3. Component cycles represented as packages in Java
ArchUnit is a testing tool inspired by (and using some of the facilities of) JUnit, but it’s used to
test various architecture features, including validations to check for cycles within a particular
scope, as illustrated in Figure 2-3.
An example of how to prevent cycles using ArchUnit appears in Example 2-1.
Example 2-1. Preventing cycles using ArchUnit
public class CycleTest {
@Test
public void test_for_cycles() {
slices().
matching("com.myapp.(*)..").
should().beFreeOfCycles()
}
In this example, the testing tool “understands” cycles. An architect who wants to prevent cycles
from gradually appearing in their codebase can wire this testing into a continuous build process
and never have to worry about cycles again. We will show more examples of using ArchUnit and
similar tools in Chapter 4.
We first define fitness functions more rigorously, and then examine conceptually how they guide
the evolution of the architecture.
Don’t mistake the function part of our definition as implying that architects must express all
fitness functions in code. Mathematically speaking, a function takes an input from some allowed
set of input values and produces an output in some allowed set of output values. In software, we
also generally use the term function to refer to something implementable in code. However, as
with acceptance criteria in agile software development, the fitness functions for evolutionary
architecture may not be implementable in software (e.g., a required manual process for
regulatory reasons). An architectural fitness function is an objective measure, but architects may
implement that measure in a wide variety of ways.
As discussed in Chapter 1, real-world architecture consists of many different dimensions,
including requirements around performance, reliability, security, operability, coding standards,
and integration, to name a few. We want a fitness function to represent each requirement for the
architecture, requiring us to find (and sometimes create) ways to measure things we want to
govern. We’ll look at a few examples and then consider the different kinds of functions more
broadly.
Performance requirements make good use of fitness functions. Consider a requirement that all
service calls must respond within 100 ms. We can implement a test (i.e., fitness function) that
measures the response to a service request and fails if the result is greater than 100 ms. To this
end, every new service should have a corresponding performance test added to its test suite
(you’ll learn more about triggering fitness functions in Chapter 3). Performance is also a good
example of the vast number of ways architects can think about common measures. For example,
performance may suggest request/response timing, as measured by a mentoring tool, or another
metric such as first contentful paint, a mobile device performance metric provided by
Lighthouse. The purpose of a performance fitness function is not to measure all types of
performance but ones that architects deem important for governance.
Fitness functions also can be used to maintain coding standards. A common code metric is
cyclomatic complexity, a measure of function or method complexity available for all structured
programming languages. An architect may set a threshold for an upper value, guarded by a unit
test running in continuous integration, using one of the many tools available to evaluate that
metric.
Despite need, developers cannot always implement some fitness functions completely because of
complexity or other constraints. Consider something like a failover for a database from a hard
failure. While the recovery itself might be fully automated (and should be), triggering the test
itself is likely best done manually. Additionally, it might be far more efficient to determine the
success of the test manually, although developers should still encourage scripts and automation.
These examples highlight the myriad forms that fitness functions can take, the immediate
response to failure of a fitness function, and even when and how developers might run them.
While we can’t necessarily run a single script and say “our architecture currently has a composite
fitness score of 42,” we can have precise and unambiguous conversations about the state of the
architecture. We can also entertain discussions about the changes that might occur on the
architecture’s fitness.
Finally, when we say an evolutionary architecture is guided by the fitness function, we mean we
evaluate individual architectural choices against the individual and the system-wide fitness
functions to determine the impact of the change. The fitness functions collectively denote what
matters to us in our architecture, allowing us to make the kinds of trade-off decisions that are
both crucial and vexing during the development of software systems.
You may think, “Wait! We’ve been running code metrics as part of continuous integration for
years—this isn’t new!” You would be correct: the idea of validating parts of software as part of
an automated process is as old as automation. However, we formerly considered all the different
architecture verification mechanisms as separate—code quality versus DevOps metrics versus
security, and so on. Fitness functions unify many existing concepts into a single mechanism,
allowing architects to think in a uniform way about many existing (often ad hoc) “nonfunctional
requirements” tests. Collecting important architecture thresholds and requirements as fitness
functions allows for a more concrete representation for previously fuzzy, subjective evaluation
criteria. We leverage a large number of existing mechanisms to build fitness functions, including
traditional testing, monitoring, and other tools. Not all tests are fitness functions, but some tests
are—if the test helps verify the integrity of architectural concerns, we consider it a fitness
function.
Categories
Fitness functions exist across a variety of categories related to their scope, cadence, result,
invocation, proactivity, and coverage.
Scope: Atomic Versus Holistic
Atomic fitness functions run against a singular context and exercise one particular aspect of the
architecture. An excellent example of an atomic fitness function is a unit test that verifies some
architectural characteristic, such as modular coupling (we show an example of this type of fitness
function in Chapter 4). Thus, some application-level testing falls under the heading of fitness
functions, but not all unit tests serve as fitness functions—only the ones that verify architecture
characteristic(s). The example in Figure 2-3 represents an atomic fitness function: it checks only
for the presence of cycles between components.
For some architectural characteristics, developers must test more than each architectural
dimension in isolation. Holistic fitness functions run against a shared context and exercise a
combination of architectural aspects. Developers design holistic fitness functions to ensure that
combined features that work atomically don’t break in real-world combinations. For example,
imagine an architecture has fitness functions around both security and scalability. One of the key
items the security fitness function checks is staleness of data, and a key item for the scalability
tests is number of concurrent users within a certain latency range. To achieve scalability,
developers implement caching, which allows the atomic scalability fitness function to pass.
When caching isn’t turned on, the security fitness function passes. However, when run
holistically, enabling caching makes data too stale to pass the security fitness function, and the
holistic test fails.
We obviously cannot test every possible combination of architecture elements, so architects use
holistic fitness functions selectively to test important interactions. This selectivity and
prioritization also allows architects and developers to assess the difficulty in implementing a
particular testing scenario, thus allowing an assessment of how valuable that characteristic is.
Frequently, the interactions between architectural concerns determine the quality of the
architecture, which holistic fitness functions address.
Cadence: Triggered Versus Continual Versus Temporal
Execution cadence is another distinguishing factor between fitness functions. Triggered fitness
functions run based on a particular event, such as a developer executing a unit test, a deployment
pipeline running unit tests, or a QA person performing exploratory testing. This encompasses
traditional testing, such as unit, functional, and behavior-driven development (BDD) testing,
among others.
Continual tests don’t run on a schedule but instead execute constant verification of architectural
aspect(s), such as transaction speed. For example, consider a microservices architecture in which
the architects want to build a fitness function around transaction time—how long it takes for a
transaction to complete, on average. Building any kind of triggered test provides sparse
information about real-world behavior. Thus, architects build a continual fitness function that
simulates a transaction in production while all the other real transactions run, often using a
technique called synthetic transactions. This allows developers to verify behavior and gather real
data about the system “in the wild.”
SYNTHETIC TRANSACTIONS
How do teams measure complex, real-world interactions between services in a microservices
architecture? One common technique employs synthetic transactions. For this practice,
requests into the system have a flag that indicates that a particular transaction may be
synthetic. It follows exactly the normal course of interactions in the architecture (often
tracked via a correlation ID for forensic analysis) until the last step, where the system
evaluates the flag and doesn’t commit the transaction as a real one. This allows architects
and DevOps to learn exactly how their complex system performs.
No advice about synthetic transactions is complete without mentioning the tale of hundreds
of appliances showing up accidentally because someone forgot to flip the “synthetic” flag,
which can itself be governed by a fitness function—make sure that any fitness function
identified as a synthetic transaction (e.g., via an annotation) has the flag set.
Notice that using a monitoring tool does not imply that you have a fitness function, which must
have objective outcomes. Rather, using a monitoring tool in which the architect has created an
alarm for deviations outside the objective measure of the metric converts the mere use of
monitors into a fitness function.
Monitoring-driven development (MDD) is another testing technique gaining popularity. Rather
than relying solely on tests to verify system results, MDD uses monitors in production to assess
both technical and business health. These continual fitness functions are necessarily more
dynamic than standard triggered tests and fall into the broader category called fitness function-
driven architecture, discussed in more detail in Chapter 7.
While most fitness functions trigger either on change or continually, in some cases architects
may want to build a time component into assessing fitness, leading to a temporal fitness
function. For example, if a project uses an encryption library, the architect may want to create a
temporal fitness function as a reminder to check if important updates have been performed.
Another common use of this type of fitness function is a break upon upgrade test. In platforms
like Ruby on Rails, some developers can’t wait for the tantalizing new features coming in the
next release, so they add a feature to the current version via a back port, a custom
implementation of a future feature. Problems arise when the project finally upgrades to the new
version because the back port is often incompatible with the “real” version. Developers use
break upon upgrade tests to wrap back-ported features to force re-evaluation when the upgrade
occurs.
Another common use of a temporal fitness function comes from an important but not urgent
requirement that arises on virtually every project eventually. Many developers have experienced
the pain of upgrading more than one major version number of a core framework or library their
project depends upon—so many changes occur between major point releases, it’s often quite
difficult to leap versions. However, upgrading a core framework is time-consuming and not
deemed as critical, making it more likely to accidentally slip too far behind. Architects can use a
temporal fitness function in conjunction with a tool like Dependabot or snyk, which tracks
releases, versions, and security patches for software, to create increasingly insistent reminders to
upgrade once the corporate criteria (e.g., first patch release) have been met.
Case Study: Triggered or Continuous?
Often the choice of continuous versus triggered fitness function comes down to trade-offs
between the approaches. Many developers in distributed systems such as microservices want the
same kind of dependency check but on allowed communication between services rather than
cycles. Consider the set of services illustrated in Figure 2-4, a more advanced version of the
cyclic dependency fitness function shown in Figure 2-3.
Figure 2-4. Set of orchestrated microservices, where communication should not exist between nonorchestrator services
In Figure 2-4, the architect has designed the system so that the orchestrator service contains the
state of the workflow. If any of the services communicates with each other, bypassing the
orchestrator, the team won’t have accurate information about the workflow state.
In the case of dependency cycles, metrics tools exist to allow architects to do compile-time
checks. However, services aren’t constrained to a single platform or technology stack, making it
highly unlikely that someone has already built a tool that exactly matches a particular
architecture. This is an example of what we alluded to earlier—often, architects must build their
own tools rather than rely on third parties. For this particular system, the architect can build
either a continuous or a triggered fitness function.
In the continuous case, the architect must ensure that each of the services provides monitoring
information (typically via a particular port) that broadcasts who the service calls during the
course of workflows. Either the orchestrator service or a utility service monitors those messages
to ensure that illegal communication doesn’t occur. Alternatively, rather than using monitors, the
team could use asynchronous message queues, have each domain service publish a message to
the queue indicating collaboration messages, and allow the orchestrator to listen to that queue
and validate collaborators. This fitness function is continuous because the receiving service can
react immediately to disallowed communication. For example, perhaps this fault indicates a
security concern or other detrimental side effect.
The benefit of this version of the fitness function is immediate reaction: architects and other
interested parties know immediately when governance has been violated. However, this solution
adds runtime overhead: monitors and/or message queues require operation resources, and this
level of observability may have a negative impact on performance, scalability, and so on.
Alternatively, the team may decide to implement a triggered version of this fitness function. In
this case, on a regular cadence, the deployment pipeline calls a fitness function that harvests
logfiles and investigates communication to determine if it is all appropriate. We show an
implementation of this fitness function in “Communication Governance in Microservices”. The
benefit of this fitness function is lack of possible runtime impact—it runs only when triggered
and looks at log records. However, teams shouldn’t use a triggered version for critical
governance issues such as security where the time lag may have negative impacts.
As in all things in software architecture, the decision between triggered and continuous fitness
functions will often provide different trade-offs, making this a case-by-case decision.
Result: Static Versus Dynamic
Static fitness functions have a fixed result, such as the binary pass/fail of a unit test. This type
encompasses any fitness function that has a predefined desirable value: binary, a number range,
set inclusion, and so on. Metrics are often used for fitness functions. For example, an architect
may define acceptable ranges for average cyclomatic complexity of methods in the codebase.
Dynamic fitness functions rely on a shifting definition based on extra context, often real-time
content. For example, consider a fitness function to verify scalability along with request/response
responsiveness for a number of users. As the number of concurrent users rises, the architects will
allow responsiveness to degrade slightly, but they don’t want it to degrade past the point where it
will become a problem. Thus, a responsiveness fitness function will take into account the number
of concurrent users and adjust the evaluation accordingly.
Notice that dynamic and objective do not conflict—fitness functions must evaluate to an
objective outcome, but that evaluation may be based on dynamic information.
Invocation: Automated Versus Manual
Architects like automated things—part of incremental change includes automation, which we
delve into deeply in Chapter 3. Thus, it’s not surprising that developers will execute most fitness
functions within an automated context: continuous integration, deployment pipelines, and so on.
Indeed, developers and DevOps have performed a tremendous amount of work under the
auspices of Continuous Delivery to automate many parts of the software development ecosystem
previously thought impossible.
However, as much as we’d like to automate every single aspect of software development, some
parts of software development resist automation. Sometimes architects cannot automate away a
critical dimension within a system, such as legal requirements or exploratory testing, which leads
to manual fitness functions. Similarly, a project may have aspirations to become more
evolutionary but not yet have appropriate engineering practices in place. For example, perhaps
most QA is still manual on a particular project and must remain so for the near future. In both of
these cases (and others), we need manual fitness functions that are verified by a person-based
process.
The path to better efficiency eliminates as many manual steps as possible, but many projects still
require manual procedures. We still define fitness functions for those characteristics and verify
them using manual stages in deployment pipelines (covered in more detail in Chapter 3).
Proactivity: Intentional Versus Emergent
While architects will define most fitness functions at project inception as they elucidate the
characteristics of the architecture, some fitness functions will emerge during development of the
system. Architects never know all the important parts of the architecture at the beginning (the
classic unknown unknowns problem we address in Chapter 7), and thus must identify fitness
functions as the system evolves. Architects write intentional fitness functions at project inception
and as part of a formal governance process, sometimes in collaboration with other architect roles
such as enterprise architects.
Fitness functions not only verify the initial assumptions by architects on projects, but they also
provide ongoing governance. Thus, it’s common for architects to notice some behavior that
would benefit from better governance, leading to an emergent fitness function. Architects should
keep a wary eye open for misbehavior in a project, especially those that can be verified via
fitness functions, and add them aggressively.
These two sometimes form a spectrum, beginning as intentional protection for some aspect but
evolving into a more nuanced or even different fitness function over time. Just like unit tests,
fitness functions become part of the team’s codebase. Thus, as architectural requirements change
and evolve, the corresponding fitness functions must change similarly.
Coverage: Domain-Specific Fitness Functions?
We are sometimes asked if some particular problem domains tend toward certain architectural
fitness functions. While nothing is impossible in software architecture and you might use the
same automated testing framework to implement some fitness functions, generally fitness
functions are used only for abstract architectural principles, not with the problem domain. What
we see in practice if you use the same test automation tools is a separation of tests. One set of
tests will focus on testing domain logic (e.g., traditional unit or end-to-end tests) and another set
of tests on fitness functions (e.g., performance or scalability tests).
This separation is utilitarian to avoid duplication and misguided effort. Remember, fitness
functions are another verification mechanism in projects and are meant to coexist alongside other
(domain) verifications. To avoid duplicating efforts, teams are wise to keep fitness functions to
pure architecture concerns and allow the other verifications to handle domain issues. For
example, consider elasticity, which describes a website’s ability to handle sudden bursts of users.
Notice that we can talk about elasticity in purely architectural terms—the website in question
could be a gaming site, a catalog site, or a streaming movie site. Thus, this part of the
architecture is governed by a fitness function. In contrast, if a team needed to verify something
like a change of address, that requires domain knowledge and would fall to traditional
verification mechanisms. Architects can use this as a litmus test to determine where the
verification responsibility lies.
Thus, even within common domains (such as finance), it is difficult to predict a standard set of
fitness functions. What each team ultimately views as important and valuable varies to an
annoyingly wide degree between teams and projects.
Who Writes Fitness Functions?
Fitness functions represent the architectural analog to unit tests and should be treated similarly in
terms of development and engineering practices. In general, architects write fitness functions as
they determine the objective measures for important architecture characteristics. Both architects
and developers maintain the fitness functions, including preserving a passing state at all times—
passing fitness functions are an objective measure of an architecture’s fitness.
Architects must collaborate with developers in the definition and understanding of both the
purpose and utility of fitness functions, which add an extra layer of verification to the overall
quality of the system. As such, they will occasionally fail as changes violate governance rules—a
good thing! However, developers must understand the purpose of the fitness function so that they
can repair the fault and continue the build process. Collaboration between the two roles is critical
so that developers don’t misunderstand the governance as a burden rather than a useful constraint
to preserve important features.
TIP
Keep knowledge of key and relevant fitness functions alive by posting the results of executing fitness functions
somewhere visible or in a shared space so that developers remember to consider them in day-to-day coding.
Where Is My Fitness Function Testing Framework?
For testing the problem domain, developers have a wide variety of platform-specific tools
because the domain is purposefully written in a particular platform/technology stack. For
example, if the primary language is Java, developers can choose from a wide array of unit,
functional, user acceptance, and other testing tools and frameworks. Consequently, architects
look for the same level of “turnkey” support for architecture fitness functions—which generally
doesn’t exist. We cover a few easy-to-download-and-run fitness function tools in Chapter 4, but
such tools are sparse compared to domain testing libraries. This is due mostly to the highly
varied nature of fitness functions, as illustrated in Figure 2-1: operational fitness functions
require monitoring tools, security fitness functions require scanning tools, quality checks require
code-level metrics, and so on. In many cases, a particular tool doesn’t exist for your particular
blend of architectural forces. However, as we illustrate in future chapters, architects can use a bit
of programming “glue” to compose useful fitness functions with little effort, just not as little as
downloading a prebuilt framework.
Outcomes Versus Implementations
It is important for architects to focus on the outcomes—the objective measures for architecture
characteristics—rather than implementation details. Architects often write fitness functions in
technology stacks other than the main domain platform, or utilize DevOps tools or any other
convenient process that enables them to objectively measure something of interest. The
important metaphorical analogy with function in the term fitness function implies something that
takes inputs and produces outputs without side effects. Similarly, a fitness function measures an
outcome—an objective evaluation of some architecture characteristic.
Throughout the book, we show examples of fitness function implementations, but it is important
for readers to focus on the outcome and why we measure something rather than how an architect
makes a particular measurement.
PENULTIMATEWIDGETS AND THE ENTERPRISE ARCHITECTURE
SPREADSHEET
When the architects for PenultimateWidgets decided to build a new project platform, they
first created a spreadsheet of all the desirable characteristics: scalability, security, resiliency,
and a host of other “-ilities.” But then they faced an age-old question: if they built the new
architecture to support those features, how can they ensure it maintains that support? As
developers add new features, how would they keep unexpected degradation of these
important characteristics from occurring?
The solution was to create fitness functions for each of the concerns in the spreadsheet,
reformulating some of them to meet objective evaluation criteria. Rather than occasional, ad
hoc verification of their important criteria, they wired the fitness functions into their
deployment pipeline (discussed more fully in Chapter 3).
Although software architects are interested in exploring evolutionary architectures, we aren’t
attempting to model biological evolution. Theoretically, we could build an architecture that
randomly changed one of its bits (mutation) and redeployed itself. After a few million years, we
would likely have a very interesting architecture. However, we don’t have millions of years to
wait.
We want our architecture to evolve in a guided way, so we place constraints on different aspects
of the architecture to rein in undesirable evolutionary directions. A good example is dog
breeding: by selecting the characteristics we want, we can create a vast number of differently
shaped canines in a relatively short amount of time.
We can also think about the system-wide fitness function as a collection of fitness functions with
each function corresponding to one or more dimensions of the architecture. Using a system-wide
fitness function aids our understanding of necessary trade-offs when individual elements of the
fitness function conflict with one another. As is common with multifunction optimization
problems, we might find it impossible to optimize all values simultaneously, forcing us to make
choices. For example, in the case of architectural fitness functions, issues like performance might
conflict with security due to the cost of encryption. This is a classic example of the bane of
architects everywhere—the trade-off. Trade-offs dominate much of an architect’s headaches
during the struggle to reconcile opposing forces, such as scalability and performance. However,
architects have a perpetual problem of comparing these different characteristics because they
fundamentally differ (an apples to oranges comparison) and all stakeholders believe their
concern is paramount. System-wide fitness functions allow architects to think about divergent
concerns using the same unifying mechanism of fitness functions, capturing and preserving the
important architectural characteristics. The relationship between the system-wide fitness function
and its constituent smaller fitness functions is illustrated in Figure 2-5.
Figure 2-5. System-wide versus individual fitness functions
The system-wide fitness function is crucial for an architecture to be evolutionary, as we need
some basis to allow architects to compare and evaluate architectural characteristics against one
another. Unlike with the more directed fitness functions, architects likely will never try to
“evaluate” the system-wide fitness function. Rather, it provides guidelines for prioritizing
decisions about the architecture in the future. While fitness functions may not help resolve the
trade-off, they help architects more clearly understand the forces at play, with objective
measures, so that they can reason about the necessary system-wide trade-offs.
A system is never the sum of its parts. It is the product of the interactions of its parts.
—Dr. Russel Ackoff
Without guidance, evolutionary architecture becomes simply reactionary architecture. Thus, for
architects, a crucial early architectural decision for any system is to define important dimensions
such as scalability, performance, security, data schemas, and so on. Conceptually, this allows
architects to weigh the importance of a fitness function based on its importance to the system’s
overall behavior.
Summary
The original seed of the idea of applying fitness functions to software architecture occurred to
Rebecca when she realized she could use some of her experience derived from another technical
domain (evolutionary computing) and apply it to software: fitness functions. Architects have
verified parts of architecture forever, but they haven’t previously unified all the different
verification techniques into a single overarching concept. Treating all these different governance
tools and techniques as fitness functions allows teams to unify around execution.
We cover more aspects of operationalizing fitness functions in the next chapter.
Chapter 3. Engineering Incremental
Change
In 2010, Jez Humble and Dave Farley released Continuous Delivery, a collection of practices to
enhance engineering efficiency in software projects. They provided the mechanism for building
and releasing software via automation and tools but not the structure of how to design evolvable
software. Evolutionary architecture assumes these engineering practices as being prerequisites
but addresses how to utilize them to help design evolvable software.
Our definition of evolutionary architecture is one that supports guided, incremental change
across multiple dimensions. By incremental change, we mean the architecture should facilitate
change through a series of small changes. This chapter describes architectures that support
incremental change along with some of the engineering practices used to achieve incremental
change, an important building block of evolutionary architecture. We discuss two aspects of
incremental change: development, which covers how developers build software, and operational,
which covers how teams deploy software.
This chapter covers the characteristics, engineering practices, team considerations, and other
aspects of building architectures that support incremental change.
Incremental Change
Here is an example of the operational side of incremental change. We start with the fleshed-out
example of incremental change from Chapter 1, which includes additional details about the
architecture and deployment environment. PenultimateWidgets, our seller of widgets, has a
catalog page backed by a microservices architecture and engineering practices, as illustrated in
Figure 3-1.
Figure 3-1. Initial configuration of PenultimateWidgets’ component deployment
PenultimateWidgets’ architects have implemented microservices that are operationally isolated
from other services. Microservices implement a share nothing architecture: each service is
operationally distinct to eliminate technical coupling and therefore promote change at a granular
level. PenultimateWidgets deploys all its services in separate containers to trivialize operational
changes.
The website allows users to rate different widgets with star ratings. But other parts of the
architecture also need ratings (customer service representatives, shipping provider evaluation,
etc.), so they all share the star rating service. One day, the star rating team releases a new version
alongside the existing one that allows half-star ratings—a significant upgrade, as shown in
Figure 3-2.
Figure 3-2. Deploying with an improved star rating service showing the addition of the half-star rating
The services that utilize ratings aren’t required to migrate to the improved rating service but can
gradually transition to the better service when convenient. As time progresses, more parts of the
ecosystem that need ratings move to the enhanced version. One of PenultimateWidgets’ DevOps
practices is architectural monitoring—monitoring not only the services but also the routes
between services. When the operations group observes that no one has routed to a particular
service within a given time interval, they automatically disintegrate that service from the
ecosystem, as shown in Figure 3-3.
Figure 3-3. All services now use the improved star rating service
The mechanical ability to evolve is one of the key components of an evolutionary architecture.
Let’s dig one level deeper in the abstraction above.
PenultimateWidgets has a fine-grained microservices architecture, where each service is
deployed using a container—such as Docker—and using a service template to handle
infrastructure coupling. Applications within PenultimateWidgets consist of routes between
instances of running services—a given service may have multiple instances to handle operational
concerns like on-demand scalability. This allows architects to host different versions of services
in production and control access via routing. When a deployment pipeline deploys a service, it
registers itself (location and contract) with a service discovery tool. When a service needs to find
another service, it uses the discovery tool to learn the location and version suitability via the
contract.
When the new star rating service is deployed, it registers itself with the service discovery tool
and publishes its new contract. The new version of the service supports a broader range of values
—specifically, half-point values—than the original. That means the service developers don’t
have to worry about restricting the supported values. If the new version requires a different
contract for callers, it is typical to handle that within the service rather than burden callers with
resolving which version to call. We cover that contract strategy in “Version Services Internally”.
When the team deploys the new service, they don’t want to force the calling services to upgrade
to the new service immediately. Thus, the architect temporarily changes the star-service endpoint
into a proxy that checks to see which version of the service is requested and routes to the
requested version. No existing services must change to use the rating service as they always
have, but new calls can start taking advantage of the new capability. Old services aren’t forced to
upgrade and can continue to call the original service as long as they need it. As the calling
services decide to use the new behavior, they change the version they request from the endpoint.
Over time, the original version falls into disuse, and at some point, the architect can remove the
old version from the endpoint when it is no longer needed. Operations is responsible for scanning
for services that no other services call anymore (within some reasonable threshold) and for
garbage collecting the unused services. The example shown in Figure 3-3 shows evolution in the
abstract; a tool that implements this style of cloud-based evolutionary architecture is Swabbie.
All the changes to this architecture, including the provisioning of external components such as
the database, happen under the supervision of a deployment pipeline, removing the responsibility
of coordinating the disparate moving parts of the deployment from DevOps.
Once they have defined fitness functions, architects must ensure that they are evaluated in a
timely manner. Automation is the key to continual evaluation. A deployment pipeline is often
used to evaluate tasks like this. Using a deployment pipeline, architects can define which, when,
and how often fitness functions execute.
Deployment Pipelines
Continuous Delivery describes the deployment pipeline mechanism. Similar to a continuous
integration server, a deployment pipeline “listens” for changes, then runs a series of verification
steps, each with increasing sophistication. Continuous Delivery practices encourage using a
deployment pipeline as the mechanism to automate common project tasks, such as testing,
machine provisioning, deployments, and so forth. Open source tools such as GoCD facilitate
building these deployment pipelines.
CONTINUOUS INTEGRATION VERSUS DEPLOYMENT PIPELINES
Continuous integration is a well-known engineering practice in agile projects that encourages
developers to integrate as early and as often as possible. To facilitate continuous integration,
tools such as ThoughtWorks CruiseControl, Jenkins, and other commercial and open source
offerings have emerged. Continuous integration provides an “official” build location, and
developers enjoy the concept of a single mechanism to ensure working code. However, a
continuous integration server also provides a perfect time and place to perform common
project tasks such as unit testing, code coverage, metrics, functional testing, and…fitness
functions! For many projects, the continuous integration server includes a list of tasks to
perform whose successful culmination indicates build success. Large projects eventually
build an impressive list of tasks.
Deployment pipelines encourage developers to split individual tasks into stages. A
deployment pipeline includes the concept of multistage builds, allowing developers to model
as many post–check-in tasks as necessary. This ability to separate tasks discretely supports
the broader mandates expected of a deployment pipeline—to verify production readiness—
compared to a continuous integration server primarily focused on integration. Thus, a
deployment pipeline commonly includes application testing at multiple levels, automated
environment provisioning, and a host of other verification responsibilities.
Some developers try to “get by” with a continuous integration server but soon find they lack
the level of separation of tasks and feedback necessary.
A typical deployment pipeline automatically builds the deployment environment (a container like
Docker or a bespoke environment generated by a tool like Puppet, or Chef) as shown in Figure 3-
4.
Figure 3-4. Deployment pipeline stages
By building the deployment image that the deployment pipeline executes, developers and
operations have a high degree of confidence: the host computer (or virtual machine) is
declaratively defined, and it’s a common practice to rebuild it from nothing.
The deployment pipeline also offers an ideal way to execute the fitness functions defined for an
architecture: it applies arbitrary verification criteria, has multiple stages to incorporate differing
levels of abstraction and sophistication of tests, and runs every single time the system changes in
any way. A deployment pipeline with fitness functions added is shown in Figure 3-5.
Figure 3-5. A deployment pipeline with fitness functions added as stages
Figure 3-5 shows a collection of atomic and holistic fitness functions, with the latter in a more
complex integration environment. Deployment pipelines can ensure the rules defined to protect
architectural dimensions execute each time the system changes.
In Chapter 2, we described PenultimateWidgets’ spreadsheet of requirements. Once the team
adopted some of the Continuous Delivery engineering practices, they realized that the
architecture characteristics for the platform work better in an automated deployment pipeline. To
that end, service developers created a deployment pipeline to validate the fitness functions
created both by the enterprise architects and by the service team. Now, each time the team makes
a change to the service, a barrage of tests validate both the correctness of the code and its overall
fitness within the architecture.
Another common practice in evolutionary architecture projects is continuous deployment—using
a deployment pipeline to put changes into production contingent on successfully passing the
pipeline’s gauntlet of tests and other verifications. While continuous deployment is ideal, it
requires sophisticated coordination: developers must ensure changes deployed to production on
an ongoing basis don’t break things.
To solve this coordination problem, a fan-out operation is commonly used in deployment
pipelines in which the pipeline runs several jobs in parallel, as shown in Figure 3-6.
Figure 3-6. Deployment pipeline fan-out to test multiple scenarios
As shown in Figure 3-6, when a team makes a change, they have to verify two things: they
haven’t negatively affected the current production state (because a successful deployment
pipeline execution will deploy code into production) and their changes were successful (affecting
the future state environment). A deployment pipeline fan-out allows tasks (testing, deployment,
etc.) to execute in parallel, saving time. Once the series of concurrent jobs illustrated in Figure 3-
6 completes, the pipeline can evaluate the results and, if everything is successful, perform a fan-
in, consolidating to a single thread of action to perform tasks like deployment. Note that the
deployment pipeline may perform this combination of fan-out and fan-in numerous times
whenever the team needs to evaluate a change in multiple contexts.
Another common issue with continuous deployment is business impact. Users don’t want a
barrage of new features showing up on a regular basis and would rather have them staged in a
more traditional way, such as in a “Big Bang” deployment. A common way to accommodate
both continuous deployment and staged releases is to use feature toggles. A feature toggle is
typically a condition in code that enables or disables a feature, or switches between two
implementations (e.g., new and old). The simplest implementation of a feature toggle is an if-
statement that inspects an environment variable or configuration value and shows or hides a
feature based on the value of that environment variable. You also can have more complex feature
toggles that provide the ability to reload configurations and enable or disable features at runtime.
By implementing code behind feature toggles, developers can safely deploy new changes to
production without worrying that users see their changes prematurely. In fact, many teams
performing continuous deployment utilize feature toggles so that they can separate
operationalizing new features from releasing them to consumers.
QA IN PRODUCTION
One beneficial side effect of habitually building new features using feature toggles is the
ability to perform QA tasks in production. Many companies don’t realize they can use their
production environment for exploratory testing. Once a team becomes comfortable using
feature toggles, they can deploy those changes to production because most feature toggle
frameworks allow developers to route users based on a wide variety of criteria (IP address,
access control list [ACL], etc.). If a team deploys new features within feature toggles to
which only the QA department has access, they can test in production.
Using deployment pipelines in engineering practices, architects can easily apply project fitness
functions. Figuring out which stages are needed is a common challenge for developers designing
a deployment pipeline. However, once the fitness functions inside a deployment pipeline are in
place, architects and developers have a high level of confidence that evolutionary changes won’t
violate the project guidelines. Architectural concerns are often poorly elucidated and sparsely
evaluated, often subjectively; creating them as fitness functions allows better rigor and therefore
better confidence in the engineering practices.
Case Study: Adding Fitness Functions to PenultimateWidgets’
Invoicing Service
Our exemplar company, PenultimateWidgets, has an architecture that includes a service to
handle invoicing. The invoicing team wants to replace outdated libraries and approaches but
wants to ensure these changes don’t impact other teams’ ability to integrate with them.
The invoicing team identified the following needs:
Scalability
While performance isn’t a big concern for PenultimateWidgets, the company handles
invoicing details for several resellers, so the invoicing service must maintain availability
service-level agreements.
Integration with other services
Several other services in the PenultimateWidgets ecosystem use invoicing. The team wants
to make sure integration points don’t break while making internal changes.
Security
Invoicing means money, and security is an ongoing concern.
Auditability
Some state regulations require that changes to taxation code be verified by an independent
accountant.
The invoicing team uses a continuous integration server and recently upgraded to on-demand
provisioning of the environment that runs their code. To implement evolutionary architecture
fitness functions, they implement a deployment pipeline to replace the continuous integration
server, allowing them to create several stages of execution, as shown in Figure 3-7.
Figure 3-7. PenultimateWidgets’ deployment pipeline
PenultimateWidgets’ deployment pipeline consists of six stages:
Stage 1: Replicate CI
The first stage replicates the behavior of the former CI server, running unit and functional
tests.
Stage 2: Containerize and deploy
Developers use the second stage to build containers for their service, allowing deeper levels
Random documents with unrelated
content Scribd suggests to you:
wide sweep from out the lane, dragging after them a huge, open,
omnibus sleigh. As the great ark ranges in front of the hotel, and its
mad team subsides into comparative quiet, forth issue from the
thronged piazzas crowds of village belles and beaux. Can it be that
so many may find room aboard the sleigh, capacious as it is? Leave
that to the Genius who presides over expeditions of this sort. In a
sleigh, large or small, there is always room for one more. In the
meantime the doors of the private dwellings have been opened, and
from each emerges a beshawled, bemuffed, behooded, and
overshod damsel—or two or three perhaps. Their happy beaux, clad
in overcoats of pilot-cloth, in seal-skin caps, red worsted leggings,
and buckskin gloves, escort them to the sleighs. The procession is
formed in front of the hotel. Twenty sleighs, besides the teeming
omnibus. The last in the line is a crockery crate, mounted upon a
rude pair of runners and hitched behind a tandem team. The leader
is a three-year old colt, wild and but half broken, and now, crazy
with the noise, he is kicking and plunging like mad. In the crate
stands the dare-devil of the village; a rich, handsome, graceless,
good-natured scamp—the darling of the girls, the marvel of the
boys, the terror of the piously disposed, and the favorite of all. He
prefers to ride alone. Now all is ready—the band strikes up—the
driver of the omnibus stands erect and tightens his reins—crack,
goes the long whiplash—the horses plunge and start, the snow
creaks, the bells jingle, the boys and loafers hurrah, the beaux laugh
as the girls scream, and away flies the long caravan, like an express
train, down the broad street, thundering, cracking, screaming,
laughing. They turn the corner, all but the daredevil and his crockery
crate, they are upset in a snow-drift, but before the army of boys
and loafers can reach the scene of the mishap, all is right side up
again, and the last seen of dare-devil he is driving by the whole
train, his frantic leader touching the snow only once in a rod.
Two hours afterward six reeking horses drag the omnibus up to
the hotel piazzas again—a string of sleighs come in behind—one by
one the stragglers arrive. Dare-devil and his team are among the
missing, and on inquiry are reported as seen last, the one kissing the
landlady at a tavern ten miles away, and the other engrossing the
attention, and calling into active exercise all the strength and agility
of the landlord and his negro hostler.
In the meantime twenty miles of snow path have been scoured
over by the merry, frost-covered throng disembarking on the steps.
Thousands of merry speeches have been said—a whole jest-book full
of funny stories have been told. Every pretty hand in the company
has been squeezed. Every pretty cheek has been kissed, and, we
doubt not, almost every pretty lip. At least nine flirtations have been
commenced. The moon has drawn together three pairs of twin
hearts, and set them throbbing in unison—and one little question
has been put and answered, very satisfactorily to the absorbed
couple in yonder sleigh, which is arriving late, closely pursued by the
shouting dare-devil and his prancing team.
All night the glaring windows of the ball-room shake and rattle.
The inspiring music, to which they keep time, the sound of the
dancers’ feet, the merry ringing of lamps, and the buzz of
conversation are heard by the sleepy watchers in the bar-room
below, who while away the hours, except when disturbed by
eruptions of the beaux from above, in quest of confectionary and
lemonade, or perhaps stronger beverages, by playing checkers,
drinking flip, smoking cigars, and endlessly discussing the points and
merits of divers horses of the neighborhood.
The pale moon lights home the revelers, just in time to save her
sister Aurora the trouble.
The young May moon has been justly celebrated by the poets,
and many have supposed, that at this season the hearts of lovers
are more susceptible than at any other time. Truly the moonlight of
May is very beautiful and love inspiring—but the August and
September moon is the time of times—when the air is clear and
warm, without cloud or chill, and rich and faint with the odors of the
ripe fruits—when the corn and grain and all that grows from the
earth’s bosom are at full height and verging toward maturity—when
other leaves than those of tall trees rustle in the night wind—when
the katy-did and cricket hold cheerful conversation, and fill the air
with noisy clamor, near akin to silence—when the nights have grown
longer and cooler than in the fierce mid-summer—when the moon
seems larger and fuller than its wont, and its light has a deeper tone
—then is the time to enjoy, in perfection, moonlight nights and
lunatic fancies. Nights we say—not evenings. In the evenings one
sees company and receives calls, takes wearying walks, hears
commonplace remarks about the beauty of the weather and the
prospects of the crops, eats ice-creams, drinks sherry-cobblers, or, it
may be, smokes cigars and reads the evening newspaper. It is a
border ground, upon which the people of the work-day world make
forays. But “the small hours,” far in “the stilly night,” from twelve to
three, contain the true romance of moonlight. The dull world is
asleep, there is a new heaven and a new earth, peopled only by
fairies, lunatics, ghosts and poets. Bright heavenly hours! Methinks
in praise of them we could “mark out a measure of verse.”
They may tell of the sunlight’s brilliant dyes
When the day in the Orient breaks;
Of the splendid glare which dazzles the eyes
As his noontide course he takes;
They may talk of the gorgeous hues that glow
In the western sky at eve,
When, in gaudy pomp and with gilded show,
Of the world he takes his leave.
They may praise the Aurora’s wayward gleam,
As far up the northern sky
The ruddy flashes fitfully stream,
Then suddenly fade and die;
And flash anew, and again sink low,
Like the love of a fickle swain;
While the shadows flicker over the snow
That covers the wintry plain.
The poets sing of the twilight hour,
The twilight hour of eve;
And teach that it hath a magic power
To soothe the hearts that grieve;
That lovers prefer this gentle time—
To courting it gives such a zest—
And, as for themselves, for the stringing of rhyme
That the twilight hour’s the best.
There are some who delight in a starlight night,
And some like a chandelier;
And others a grate-full of anthracite,
Or of hickory burning clear,
And some the religious light that is shed
Adown in a church’s aisle—
And some will turn out from a nice, warm bed
To gaze on a burning pile.
But the light that we love far better than all
Is the light of the golden moon
At the sweet, short hour “ayont the twal,”
Just past the summer night’s noon.
Oh! then ’tis sweet to roam alone,
Or to sit in the shaded bower!
No enchantment, we ween, on earth is known
Like the magic of such an hour.
’Tis sweet when the night by the moon is graced
To wander with her we love;
Or to sit with our arm around her waist,
While we coax from her hand the glove;
And to teaze in a whisper for one sweet kiss
Till we gain the darling boon!
Oh! for making love ne’er a time like this—
By the light of the August moon.
“And so on,” as Elia says, “one might proceed in this strain
forever.”
Give to us, then, the moonlit nights of fragrant August and
mature September. There is a body to them, a delicate aroma withal
—the intoxication is heavenly, such as nectar might produce. Then it
is that heaven seems descended to the earth, and fairy land
restored. Then it is, that, if we find ourselves alone with one of the
other sex, by the soft light, we are prone to imagine her to be our
better self, our other moiety, the twin soul for which we have longed
in our dreams, and—hence the propriety of a proper selection of
moonlight company, judiciously made, before sunset. Then it is that
we like to talk but little, and only in whispers and low tones. Then it
is that our souls grow large, and we cannot believe ourselves mortal.
Deep ardent longings seize us for something we know not what.
Tears, neither of sadness or joy, spring to our eyes. Delicious,
incomprehensible emotions agitate our hearts. Strange things seem
easy of credence, and to see a troop of fairies dancing on the green
lawn, or the placid ghost of a dear friend, half hidden in the shade of
yonder vine, would startle us but little, and would seem all in
keeping. Then we grow poetical—romantic—at peace with all the
world—then chilly—then—ah! poor human nature!—then sleepy! and
when, six hours after, we rise, at the third call, to a late cold
breakfast, eggs, rolls and coffee seem to us of great importance,
and occupy the whole attention of a soul, which, but lately, held the
whole world in its embrace and felt a void the while.
Gentle reader—while we write the pale, exhausted moon is
setting behind the distant ridge of Talcott mountain. The tall tower
of Montevideo stands like a lonely, belated giant, in full relief against
the silver-gray western sky. Our hair is damp with dew—our numb
and weary fingers can hardly retain the blunt pencil with which we
have indited the preceding extravagances. There is a faint, ruddy
glow in the east—we hear the neigh of Aurora’s steeds. Good night
then, dear, lunatic reader. May the morn find you sane—the night
mad again—and long may it be ere the soft light of the full moon
shall rest upon the green sod of your grave, and glow, reflected from
the marble of your monument.
TO MISS MARTHA GRIFFITH.
———
BY G. D. P.
———
Beautiful girl, I have wandered far,
Toward the rising sun and the evening star,
I have roamed ’mid the Northern wastes of snow,
And strayed where the soft magnolias blow,
But I never gazed on a face as bright
As thine, sweet spirit of young delight.
Beautiful girl, thou art bright and fair
As an angel-shape in the moonlight air,
No shadow rests on thy brow of snow
Save that of thy tresses drooping low,
Love’s own dear light is wandering oft
O’er thy gentle lip of carmine soft,
Thy lovely cheek, where the rich, red glow
Of the warm blood melts through the virgin snow,
Is sweetly blending in one rich dye
The woven beauties of earth and sky;
Truth, holy truth in its freshness dwells
Deep, deep in thy dark eyes’ shaded wells,
And fancies wild from their clear depths gleam,
Like shadows of stars from a trembling stream,
And thy thoughts are a dream of Eden’s bowers,
And thy words are garlands of flowers, bright flowers.
Beautiful girl, I have seen thee move
A floating creature of joy and love,
As light as a mist on the sunrise gale,
Or the buoyant sway of a bridal veil,
Till I almost looked to see thee rise
Like a soaring thought to the free blue skies,
Or melt away in the thin blue air,
Like a vision of fancy painted there.
Thy low sweet voice, as it thrills around,
Seems less a sound than a dream of sound;
Softly and wildly its clear notes swell
Like the spirit-tones of a silver bell,
And the lips whence the fairy music flows
Is to fancy’s eye like a speaking rose.
Beautiful, beautiful girl, thou art
A vision of joy to the throbbing heart,
A star sent down from a world of bliss
And all undimmed by the shades of this;
A rainbow pictured by love’s own sun
On the clouds of being, beautiful one.
Beautiful girl, ’tis a weary year
Since thy sweet voice fell on my ravished ear.
’Tis a long, long year of light and gloom
Since I gazed on thy young cheek’s lovely bloom—
Yet thy gentle tones of music still
Through the holiest depths of memory thrill
Like tones of a fount, or breeze, or bird,
In the long gone years of childhood heard.
And oft in my dark and lonely moods,
When a demon-wing o’er my spirit broods,
Thine image seems on my soul to break
Like the sweet young moon o’er a gloomy lake,
Filling its depths as the shadows flee,
With beauty and love and melody.
Beautiful girl, thou art far away,
And I know not where thy steps now stray;
But oh! ’tis sweet, it is very sweet,
In the fairy realms of dreams to greet
Thy cheek of roses, thy brow of pearl,
And thy voice of music, beautiful girl.
PICTURE OF CHILDHOOD.
———
BY WM. ALEXANDER.
———
Forth issuing from a craggy mountain’s side,
A stream is seen. Anon, with gilded prow
And silvery oars, a bark appears to glide,
Bearing a happy infant, on whose brow,
Pictured are Joy and Wonder. Onward still
Over the widening stream’s wild waves, eke, skims
It merrily. The tiny steersman hymns
His roundelay of Joy, or at his will,
Plucks the gay flowers of early morn,
Which diamond dew-drops, silver-like, adorn—
Unmindful that such pleasures fade away,
That youth, and love, and beauty soon decay—
Life is a launch—we voyage to the grave,
We venture on, unthoughtful of the whelming wave.
MINNIE DE LA CROIX:
OR THE CROWN OF JEWELS.
———
BY ANGELE DE V. HULL.
———
(Concluded from page 304.)
“Lord bless us, my children! what a noise,” cried Mr. de la Croix
on the morrow as he entered the store-room. “I am deaf! give me
some claret and water some of you! I am thirsty enough to swallow
bottle and all. I have had lamps fastened to every other tree in the
avenue and every column around the piazza.”
Minnie brought him the iced wine and ran off to work again. She
was beating eggs for a mayonnaise, and directing the servant behind
her in chopping celery and chicken for salad.
Lisa was standing on a table pouring from an immense bowl a
stream of icing over a pyramid of cake that stood in a salver on the
floor. Rose was frothing eggs for something else, Kate was churning
syllabub, and Blanche was pounding almonds.
Mr. de la Croix stopped his ears and called out as loudly as he
could, “Halt! order! I want to talk. Where are those great china
bowls to be placed, and the pride of Rose’s existence, the diamond-
cut wonder—the crystal one? No one can carry them among you
here, and I must tell Sampson to do it.”
“The two first on the piazza, the glass one in the middle of the
table,” answered Lisa, looking up from her task. “I only hope
Sampson will not serve them like Philistines, with the exertion.”
“Do you think there is too much strength under those woolly
locks of his, Lisa, or do you fear a superfluity of grace in his
‘fantastic toe?’” said Kate.
“I know that his ‘fantastic toe,’ as you are pleased to dignify it,
kicked over a pan of milk an hour ago, when I sent him to the dairy,
and these tricks have not certainly power to make angels smile.”
“Samp want to white hisself for to-night,” said his wife, showing
her ivory as she looked at him. “Miss Lisa never scold him for it, but
you may know I did, Miss Kate. What he do such ladicalous things
for?”
“He could not help it, Aunt Winny,” said Minnie as she turned her
dish of well frothed eggs to prove her skill. “Now here is a
magnificent float for your ‘island.’ You know I always said that you
should make your favorite dish for my wedding-supper, and this is an
occasion quite as important. Here is the sugar, sand and every thing
you want.”
“Thank’ee, Miss Minnie. I’ll make it splendid, you may know that.
But dis an’t no wedding-supper, my child, and it musn’t be so grand
a floatin’ island as the bride’s. Ah! didn’t I make two for Miss Kate
and Miss Blanche if dey wos married in de mornin’. I nussed you all
—fine gals you is! Dey an’t such young ladies for miles round, and
please God! I may live to see you all happy and lovin’ your pardners
as them do. My old mistress herself would love to see ’em so.”
And Winny left the room majestically—a pan on her head and
one in each hand, six little nigs at her heels, each dismissed with a
lump of sugar as they went along in a straight line to the kitchen.
“Winny grows eloquent, as she gets older,” said Lisa. “If every
body believed her, we would all be like Miranda with every creature’s
best. I wonder what she will say when she sees us all dressed to-
night.”
Winny was not the only one delighted with her young mistresses
as they made their appearance in the hall, one after another, and
surveyed the beautifully decorated walls of the several apartments
opened for the occasion. Festoons of cedar were hung around and
above, and beneath each were large bouquets of fresh flowers,
arranged in perfect taste. The orchestra hung in scarlet cloth, was
wreathed in roses and evergreens, and surrounded by lamps placed
so as to illuminate these fairy bowers independent of the glittering
row of lights for the musicians. Stands of exotics occupied one side
of the hall, the fair and tender buds throwing out a thousand
perfumes on the air, yet even these were not more fragrant than the
flowers of the season that hung around, the delicate maiden’s-blush
and the pale tea-rose. Long after the chilly autumn winds have made
us close our casements and doors, these sweet sisters are blooming
in the gardens without, and from Mr. de la Croix’s thick and extended
hedges he had found a harvest for his daughter’s ball.
Nothing could be more brilliant than the tout ensemble of
garden, house and avenue. Every nook and corner had its light,
every room its comfort, and before the guests began to assemble
Lisa had satisfied herself that the arrangements for their enjoyment
were indeed complete. Her queenly form well became the blue
tarlatan with its moss-roses in bunches of half opened buds. Her hair
was simply twisted, and in satin-like bands over her ears.
Blanche and Kate floated about in their pure white, their
elegance conspicuous from their simplicity, while Rose and Minnie,
like twin roses, were radiant with beauty. The excitement had
deepened the color on their cheeks and brightened their eyes into
stars. Who wonders then at the father’s pride as he looked at his
crown of jewels this night? Who wonders that the guests loved their
pleasant smiles, and treasured their gentle welcomes? No one was
neglected by them, not one in the whole crowd felt forgotten or
slighted, and the hours flew by as though Time had laid his hour-
glass in the green bowers and slept at its side.
“Minnie, Minnie!” whispered Blanche, “you talk too heedlessly. Be
more quiet, my dear girl.”
“Ah, do not scold me to-night,” cried she, as she leant half
panting for breath upon her partner’s arm. “Is it not a shame to
scold me now?” And she raised her bright eyes to his with a look
that dazzled him.
“It is a shame ever to do so,” replied he earnestly. “Surely Mrs.
Stuart you are not so cruel?”
“Only prudent, Mr. Milton, that is all; remember this is my little
sister’s ‘first appearance.’”
“You mean that she is one of the unsophisticated,” said he
laughing. “And by far more bewitching in consequence,” was added
in a whisper.
Blanche smiled and shook her head at him, but they whirled off
in a waltz before she could reply, so she returned to her station by
Kate, who was talking in a very old-fashioned kind of way to—her
husband.
“Paul and I were thinking the same,” said Kate, as she placed her
arm within hers. “Minnie is tant soit peu inclined to flirtation, and we
must warn her before it becomes a passion.”
“A passion, Kate!” said her husband smiling.
“Yes; a passion for admiration—for change, and a sickly love of
flattery that is beneath a girl like our Minnie. How I do hope she will
preserve that perfect freedom from all affectation that is one of her
greatest charms.”
Paul made no answer, but as the quadrille broke up, went
forward to the object of this enconium as she accepted her partner’s
offer of a quiet promenade after her dance.
“Minnie,” said he, “you have not danced with me this evening.”
“Because you have not asked me,” replied she, putting her arm
through his with an affectionate smile. “I have felt myself quite
neglected by you and Kenneth, I assure you.”
“I was just coming to claim you, Minnie,” said Mr. Stuart, who
had heard her last remark. “But since I am supplanted this time, we
are engaged for the next.”
She nodded to him and passed on to a group of young girls who
were talking gayly, and joined them. One, a fair-haired blonde with a
pair of melting blue orbs, accosted her with a congratulatory remark
upon the entire success of her fête.
“We are all delighted with every thing—with you and with
ourselves, par parentheses. But why does not your father dance,
Minnie?”
“Go and ask him,” said she laughing. “I have not seen him dance
since I was a little girl.”
“Well, he shall dance with me then,” exclaimed the pretty
questioner, “and I am going to invite him for the very next quadrille.”
And off she tripped to find Mr. de la Croix.
“Dance with you, my sweet young lady,” cried he. “And what will
all these gay and handsome fellows say to my usurping their place?”
“That I show very good taste in my selection of a cavalier,” was
the reply. “You must dance with me Mr. de la Croix because—I have
said that you must.”
“The little maid would have her will,” quoted he, much amused.
“So come, my little conqueror, I could not refuse, even if an old
man’s bygone steps are shocking to polka lovers and sliding graces.”
“I have gained a victory,” said Miss Ashton, as he led her to a
place among the dancers. “See, Minnie! I have chosen my own
partner, in spite of ceremony and etiquette.”
“Age has its privileges,” observed Mr. de la Croix, with a courtly
bow, “and this is one of its most pleasant advantages. I had never
been so honored but for my silver-streaked head.”
“Ah, Mr. de la Croix!” said his young companion archly, “your
youth has only to return to put us to the test. I’m sure you could tell
us of bright eyes that followed you wistfully in days of yore.”
“Little flatterer!” exclaimed he, as the music struck up. “My age
again has helped me to this.”
But the gay girl bounded forward, and he watched her graceful
movements with so much pleasure that he almost forgot his own
part.
Minnie was opposite too, and seemed so delighted at seeing her
father dance, that he quite enjoyed an amusement that had been for
so many years discarded, as one too frivolous for a père de famille.
Mr. Selby had to follow his example, as Minnie declared it his
duty to do so, and thus her “first party” was a perfect triumph, as
not only the younger but the older heads were giddy with their
exertions to amuse and be amused. It was nearly daylight before
Sampson had finished his task of putting out the lights, and the hall,
like all other banquet halls, deserted. There were no heavy hearts
carried away, though many perhaps were lost to merciful finders,
and Minnie laid her young head on her pillow with a feeling of
consciousness that her debut had been one of unusual and brilliant
success.
And so it proved, for during the season that followed, no party of
pleasure—no crowded ball was complete without her presence. She
was a perpetual sunbeam, shedding light by her winning smile and
sweet temper. Her sisters accompanied her by turns, and watched
her flying steps with affectionate pride; but Kate’s fears were partly
verified, and her young sister too fond of admiration to escape that
love of sway over the hearts of the many that seemed to live but in
her glances. In vain they warned—in vain they lectured, Minnie had
been too long careless of advice to heed it now in this whirlpool of
constant gayety. Still artless, still unaffected, she dispensed her
smiles too lavishly, and fanned the flame her varied charms had
kindled, where she might have spared her victims many a pang, had
she heeded the voice of reason.
“Would you have me cross to people?” said she to Kate.
“No, Minnie; but seemingly less pleased with their attentions. Did
not Mr. Douglas have reason to complain that you had encouraged
him, when you refused his offer last week?”
“Who told you that?” asked Minnie, crimsoning to the temples.
“Who told you that, Kate?”
“Himself, and I could not but feel for his disappointment,” said
Kate earnestly. “I have seen you look pleased at his assiduities—so
pleased, that I could not wonder at the reproach he made you.”
“I granted him no more than I did to others,” said the girl
tearfully.
“But you have a way, Minnie, of accepting homage that is
flattering to those who offer it.”
“I am flattered, and return only what I receive.”
“But you do not, my dear sister. What they offer is too often
sincere; they, then, according to your mode of reasoning, have a
right to expect the same. Harry Lamfear left here in consequence of
your refusal, for, as he said, he could not bear to meet you wherever
he went, and I own that I thought you were partial to him from a
promise I heard you make, to wear no bouquets but his for one
month.”
“You are making mountains of mole-hills,” said Minnie, blushing
again. “I never dreamed that such a promise was equivalent to
‘Certainly, sir! go and order the furniture.’ I did like Harry Lamfear
exceedingly, but love was no part of the liking. I told him more than
once—more than twice, since I must defend myself, that it was
useless for him to expect any thing more than friendship from me. I
could not refuse to speak to him—it will not do to insult a man
because he wants to marry you, will it?”
“Decidedly no; but then you should have refused to dance with
him more than once in the evening—you should have denied
yourself on more occasions than one, when he called. I saw you one
morning get up from the sofa, where you were suffering actually
with a headache, and dress your hair as becomingly as you knew
how, with a morning-cap that was really a charming set-off to your
piquante style, and go in the parlor to receive him. You told him of
your indisposition of course, and his inference was, that there must
have been something more than friendship to rouse you in the midst
of pain, to the exertion of entertaining him. Did it look like
indifference?”
“I was wrong there, sister,” said Minnie, rising and seating herself
beside her. “Tell me what I must do.”
“Be kind and courteous to all, my little pink-cheek, and do not
listen with such a ready ear to the honied words that make you
giddy. Do not every week or month select one on whom to bestow
your favors, but treat all alike indifferently until you really find your
own feelings enlisted. Then I need not advise, your own delicacy,
your own natural modesty will make you every thing you ought to
be. But for heaven’s sake do not give people the idea, that you are
caught like a candle-fly by every glare, and wear a battered down
heart after your first winter is over.”
“Oh, Kate, how matter-of-fact you are! Why didn’t you say ‘pretty
moth,’ and ‘withered heart?’ You shock me with your every day-
isms.”
“You have very fastidious ears, Minnie, and I am not jesting.
There is one thing more to be said and I have done. Beware of
trifling with young Freeman. He will not suffer himself to be led like
his predecessors if he is serious. And if he is, as I think, merely
playing your game of flirting, he will make you regret ever having
seen him. I do not like him—I cannot look at him without a feeling of
uneasiness.”
“How foolish!” cried Minnie, laughing, “and how ungrateful! he is
always praising my charming sister Mrs. Linden.”
“Yes, so as to tell you immediately afterward how much you
resemble her,” said Kate gravely. “I am not old, Minnie, but I am
sorrowed, and feel no longer young. Let what I have said this
morning be of some benefit to you, for your own sake, if not for
mine. I must watch and warn you, heedless as you are to all
counsel, and in so doing I make a sacrifice that costs me something,
for I might be conversing pleasantly on other subjects, and feel
secure that my sister Minnie does not think me harsh and
disagreeable,” and her eyes filled with tears.
“How unjust!” cried Minnie, throwing her arms around Kate’s
neck, and kissing her affectionately. “How very unjust! Do I not
know how to value your advice, Kate—am I so heartless in your
eyes? Heedless I am indeed, but not heartless, and I will try and
remember what you have said, that I may act upon it.”
And so she did until it was forgotten, and young Freeman’s
devotion became once more a triumph to the unreflecting Minnie.
Her sisters rejoiced as the end of the season drew nigh, as the entire
summer would be undisturbed by these constant amusements. They
would once more live in quiet after the gay and to them tiresome
winter, passed in following their young charge from place to place,
and in the meantime a change might come over the “spirit of her
dream.”
It was at the opera that Minnie sat once more, while Mme. ——
enchanted and fascinated her audience. Her bright eyes were fixed
upon the sweet singer, and she did not perceive the door of her box
opened to admit a gentleman, who took his seat and gazed in
silence at the lovely form before him. Ever and anon he turned to Mr.
Stuart, who stood behind with a smile of pleasurable surprise upon
his fine open countenance, and watched with some impatience the
close of the second act of “Jerusalem,” in spite of his love of music
and the beauty of this particular opera.
But the curtain fell, and Minnie turned to speak her delight to her
brother. She started as she recognized Harry Selby!
He could not but be flattered at the expression of pleasure upon
that speaking countenance, and the fluttering of the little hand,
which, for a moment, rested in his; while Minnie read in those dark
eloquent eyes a story that sent the tell-tale blush to her cheek, and
forced her into a silence that provoked and embarrassed her.
But Rose came to her aid, and poured inquiries into his not over
attentive ear. When did he arrive—when did he sail? Where was his
uncle?
“I arrived this morning—I sailed three weeks ago from Liverpool
to New York, and lost not a minute in coming south, and left my
uncle at home.”
“You are a perfect telegraph,” said Minnie, recovering her speech.
“Your friends must feel highly flattered at your haste to reach them.”
“Ah!” exclaimed he, fixing his eyes upon her, “I felt that I could
not trust myself to remain absent any longer! I had so much to
learn! so much to lose!”
Minnie turned to the stage and lifted her opera-glass, while Rose
smiled in spite of herself. Here was a lover comme il y’en a peu. And
as she contemplated his handsome countenance expressive of high
and noble qualities, his attractive manner and pleasant flow of
words, she felt that Minnie was a conqueror indeed.
“Come and dine with us to-morrow, Harry,” whispered she, as he
handed her in the carriage. “And bring your uncle with you. Tell him
I have a japonica in full bloom and he must see it.”
“Ah, Rose!” was the reply, “you are an angel! You do not mock
the ear with promises—you mean to keep them.”
And they drove off at a rapid pace, leaving him to rejoice over
the beauty and fascination of his youthful love, while she leaned
back and wondered at the beating of that hitherto quiet heart—the
strange but pleasurable emotion that seemed gushing from its
depths.
“How remarkably he has improved!” exclaimed she, turning to
her sister. “How proud his uncle must be.”
“Proud indeed!” replied Rose. “And Harry’s worth does not consist
in his good looks, he has a well-regulated, intelligent mind, a noble
heart, and that rare pride that scorns an unworthy thought. I saw
him constantly when I was in Paris, and I am certain that he will
fully justify the opinion I formed of him.”
The carriage stopped at Mrs. Bliss’s door for Kenneth and
Blanche, and Mr. Selby came out to meet his favorite. Minnie parried
his questions as well as she could, but Rose’s congratulations upon
his nephew’s arrival and appearance satisfied him, and he accepted
her invitation to dinner with unmistakeable pleasure. He had
intended to take them by storm, but now Lisa would have warning,
and be able to fuss over them as they deserved, and he bade them
“good night” with a hearty shake of the hand.
Down the pleasant avenue wandered two graceful forms a few
weeks after this, the gentle tones of a young girl’s voice mingling
with the deeper, more tender ones of a youth, who was gazing
earnestly on her deepening cheek.
“I need not have told you, Minnie, for you knew it that night at
the opera,” said he pleadingly. “You could not but see that I loved
you as few love—that in spite of time and space your image had
remained within my heart, its fondest remembrance. Tell me,
Minnie,” and he paused as they reached a vine-covered bower, and
led her to a seat beneath its shade, “tell me honestly, did you not
read all this ere now?”
She trembled—her lot now was to be cast, her fate determined,
and there seemed a spell upon her, for she could not speak; but
there was no shade upon that fair smooth brow, no anger in those
softened looks, and Harry, like many a one before him, dared to
interpret for himself what her own lips at length were able to affirm.
And now to them the world seemed a paradise indeed, and life
one long summer day, o’er which no cloud could ever come, to
shadow their sunny hopes. The blue sky seemed clearer above their
heads—the flowers were brighter, and the fair earth fairer still.
Happiness was theirs, for they were all to one another, and as the
hours passed unheeded, and the gleaming stars burst forth into the
quiet heavens, they raised their eyes and likened their love to the
quenchless beauty of its countless lamps.
Alas, poor dreamers! ye are granted this one momentary
perfection of bliss! Ye can linger for once over this dawn of promised
light—for once ye are convinced of its duration. But the sky must
darken, the lamps must go out—the flowers must perish—the hopes
must wither! There is but one hope—one home of happiness—the
home that is not to be won without its pains, its fierce and mighty
struggles, its chastenings, that purify and fit the soul for the
presence of Him who promised it to the pure of heart.
Poor Minnie had to wake from her dream of love, but not yet—
not until she was once more in the giddy round of engagements for
the spring. It was at Mrs. Bliss’s last soirée that she was seen flying
about like a vision of light, while Harry Selby watched her every
glance. He had a right to be proud of her, for she was his own—his
promised one, and proud he was. But a shade passed over his face
as he beheld her extending to another the same smiles she gave to
him; exerting for another the same fascinations that bound him
captive from the hour he first beheld her. He did not intend, dear
reader, that Minnie should give up all for him; he did not expect her
to be less gay or less fond of dancing, but he could see no difference
now between her conduct to those around her, and to him alone. He
had a right to more than they, but although Minnie’s engagement
was generally known, she allowed her lover to be pitied or jested
with upon the danger of marrying a flirt, who cared more for
admiration than for the love he bore her.
I am no advocate for the exactions or fastidiousness of the
stronger sex, exactions that in all cases become that conjugal
tyranny that drives us with broken hearts to an early and welcome
tomb. I cannot uphold that constant recurrence to the difference of
duties and deportment that marked the single and the married
woman. The ceremony that binds in a few moments, cannot change
the disposition of eighteen or twenty years—cannot blanch the dark
braids of the bride into a matron’s sober locks; and yet there are few
husband’s in the world who do not frown and wonder, if before the
honey-moon is half over, he sees in his young wife the same ways
and manners of the unfettered creature he had sworn so perfect,
that her faults, if faults she could have, were virtues. He had vowed
that his life was a curse without her, that he asked only her love in
return for his passionate devotion. But no sooner is she won, no
sooner is she the wife who has bound herself to him “for better, for
worse,” than he expects, God help her! the sacrifice of every thought
she has to his prejudices, and never dreams how often she has been
shocked at faults and habits that tore from her eyes the veil her own
youth and inexperience had helped to weave.
But Harry Selby was not as a lover more exacting than was
natural and proper, and he had imbibed some of Kate’s opinions
concerning young Freeman, knowing too, more than she did, to
justify his aversion. His devotion to Minnie de la Croix was not at
first sincere, for his object was merely to triumph over others, and
win a wager he had already made to do so. But her indifference to
all his protestations enraged him, and her subsequent betrothal had
made him jealous, and proved how madly he had learned to love
her. He swore that he would force her to dismiss his rival, and
Minnie’s acceptance of his attentions allowed him to dream of
success in spite of her coldness to his suit, and laughing answers to
his serious questions. He was well aware of his powers; he was one
of the most attractive of his sex, witty, entertaining, and having that
peculiar expression of high respect in his manner, that is particularly
pleasing to women. Many would have given up, with more success
than he could boast of, but he had vowed to revenge himself on
Harry Selby, and his friends had heard him; so around poor Minnie a
web was forming which her own thoughtlessness but helped to
strengthen. She was convinced that Mr. Freeman fully
comprehended her sentiments, and thus excused herself for carrying
him in her train, unwilling to give up one who added so much to her
amusement, and the splendor of her triumphs. In the midst of a
merry argument upon the rights of two waltzers that stood before
her, Harry approached.
“Will you dance with me?” he asked, and offering his arm to her.
“I have waited patiently until now, you were so surrounded!”
“Why, do you not see these two importunate creatures teasing
my life out? They want me to waltz, when I am tired to death and
want to rest,” replied she, with a toss of the head that became her
amazingly.
“But I ask you to dance,” said Harry, earnestly. “It is not so
fatiguing, and I am but too happy to remain here until the quadrilles
recommence.”
At this moment the band began a waltz, a sweet, bird-like
clarionet pouring out its enchanting sounds, and the young girl
bounded from her seat.
“Come, Mr. Freeman, I cannot resist that!” cried she laughing. “I
must surely have been bitten by a tarantula.”
Harry drew back, and an expression of pain and anger crossed
his face as he watched Minnie and her partner, who glanced at him
with a look of haughty triumph.
A hand was laid upon his arm, and Kate Linden stood beside him.
“As much as I dislike him, Harry, I must put Minnie in the wrong. For
God’s sake, let there be no quarrels between men—I will speak to
Minnie. She loves you dearly, but—”
“She loves adulation more,” said he bitterly. “Would to God I
were not so madly fond!”
But the dance ended and Minnie returned to her place, with
brightened eyes and flushed cheeks. Sending her companion for an
ice, she turned to Harry.
“Now I will dance with you, patient creature, if you will wait a
little longer.”
“You are very kind,” said he, more bitterly than before.
She started and looked at him, but laughed lightly as she said—
“You are very particular in commending my goodness, but you do
not seem pleased.”
“No, Minnie; for I am too unhappy to conceal it,” was his reply. “I
had thought you loved me better.”
“And since I did confess that love,” said she haughtily, and
coloring deeply, “by what right do you doubt it?”
“Ask others beside myself, Minnie; ask all the world here, if this
very hour you have not given me cause to think myself weighed in
the balance with another?”
“You are jealous then. I had not deemed your breast capable of
harboring so base a passion,” said she scornfully. “My actions are yet
uncontrolled, and I must beg leave to decline any dictation of terms
from your lips.”
He turned pale with suffering, but remembered her youth, and
calmly met her eye.
“You do me injustice, Minnie; I had no such intention I assure
you.”
At this moment Mr. Freeman handed her a plate of frozen
strawberries, and a smile flitted over his features as he remarked
their own. It was evident to him—there had been a dispute and he
chose the opportunity. Quietly approaching the musicians, he gave
them an order, and they began a mazourka then much in vogue.
Harry’s head was turned away, and Minnie gave him a hurried glance
as a most melodious voice was entreating her to dance.
“Ah!” said Mr. Freeman, smiling and gazing at her, “is it forbidden
already?”
“I do not understand,” replied she in some confusion; but when
Harry looked up she was gliding over the floor again, after reminding
him of his own invitation. He rushed from the room, and making his
adieus to Mrs. Bliss, drove rapidly home. It was not easy to imagine
his state of mind, but Kate followed her sister until the mazourka
ended, to warn her of a coming storm. Taking her arm, she bowed
coldly to Mr. Freeman, who bit his lip and fell back among a group of
gentlemen, some of whom had heard his wager and now laughed at
his defeat.
“Defeat,” echoed he. “I have driven il caro off in despair, and a
few words more will settle all between the charming Minnie and
myself. Not that I care particularly for her, but rejoice in the downfall
of Mr. Harry Selby.”
“Nous verrons,” said a young man, who surveyed him with a look
of disgust. “Miss de la Croix may like to flirt, but she loves Mr. Selby
more. And I for one doubt your success.”
“Had I but one quarter of an hour alone with her, she would no
longer dream of him. She loves me now, and I will prove it yet.”
Some one touched him as he walked away, and Paul Linden
beckoned him to another room.
“My sister’s name is not to be sullied by such lips as yours, Mr.
Freeman. I hold you accountable for what I have heard to-night, and
trust you to prepare yourself to be made so.”
They passed into the street, and angry words rose between
them, but when once more Minnie’s name was pronounced, Paul
passed his hand across the face of the speaker and left him.
Poor Kate! little knew she the “business” that detained him the
next day, and when at length Blanche came to her with a white face
and trembling lips to prepare her for the dreadful news, she seemed
unable to understand until it had been repeated—that her own
husband was dangerously, though not mortally wounded, in a duel
with Mr. Freeman.
With a loud shriek she became insensible, and thus they lifted
her into the carriage, while the rest followed. Paul had been
conveyed to her aunt’s, and there lay weak and fainting from pain
and loss of blood. The ball had been extracted, and his poor Kate
was told to be calm! lest her agony prove fatal to the one she loved
beyond all earthly things. Calm! when her heart was torn and
bleeding, when there was perhaps no chance of his recovery! But
woman-like, she strove against her misery and bent down to kiss
him, half fainting as she gazed at his pale face. He turned to her
with such a look of love!
“Do not blame me, Kate, I would have died to spare you a
moment’s unhappiness, as careless as this may seem of your
feelings,” murmured he.
“Hush, Paul! for God’s sake hush!” cried she clasping his hand.
“Do I not know your love for me? Do not speak my own husband—
be assured that I would never blame you. But for my own happiness
be careful and follow the doctor’s advice—be quiet.”
He fell asleep with his hand in hers, and she sat beside him
motionless as a statue, the big tears falling over her face the while.
She knew how much she had at stake, she knew by what a mere
thread that precious life was hung, but she nerved herself to restrain
her wretchedness, to keep silent her torturing fears, and tried to
hope. Poor Minnie! throwing herself upon her knees she entreated
her forgiveness for the pain she had caused—the tempest of grief
her fault had raised. Kate gently put her head against her breast.
“My poor Minnie! my darling! who could refuse your forgiveness?
God knows you are suffering sufficiently now—but oh! if he should
die!” Her composure gave way out of her husband’s presence, and
her convulsive sobs seemed too much for her strength. They
gathered around her frightened and weeping, beseeching her to
cease, lest her cries reached Paul himself. A composing draught at
length relieved her, and this was her last indulgence of her sorrow
while a prey to such anguish as in vain assailed her. From that day
her fortitude never forsook her, and neither loss of sleep or appetite
were able to affect her. Minnie shared her vigils—both were mere
shadows of their former selves, both watching with pale faces and
sunken eyes the patient sufferer. Minnie left the room only when
Harry Selby’s watch came round. She had not seen him since the
fatal evening, nor mentioned his name after writing him when the
meeting took place. It was a touching letter, and Harry bowed his
head over it with a burst of manly grief. It ran thus:
“I write to say that you are free—you cannot but wish it,
after what has passed. You cannot but hate one so
apparently void of all feeling—so wickedly frivolous. Forgive
me for the pain I cause you, God knows I am in need of
pity! Should the worst happen, I will be guilty of my
brother’s blood, a thought that maddens me. Farewell, I will
always pray for your happiness.
“Minnie de la Croix.”
And she drooped day by day, with a weight of iron on her soul.
Her sister’s sorrow—Paul’s suffering, and the separation from her
young heart’s treasure were cankers, to eat away its hopes, and
wither its freshness. Her father, too—how much he had changed,
how gray he had become! How sad her sisters were, how gravely
Kenneth spoke! The thought of their now deserted home, of its once
happy aspect. She thought of its cheerful, merry-hearted inmates,
and the light voices that were now so low and sad. She remembered
her mother and the last blessing, the prayer that they might be
forever united—she remembered the dead infant and Kate’s return—
poor Kate! that she should be the only sufferer! Gladly would she
have laid down her now darkened life for her sister—gladly would
she have sunk into the tomb, to hide her bursting, breaking heart!
One night she sat at the head of Paul Linden’s bed after
entreating Kate to go once around her aunt’s garden and breathe
the sweet spring air. Her face was buried in her hands, and by the
deep sighs that shook her frame a portion of that young creature’s
misery might be conceived. On the opposite side of the bed sat
another, watching her, by the darkened light of the sick room, with a
look of deep compassion. He had entered unperceived, and there
was a start of surprise as his eyes fell upon the drooped figure. He
could never mistake it—he knew the outline of that once loved form
—he knew the little hands that were clasped across her knees, and
he held his breath least even that should rouse her. Involuntarily he
held out his arms, but at a movement from the invalid she sprung to
his side, and her companion bent down to raise him as he asked for
some water. Minnie held the glass to his lips, and replaced it on the
table without raising her eyes to his face, for she thought it was
Kenneth; when she turned to seat herself her eyes fell upon the
figure of him she loved! The blood forsook her cheeks, and with a
low smothered cry she covered her face once more. When she
looked again he was still there, and his hand was held out
beseechingly toward her. Slowly she gave him hers, it was no bond
of renewed faith, she thought merely that he offered her
forgiveness, and he seemed now further from her than ever, as she
remembered this and looked at the wounded man upon the bed.
Sick at heart she sunk back upon her chair and buried her head in
the clothes. The silence around them was painful now in the
extreme, and Paul’s heavy breathing fell like a reproach upon her
tortured heart. Years seemed to pass, and when Blanche came in to
take her place, she breathed a prayer of thankfulness for the relief a
change afforded.
She hurried from the room out into the garden to give vent to
her wretchedness. She had then seen him again—seen him, she
resolved for the last time. She had suffered too much for the last
half hour to dare it again, and she dwelt upon the remembrance of
his loved features as if to impress them more deeply yet upon her
heart. Alas! how wildly she clung to him, now that she had bid him a
last farewell! how intense grew the love she had lavished upon him
with a woman’s bounty! She returned no more that night to her
brother’s chamber, for she knew who watched beside him, but the
lowly vigil she kept within her own was an eternity of grief.
Toward daylight Lisa entered with a face of joy. Clasping Minnie
in her arms, she burst into tears as she spoke.
“Minnie, my poor child! he is saved! saved at last!”
She sunk upon the floor in a swoon, and during Paul’s
convalescence, another of the household lay at death’s door. Day
after day her fearful ravings smote their heavy hearts, and a gloom
seemed hanging like a vast pall over them. Father, brothers and
sisters, grew pale and thin; but there sat one beside that bed who
seemed to grow old as he looked upon the distorted countenance of
his Minnie. His poor blighted flower!
The physicians did not despair, but they did not bid them hope,
and so a week passed—a week that dragged by like a lengthened
chain that overpowered them. Then there came a gleam of light—
And Minnie opened her eyes once more to life. Who can tell their
joy—their prayers of thankfulness as at length she knew them all? At
the door now, sat her lover, not daring to enter lest his presence
prove fatal, but as the tones of her sweet feeble voice reached him,
he leaned against the wall for support. Rose wept silently at his side,
and pressed his hand as he called on Minnie’s name——they might
yet be happy!
Minnie’s first coherent inquiry was for Paul Linden, and the news
of his recovery was the first and surest step to her own. He came to
see her as soon as he heard it, and tenderly kissing that pale thin
cheek, remained sitting by her with his hand in hers.
“Will you forgive me, Paul?” she asked, her eyes filling with tears.
“Dear child,” replied he tenderly, “did you imagine all this time
that I could ever do aught but love you? So do not speak of
forgiveness again, we are all too happy at your recovery to think of
any thing but joy.”
How gratefully Minnie listened to all this, and how much she
prized the affection each in their turn was striving to prove! She had
awakened from a dream of horror to a new existence. She had
grown wiser—the trial had purified her, and if at times her thoughts
would turn to the happy hours of the past—to the blessing his love
had seemed, she struggled against the regret that stung so sharply,
and bowed her head to the justice of her punishment. It never
occurred to her, poor penitent! that Harry could love her still, she
thought her own conduct fully justified his accepting the freedom
she had offered him, and heavy as the stroke came—deeply as it
was felt, Minnie looked upon it as her due, and bound herself to
suffer in silence—to battle with her troubles.
One morning her father carried her out into the garden, and
seated her under a climbing jessamine that covered a bower at the
side of the house. Few would have recognized the once gay and
blooming girl in the delicate creature that leaned back exhausted in
the chair—few could have realized the active little sprite, the idol of
the ball-room, in this languid, helpless figure; but to her father and
sisters there was something sweeter than ever in their suffering
Minnie. A placid smile overspread her features at the sight of the
sweet flowers that bloomed around her, and she held out her hand
toward a cluster of fragrant Lady Banks that grew near.
“I can tell you a secret of the loveliest bouquet you ever saw,
Minnie,” said Rose, gathering the bunch of tiny roses for her sister.
“A bouquet that was sent an hour ago by a friend of yours and mine.
It is the eighth received to-day, and I reserved this one as a bonne
bouche, after all the rest. Now I am going to get it while you sit
here, and papa will watch you until I get back.”
Her father looked tenderly at his poor bird, and stooped to kiss
her. She smiled so gratefully in return, that the tears sprung to his
eyes.
“We will go home soon, father,” said she, holding his hand; “we
will go back to the old homestead. I pine for my native air like a
caged bird, and long to be there again.”
He assented with a look of joy, for it was the first time she had
mentioned her home, and he fancied she was stronger as she spoke.
Rose came running back with the bouquet, and the sick girl bent
forward to receive it. Rare exotics and simple flowers lay lovingly
together, and round the edge were rows of double violets—sweet
flowers of spring that gladdened her heart. How many times she had
sought them in the thickly bordered beds at home! How often she
had kissed them with childish delight, when the fresh perfume had
come like a message to tell her the spring had breathed upon them.
And now they whispered of the old place and its past joys—of the
time that had elapsed since she had been there, and the warm tears
fell upon the leaves like shining drops of dew.
“And who sent this bouquet, Rose?” asked she, as her father
walked toward the house. “Who sent it?”
“One who loves you dearly, Minnie, and who longs to see you,”
replied she. “Will you let me bring him here, dear sister?”
“Him!” murmured the girl, as the color stole slowly over her
cheek. “Him, Rose!”
A rustling among the leaves was heard—Rose fled, and once
more Harry Selby and Minnie were alone! She gazed at him for a
moment, and burst into tears.
“Harry! why are you here, for God’s sake!” she cried, as he knelt
beside her and wound his arm around the fragile form he had so
longed to see.
“Why am I here, Minnie?” said he reproachfully. “Can you ask
me? Is it not to tell you once more how dear you are to me—how
wretched I have been?”
“You love me still, then?” she said feebly, and fixing her eyes
upon him. “I am not worthy of your love, Harry; I have deserved to
lose it.”
“Minnie! Minnie! say not so! Whom could I ever love as I love
you? Whose memory has followed me through long years but yours
—what torture have I not endured since last we met?”
A look of gladness beamed from those beautiful eyes, and she
clasped her hands together. “My God!” she whispered, “he loves me
then in spite of all!” and she bowed her head upon her knees.
“Loves me! after all that I have caused him and others to suffer.”
“And have you not suffered likewise, my own Minnie? How little
you knew me, if you supposed for an instant that I could ever be
happy without you!”
She learned to know him, reader; she learned to feel how deeply
he loved her, how noble and just he could be, and the next day he
bore her into the carriage that was to take them to Oakwood, and
took his seat opposite to her, that he too might watch her through
the drive.
It was a gala day that—father and sisters, husbands and the
lover, his happy uncle and Mr. and Mrs. Bliss followed Minnie to instal
her with new honors in her old home. Winny and Sampson headed
the procession that came to meet them, and mingled their tears with
the rest. Paul had become a hero to them, Minnie a greater pet than
ever, and they both accepted the ovation as kindly as it was meant.
After dinner, as Minnie sat playing with her beautiful fan, Harry took
it gently from her hand.
“There is a secret in this fan, Minnie, unknown to any but myself.
Shall I unfold it for you?”
She assented, and touching a spring in the little mirror at the
side of the fan, he held it up to her. It disclosed a small, but perfect
miniature of himself!
She gave an exclamation of surprise. “Why, Harry! your own dear
self! Now I know who gave me this fan—now I guess the sender of
this exquisite gift. To think how often I have used it, too, without
knowing its real value.”
He smiled and pressed the soft hand he held. “And do you not
think me a vain fellow, Minnie, mine, for having my own self, set into
a frame like this? See on the other side, dearest, what I dared to
do?”
It flew open there and a ring fell out, a tiny bouquet of the
brightest diamonds upon it, and an opal in the centre that changed
its hue at every motion of the hand. Harry placed the circle upon
that taper finger, and held captive the hand that owned it.
“Now, Minnie! I loved you so dearly that I vowed to strive and
win the very privilege I have taken, of placing this ring upon your
hand myself. I will not let you go until you now tell me when I may
put another where this now is, that will bind us closer yet. Tell me,
Minnie, and make my happiness complete.”
And I suppose that Minnie told him, reader, for the last time I
was at Oakwood there was the happiest bond assembled that earth
can show. Kate, my poor Kate! was the delighted mother of another
girl called Minnie, while a little Paul that ran about had a decided
resemblance to Harry Selby, the proudest man alive. Blanche was
beginning to look matronly with her three treasures, and Rose was
wandering down the avenue with another nephew of Mr. Selby’s.
Lisa, my queen-bee, was herself still—I could not say more for her,
and Mr. de la Croix sat at the hall door watching his children and
grand-children with a happy look. “They have suffered enough,” said
he to me; “but my crown of jewels, my friend, is brighter than ever,
after the breath of adversity for a while dimmed its lustre. Kate and
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com

More Related Content

PDF
Clean Architecture A Craftsman’s Guide to Software Structure and Design by Ro...
PDF
Patterns of Evolutionary Architecture - Agile and Beyond 2018
PDF
Evolutionary architecture
PDF
Ten Advices for Architects
PDF
10 Hinweise für Architekten
PDF
Scott Whitmire - Just What is Architecture Anyway
PPTX
Kits to Find the Bits that Fits
PPT
Architectural Thinking - What Is Architecture?
Clean Architecture A Craftsman’s Guide to Software Structure and Design by Ro...
Patterns of Evolutionary Architecture - Agile and Beyond 2018
Evolutionary architecture
Ten Advices for Architects
10 Hinweise für Architekten
Scott Whitmire - Just What is Architecture Anyway
Kits to Find the Bits that Fits
Architectural Thinking - What Is Architecture?

Similar to Building Evolutionary Architectures Automated Software Governance 2nd Edition Neal Ford (20)

PPT
Chapter 2_Software Architecture.ppt
PPT
Chapter 2_Software Architecture.ppt
PDF
Evolve or Dissolve
PPT
25 architectural adaptation
PDF
An Introductory Session on Enterprise Architecture
PDF
The Changing Role of Software Architecting in the Digital Age
PPTX
2009 scrum & architecture
PPTX
Agile Architecture and Modeling - Where are we Today
PDF
O.Savchenko FWDays workshop Software Architecture
PDF
The Language of Application Architecture
PPTX
Arceneaux
PDF
The Modern Software Architect
PDF
Evolving Software Patterns
PPT
Importance of Software architecture
PPTX
The-Evolution-of-Software-From-Mainframes-to-the-Cloud .pptx
PDF
Modern Evolutionary Software Architectures
PDF
Principles and Techniques of Evolutionary Architecture with Dr. Rebecca Parsons
PDF
Software Architecture in an Agile World
PDF
The Modern Tech Stack: Building Evolvable Architectures
PPTX
Chapter 2_Software Architecture.ppt
Chapter 2_Software Architecture.ppt
Evolve or Dissolve
25 architectural adaptation
An Introductory Session on Enterprise Architecture
The Changing Role of Software Architecting in the Digital Age
2009 scrum & architecture
Agile Architecture and Modeling - Where are we Today
O.Savchenko FWDays workshop Software Architecture
The Language of Application Architecture
Arceneaux
The Modern Software Architect
Evolving Software Patterns
Importance of Software architecture
The-Evolution-of-Software-From-Mainframes-to-the-Cloud .pptx
Modern Evolutionary Software Architectures
Principles and Techniques of Evolutionary Architecture with Dr. Rebecca Parsons
Software Architecture in an Agile World
The Modern Tech Stack: Building Evolvable Architectures
Ad

Recently uploaded (20)

PDF
Hazard Identification & Risk Assessment .pdf
PPTX
Education and Perspectives of Education.pptx
PDF
My India Quiz Book_20210205121199924.pdf
PDF
MBA _Common_ 2nd year Syllabus _2021-22_.pdf
PPTX
Computer Architecture Input Output Memory.pptx
PDF
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 2).pdf
PDF
LIFE & LIVING TRILOGY - PART (3) REALITY & MYSTERY.pdf
PDF
Environmental Education MCQ BD2EE - Share Source.pdf
PDF
English Textual Question & Ans (12th Class).pdf
PDF
LIFE & LIVING TRILOGY - PART - (2) THE PURPOSE OF LIFE.pdf
PDF
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 1)
PDF
Empowerment Technology for Senior High School Guide
PDF
Journal of Dental Science - UDMY (2022).pdf
PDF
1.3 FINAL REVISED K-10 PE and Health CG 2023 Grades 4-10 (1).pdf
PDF
BP 505 T. PHARMACEUTICAL JURISPRUDENCE (UNIT 1).pdf
PDF
CISA (Certified Information Systems Auditor) Domain-Wise Summary.pdf
PDF
IP : I ; Unit I : Preformulation Studies
PDF
Literature_Review_methods_ BRACU_MKT426 course material
PDF
LIFE & LIVING TRILOGY- PART (1) WHO ARE WE.pdf
PDF
HVAC Specification 2024 according to central public works department
Hazard Identification & Risk Assessment .pdf
Education and Perspectives of Education.pptx
My India Quiz Book_20210205121199924.pdf
MBA _Common_ 2nd year Syllabus _2021-22_.pdf
Computer Architecture Input Output Memory.pptx
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 2).pdf
LIFE & LIVING TRILOGY - PART (3) REALITY & MYSTERY.pdf
Environmental Education MCQ BD2EE - Share Source.pdf
English Textual Question & Ans (12th Class).pdf
LIFE & LIVING TRILOGY - PART - (2) THE PURPOSE OF LIFE.pdf
BP 704 T. NOVEL DRUG DELIVERY SYSTEMS (UNIT 1)
Empowerment Technology for Senior High School Guide
Journal of Dental Science - UDMY (2022).pdf
1.3 FINAL REVISED K-10 PE and Health CG 2023 Grades 4-10 (1).pdf
BP 505 T. PHARMACEUTICAL JURISPRUDENCE (UNIT 1).pdf
CISA (Certified Information Systems Auditor) Domain-Wise Summary.pdf
IP : I ; Unit I : Preformulation Studies
Literature_Review_methods_ BRACU_MKT426 course material
LIFE & LIVING TRILOGY- PART (1) WHO ARE WE.pdf
HVAC Specification 2024 according to central public works department
Ad

Building Evolutionary Architectures Automated Software Governance 2nd Edition Neal Ford

  • 1. Building Evolutionary Architectures Automated Software Governance 2nd Edition Neal Ford download https://ebookbell.com/product/building-evolutionary- architectures-automated-software-governance-2nd-edition-neal- ford-50008164 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. Building Evolutionary Architectures Support Constant Change 1st Edition Neal Ford https://ebookbell.com/product/building-evolutionary-architectures- support-constant-change-1st-edition-neal-ford-6724076 Building Evolutionary Architectures Support Constant Change Neal Ford Rebecca Parsons Patrick Kua https://ebookbell.com/product/building-evolutionary-architectures- support-constant-change-neal-ford-rebecca-parsons-patrick- kua-230924664 Odontodes The Developmental And Evolutionary Building Blocks Of Dentitions 1st Edition Donglei Chen https://ebookbell.com/product/odontodes-the-developmental-and- evolutionary-building-blocks-of-dentitions-1st-edition-donglei- chen-53166774 Evolutionary Optimisation Of Faade Design A New Approach For The Design Of Building Envelopes 1st Edition Giovanni Zemella https://ebookbell.com/product/evolutionary-optimisation-of-faade- design-a-new-approach-for-the-design-of-building-envelopes-1st- edition-giovanni-zemella-4661712
  • 3. Building A Revolutionary State The Legal Transformation Of New York 17761783 Howard Pashman https://ebookbell.com/product/building-a-revolutionary-state-the- legal-transformation-of-new-york-17761783-howard-pashman-51438000 Building The Revolutionary Party Jim Percy Selected Writings 198087 Jim Percy https://ebookbell.com/product/building-the-revolutionary-party-jim- percy-selected-writings-198087-jim-percy-2124078 State Building In Revolutionary Ukraine A Comparative Study Of Governments And Bureaucrats 19171922 Stephen Velychenko https://ebookbell.com/product/state-building-in-revolutionary-ukraine- a-comparative-study-of-governments-and-bureaucrats-19171922-stephen- velychenko-51961506 State Building In Revolutionary Ukraine A Comparative Study Of Governments And Bureaucrats 19171922 Stephen Velychenko https://ebookbell.com/product/state-building-in-revolutionary-ukraine- a-comparative-study-of-governments-and-bureaucrats-19171922-stephen- velychenko-43222732 Building Bone Vitality A Revolutionary Diet Plan To Prevent Bone Loss And Reverse Osteoporosiswithout Dairy Foods Calcium Estrogen Or Drugs 1st Edition Amy Lanou https://ebookbell.com/product/building-bone-vitality-a-revolutionary- diet-plan-to-prevent-bone-loss-and-reverse-osteoporosiswithout-dairy- foods-calcium-estrogen-or-drugs-1st-edition-amy-lanou-2368600
  • 6. Building Evolutionary Architectures 2ND EDITION Automated Software Governance Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage
  • 7. Building Evolutionary Architectures by Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage Copyright © 2023 Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editor: Melissa Duffield Development Editor: Virginia Wilson Production Editor: Christopher Faucher Copyeditor: Audrey Doyle Proofreader: Piper Editorial Consulting, LLC Indexer: WordCo Indexing Services, Inc. Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: O’Reilly Media, Inc. October 2017: First Edition December 2022: Second Edition Revision History for the Second Edition 2022-11-22: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781492097549 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Building Evolutionary Architectures, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the authors and do not represent the publisher’s views. While the publisher and the authors have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility for errors or omissions, including without limitation responsibility for
  • 8. damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights. 978-1-492-09754-9 [LSI]
  • 9. Foreword to the First Edition For a long time, the software industry followed the notion that architecture was something that ought to be developed and completed before writing the first line of code. Inspired by the construction industry, it was felt that the sign of a successful software architecture was something that didn’t need to change during development, often a reaction to the high costs of scrap and rework that would occur due to a re-architecture event. This vision of architecture was rudely challenged by the rise of agile software methods. The preplanned architecture approach was founded on the notion that requirements should also be fixed before coding began, leading to a phased (or waterfall) approach where requirements were followed by architecture which itself was followed by construction (programming). The agile world, however, challenged the very notion of fixed requirements, observing that regular changes in requirements were a business necessity in the modern world and providing project planning techniques to embrace controlled change. In this new agile world, many people questioned the role of architecture. And certainly the preplanned architecture vision couldn’t fit in with modern dynamism. But there is another approach to architecture, one that embraces change in the agile manner. In this perspective, architecture is a constant effort, one that works closely with programming so that architecture can react both to changing requirements and to feedback from programming. We’ve come to call this evolutionary architecture, to highlight that while the changes are unpredictable, the architecture can still move in a good direction. At Thoughtworks, we’ve been immersed in this architectural worldview. Rebecca led many of our most important projects in the early years of this millennium and developed our technical leadership as our CTO. Neal has been a careful observer of our work, synthesizing and conveying the lessons we’ve learned. Pat has combined his project work with developing our technical leads. We’ve always felt that architecture is vitally important and can’t be left to idle chance. We’ve made mistakes, but we’ve learned from them, growing a better understanding of how to build a codebase that can respond gracefully to the many changes in its purpose. The heart of doing evolutionary architecture is to make small changes and put in feedback loops that allow everyone to learn from how the system is developing. The rise of Continuous Delivery has been a crucial enabling factor in making evolutionary architecture practical. The authorial trio use the notion of fitness functions to monitor the state of the architecture. They explore different styles of evolvability for architecture and emphasize the issues around long-lived data —often a topic that gets neglected. Conway’s Law towers over much of the discussion, as it should. While I’m sure we have much to learn about doing software architecture in an evolutionary style, this book marks an essential road map for the current state of understanding. As more people are realizing the central role of software systems in our 21st-century human world, knowing how best to respond to change while keeping on your feet will be an essential skill for any software leader. Martin Fowler
  • 11. Foreword to the Second Edition A metaphor attempts to describe similarities between two unrelated things in order to clarify their essential elements. A good example of this is with software architecture. We commonly attempt to describe software architecture by comparing it to the structure of a building. The things that make up the structure of a building—its outer walls, inner walls, roof, room size, number of floors, even the location of the building—all relate to structural elements of software architecture—databases, services, communication protocols, interfaces, deployment location (cloud, on-premises), and so on. The old view is that in both cases these are things that, once in place, are very hard to change later. And that’s exactly where the building metaphor breaks down. Today, the building metaphor for software architecture is no longer a valid one. While it’s still useful to explain what software architecture is to a nontechnical person in terms of comparing the structure of a system, software architecture must be malleable enough to change quickly, which is very different from a physical building. Why must software architecture be so malleable? Because businesses are in a constant state of rapid change, undergoing mergers, acquisitions, new business lines, cost-cutting measures, organizational structures, and so on. However, so is technology, with new frameworks, technical environments, platforms, and products. To properly align with the business and technology environment, software architecture must change as well, and at the same rapid pace. A good example is a major acquisition by a large company. Aside from the myriad business concerns and changes, the software architectures supporting the major business applications must be able to scale to meet the additional customer base and must be both adaptable and extensible to accommodate new business functionality and practices. Many companies already know this but struggle with one thing: how do you make software architecture malleable enough to withstand a fast rate of business and technology change? The answers are found in this book you are about to read. This second edition builds on the concepts of guided and incremental change introduced in the first edition to provide you with the latest techniques, knowledge, and tips on fitness functions, automated architectural governance, and evolutionary data to make sure your software architectures are agile enough to keep up with the constant change we are all experiencing today. Mark Richards developertoarchitect.com October 2022
  • 12. Preface When we wrote the first edition of Building Evolutionary Architectures in 2017, the idea of evolving software architecture was still somewhat radical. During one of her first presentations about the subject, Rebecca was approached afterward by someone accusing her of being professionally irresponsible for suggesting that software architecture can evolve over time—after all, the architecture is the thing that never changes. However, as reality teaches us, systems must evolve to meet new demands of their users and to reflect changes in the constantly shifting software development ecosystem. When the first edition was published, few tools existed to take advantage of the techniques we describe. Fortunately, the software development world keeps evolving, including many more tools to make building evolutionary architectures easier. The Structure of This Book We changed the structure from the first edition to more clearly delineate the two main topics: the engineering practices for evolving software systems and the structural approaches that make it easier. In Part I, we define the various mechanisms and engineering practices that teams can use to implement the goals of evolutionary architecture, including techniques, tools, categories, and other information readers need to understand this topic. Software architecture also involves structural design, and some design decisions make evolution (and governance) easier. We cover this in Part II, which also includes coverage of architecture styles as well as design principles around coupling, reuse, and other pertinent structural considerations. Virtually nothing in software architecture exists in isolation; many principles and practices in evolutionary architecture involve the holistic entanglement of many parts of the software development process, which we cover in Part III. Case Studies and PenultimateWidgets We highlight a number of case studies in this book. All four authors were (and some still are) consultants while working on the material in this book, and we used our real-world experience to derive many of the case studies that appear here. While we can’t divulge the details for particular clients, we wanted to provide some relevant examples to make the topic less abstract. Thus, we adopted the idea of a surrogate company, PenultimateWidgets, as the “host” for all our case studies.
  • 13. In the second edition, we also solicited case studies from our colleagues, which further highlight examples of applying the techniques we discuss. Throughout the book, each case study appears as one from PenultimateWidgets, but each comes from a real project. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values determined by context. TIP This element signifies a tip or suggestion. NOTE This element signifies a general note. WARNING This element indicates a warning or caution. Using Code Examples Supplemental material (code examples, exercises, etc.) is available for download at http://evolutionaryarchitecture.com.
  • 14. If you have a technical question or a problem using the code examples, please send email to bookquestions@oreilly.com. This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission. We appreciate, but generally do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Building Evolutionary Architectures, 2nd edition, by Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage (O’Reilly). Copyright 2023 Neal Ford, Rebecca Parsons, Patrick Kua, and Pramod Sadalage, 978-1-492-09754-9.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com. O’Reilly Online Learning NOTE For more than 40 years, O’Reilly Media has provided technology and business training, knowledge, and insight to help companies succeed. Our unique network of experts and innovators share their knowledge and expertise through books, articles, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, visit https://oreilly.com. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472
  • 15. 800-998-9938 (in the United States or Canada) 707-829-0515 (international or local) 707-829-0104 (fax) We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at https://oreil.ly/evolutionary-arch-2e. Email bookquestions@oreilly.com to comment or ask technical questions about this book. For news and information about our books and courses, visit https://oreilly.com. Find us on LinkedIn: https://linkedin.com/company/oreilly-media. Follow us on Twitter: https://twitter.com/oreillymedia. Watch us on YouTube: https://youtube.com/oreillymedia. Additional Information The authors maintain a companion website for this book at http://evolutionaryarchitecture.com. Acknowledgments The authors would like to give vociferous thanks to our colleagues who provided the outlines and inspirations for the many fitness function case studies presented within. In no particular order, thanks to Carl Nygard, Alexandre Goedert, Santhoshkumar Palanisamy, Ravi Kumar Pasumarthy, Indhumathi V., Manoj B. Narayanan, Neeraj Singh, Sirisha K., Gireesh Chunchula, Madhu Dharwad, Venkat V., Abdul Jeelani, Senthil Kumar Murugesh, Matt Newman, Xiaojun Ren, Archana Khanal, Heiko Gerin, Slin Castro, Fernando Tamayo, Ana Rodrigo, Peter Gillard- Moss, Anika Weiss, Bijesh Vijayan, Nazneen Rupawalla, Kavita Mittal, Viswanath R., Dhivya Sadasivam, Rosi Teixeira, Gregorio Melo, Amanda Mattos, and many others whose names we failed to capture. Neal would like to thank all the attendees of the various conferences at which he has spoken over the last few years to help hone and revise this material in person and especially online, due to the unusual circumstances of a global pandemic. Thanks to all the front-line workers who stepped up bravely to help us all through this difficult time. He would also like to thank the technical reviewers who went above and beyond to provide excellent feedback and advice. Neal would also like to thank his cats, Amadeus, Fauci, and Linda Ruth, for providing useful distractions that often led to insights. Cats never dwell on the past or future; they are always in the current moment, so he uses his time with them to join their presence in the here and now. Thanks also to our outdoor neighborhood “cocktail club,” which started as a community way to see friends and has evolved into the neighborhood brain trust. And finally, Neal would like to thank his long- suffering wife, who endures his travel, and then the abrupt absence of travel, and other
  • 16. professional indignities with a smile. Rebecca would like to thank all the colleagues, conference attendees and speakers, and authors who have, over the years, contributed ideas, tools, and methods and asked clarifying questions about the field of evolutionary architecture. She echoes Neal’s thanks to the technical reviewers for their careful reading and commentary. Further, Rebecca would like to thank her coauthors for all the enlightening conversations and discussions while working together on this book. In particular, she thanks Neal for the great discussion, or perhaps debate, they had several years ago regarding the distinction between emergent and evolutionary architecture. These ideas have come a long way since that first conversation. Patrick would like to thank all his colleagues and customers at ThoughtWorks, who have driven the need and provided the test bed to articulate the ideas in building evolutionary architecture. He also would like to echo Neal’s and Rebecca’s thanks to the technical reviewers, whose feedback helped to improve the book immensely. Finally, he would like to thank his coauthors for the past several years and for the opportunity to work closely together on this topic, despite the numerous time zones and flights that made meeting in person the rare occasion. Pramod would like to thank all his colleagues and clients who have always provided the space and time to explore new ideas and to push new ideas and thinking. He would like to thank his coauthors for thoughtful discussions ensuring that all aspects of architecture are considered. He also would like to thank the reviewers—Cassandra Shum, Henry Matchen, Luca Mezzalira, Phil Messenger, Vladik Khononov, Venkat Subramanium, and Martin Fowler—for thoughtful comments that helped the authors immensely. And finally, he would like to thank his daughters, Arula and Arhana, for the joy they bring into his life, and his wife, Rupali, for all her love and support.
  • 17. Part I. Mechanics Evolutionary architecture consists of broad areas of inquiry: mechanics and structure. The mechanics of evolutionary architecture concern the engineering practices and verification that allow an architecture to evolve, which overlap architectural governance. This covers engineering practices, testing, metrics, and a host of other moving parts that make evolving software possible. Part I defines and presents numerous examples of the mechanics of evolutionary architecture. The other aspect of Building Evolutionary Architectures concerns the structure or topology of software systems. Do some architecture styles better facilitate building systems that are easier to evolve? Are there structural decisions in architecture that should be avoided to make evolution easier? We answer these and other questions in Part II, which concerns structuring architecture for evolution. Many of the facets of building evolutionary architectures combine both mechanics and structure; Part III of the book is titled “Impact.” It includes many case studies, provides advice, and covers patterns and antipatterns as well as other considerations architects and teams need to be aware of to make evolution possible.
  • 18. Chapter 1. Evolving Software Architecture Building systems that age gracefully and effectively is one of the enduring challenges of software development generally and software architecture specifically. This book covers two fundamental aspects of how to build evolvable software: utilizing effective engineering practices derived from the agile software movement and structuring architecture to facilitate change and governance. Readers will grow to understand the state of the art in how to manage change in architecture in a deterministic way, unifying previous attempts at providing protection for architecture characteristics and actionable techniques to improve the ability to change architecture without breaking it. The Challenges of Evolving Software bit rot: also known as software rot, code rot, software erosion, software decay, or software entropy, is either a slow deterioration of software quality over time or its diminishing responsiveness that will eventually lead to software becoming faulty. Teams have long struggled with building high-quality software that remains high quality over time, including adages that reflect this difficulty, such as the varied definitions of bit rot shown above. At least two factors drive this struggle: the problems of policing all the various moving parts in complex software, and the dynamic nature of the software development ecosystem. Modern software consists of thousands or millions of individual parts, each of which may be changed along some set of dimensions. Each of those changes has predictable and sometimes unpredictable effects. Teams that attempt manual governance eventually become overwhelmed by the sheer volume of parts and combinatorial side effects. Managing the myriad interactions of software would be bad enough against a static backdrop, but that doesn’t exist. The software development ecosystem consists of all the tools, frameworks, libraries, and best practices—the accumulated state of the art in software development at any given snapshot in time. This ecosystem forms an equilibrium—much like a biological system— that developers can understand and build things within. However, that equilibrium is dynamic— new things come along constantly, initially upsetting the balance until a new equilibrium emerges. Visualize a unicyclist carrying boxes: dynamic because the unicyclist continues to adjust to stay upright, and equilibrium because they continue to maintain balance. In the software development ecosystem, each new innovation or practice may disrupt the status quo, forcing the establishment of a new equilibrium. Metaphorically, we keep tossing more boxes onto the unicyclist’s load, forcing them to reestablish balance.
  • 19. In many ways, architects resemble our hapless unicyclist, constantly both balancing and adapting to changing conditions. The engineering practices of Continuous Delivery represent such a tectonic shift in the equilibrium: incorporating formerly siloed functions such as operations into the software development lifecycle enabled new perspectives on what change means. Enterprise architects can no longer rely on static, five-year plans because the entire software development universe will evolve in that time frame, rendering every long-term decision potentially moot. Disruptive change is hard to predict even for savvy practitioners. The rise of containers via tools like Docker is an example of an unknowable industry shift. However, we can trace the rise of containerization via a series of small, incremental steps. Once upon a time, operating systems, application servers, and other infrastructure were commercial entities, requiring licensing and great expense. Many of the architectures designed in that era focused on efficient use of shared resources. Gradually, Linux became good enough for many enterprises, reducing the monetary cost of operating systems to zero. Next, DevOps practices like automatic machine provisioning via tools like Puppet and Chef made Linux operationally free. Once the ecosystem became free and widely used, consolidation around common portable formats was inevitable: thus, Docker. But containerization couldn’t have happened without all the evolutionary steps leading to that end. The software development ecosystem constantly evolves, which leads to new architectural approaches. While many developers suspect that a cabal of architects retreat to an ivory tower to decide what the Next Big Thing will be, the process is much more organic. New capabilities constantly arise within our ecosystem, providing new ways to combine with existing and other new features to enable new capabilities. For example, consider the recent rise of microservices architectures. As open source operating systems became popular, combined with Continuous Delivery–driven engineering practices, enough clever architects figured out how to build more scalable systems that they eventually needed a name: thus, microservices. WHY WE DIDN’T HAVE MICROSERVICES IN THE YEAR 2000 Consider an architect with a time machine who travels back in time to the year 2000 and approaches the head of operations with a new idea. “I have a great new concept for an architecture that allows fantastic isolation between each of the capabilities—it’s called microservices; we’ll design each service around business capabilities and keep things highly decoupled.” “Great,” says the head of operations. “What do you need?” “Well, I’m going to need about 50 new computers, and of course 50 new operating system licenses, and another 20 computers to act as isolated databases, along with licenses for those. When do you think I can get all that?” “Please leave my office.” While microservices might have seemed like a good idea even back then, the ecosystem wasn’t available to support it.
  • 20. A portion of an architect’s job is structural design to solve particular problems—you have a problem, and you’ve decided that software will solve it. When considering structural design, we can partition it into two areas: the domain (or requirements) and architecture characteristics, as illustrated in Figure 1-1. Figure 1-1. The entire scope of software architecture encompasses requirements plus architecture characteristics: the “-ilities” of software The requirements shown in Figure 1-1 represent whatever problem domain the software solution addresses. The other parts are variously known as architecture characteristics (our preferred term), nonfunctional requirements, system quality attributes, cross-cutting requirements, and a host of other names. Regardless of the name, they represent critical capabilities required for project success, both for initial release and long-term maintainability. For example, architecture characteristics such as scale and performance may form success criteria for a market, whereas others such as modularity contribute to maintainability and evolvability. THE MANY NAMES OF ARCHITECTURE CHARACTERISTICS We use the term architecture characteristics throughout the book to refer to nondomain design considerations. However, many organizations use other terms for this concept, among them nonfunctional requirements, cross-cutting requirements, and system quality attributes. We don’t have a strong preference for one term over another—feel free to translate our term to yours anywhere you see it in the book. These are not distinct concepts. Software is rarely static; it continues to evolve as teams add new features, integration points, and a host of other common changes. What architects need are protection mechanisms for architecture characteristics, similar to unit tests but focused on architecture characteristics, which change at a different rate and are sometimes subject to forces that are different from the domain. For example, technical decisions within a company may drive a database change that is independent of the domain solution. This book describes the mechanisms and design techniques for adding the same kind of continual assurance about architectural governance that high-performing teams now have about other aspects of the software development process. Architectural decisions are ones in which each choice offers significant trade-offs. Throughout this book, when we refer to the role of architect, we encompass anyone who makes architectural decisions, regardless of their title in an organization. Additionally, important architecture decisions virtually always require collaboration with other roles.
  • 21. DO AGILE PROJECTS NEED ARCHITECTURE? This is a common question asked of those who have utilized agile engineering practices for a while. The goal of agility is to remove useless overhead, not necessary steps such as design. As in many things in architecture, the scale dictates the level of architecture. We use the analogy of building—if we want to build a dog house, we don’t need an elaborate architecture; we just need materials. On the other hand, if we need to build a 50-story office building, design must occur. Similarly, if we need a website to track a simple database, we don’t need an architecture; we can find materials that enable us to piece it together. However, we must carefully consider many trade-offs to design a highly scalable and available website, such as a high-volume concert ticketing website. Rather than the question Do Agile projects need architecture?, the question for architects lies in how little unnecessary design they can afford, while building the ability to iterate on early designs to work toward more suitable solutions. Evolutionary Architecture Both the mechanisms for evolution and the decisions architects make when designing software derive from the following definition: An evolutionary software architecture supports guided, incremental change across multiple dimensions. The definition consists of three parts, which we describe in more detail below. Guided Change Once teams have chosen important characteristics, they want to guide changes to the architecture to protect those characteristics. For that purpose, we borrow a concept from evolutionary computing called fitness functions. A fitness function is an objective function used to summarize how close a prospective design solution is to achieving the set aims. In evolutionary computing, the fitness function determines whether an algorithm has improved over time. In other words, as each variant of an algorithm is generated, the fitness functions determine how “fit” each variant is, based on how the designer of the algorithm defined “fit.” We have a similar goal in evolutionary architecture: as architecture evolves, we need mechanisms to evaluate how changes impact the important characteristics of the architecture and prevent degradation of those characteristics over time. The fitness function metaphor encompasses a variety of mechanisms we employ to ensure architecture doesn’t change in undesirable ways, including metrics, tests, and other verification tools. When an architect identifies an architectural characteristic they want to protect as things evolve, they define one or more fitness functions to protect that feature. Historically, a portion of architecture has often been viewed as a governance activity, and
  • 22. architects have only recently accepted the notion of enabling change through architecture. Architectural fitness functions allow decisions in the context of the organization’s needs and business functions, while making the basis for those decisions explicit and testable. Evolutionary architecture is not an unconstrained, irresponsible approach to software development. Rather, it is an approach that balances the need for rapid change and the need for rigor around systems and architectural characteristics. The fitness function drives architectural decision making, guiding the architecture while allowing the changes needed to support changing business and technology environments. We use fitness functions to create evolutionary guidelines for architectures; we cover them in detail in Chapter 2. Incremental Change Incremental change describes two aspects of software architecture: how teams build software incrementally and how they deploy it. During development, an architecture that allows small, incremental changes is easier to evolve because developers have a smaller scope of change. For deployment, incremental change refers to the level of modularity and decoupling for business features and how they map to architecture. An example is in order. Let’s say that PenultimateWidgets, a large seller of widgets, has a catalog page backed by a microservices architecture and modern engineering practices. One of the page’s features enables users to rate different widgets with star ratings. Other services within PenultimateWidgets’ business also need ratings (customer service representatives, shipping provider evaluation, etc.), so they all share the star rating service. One day, the star rating team releases a new version alongside the existing one that allows half-star ratings—a small but significant upgrade. The other services that require ratings aren’t required to move to the new version but to gradually migrate as convenient. Part of PenultimateWidgets’ DevOps practices include architectural monitoring of not only the services but also the routes between services. When the operations group observes that no one has routed to a particular service within a given time interval, they automatically disintegrate that service from the ecosystem. This is an example of incremental change at the architectural level: the original service can run alongside the new one as long as other services need it. Teams can migrate to new behavior at their leisure (or as need dictates), and the old version is automatically garbage collected. Making incremental change successful requires coordination of a handful of Continuous Delivery practices. Not all of these practices are required in all cases; rather, they commonly occur together in the wild. We discuss how to achieve incremental change in Chapter 3. Multiple Architectural Dimensions There are no separate systems. The world is a continuum. Where to draw a boundary around a system depends on the purpose of the discussion.
  • 23. —Donella H. Meadows Classical Greek physicists gradually learned to analyze the universe based on fixed points, culminating in classical mechanics. However, more precise instruments and more complex phenomena gradually refined that definition toward relativity in the early 20th century. Scientists realized that what they previously viewed as isolated phenomena in fact interact relative to one another. Since the 1990s, enlightened architects have increasingly viewed software architecture as multidimensional. Continuous Delivery expanded that view to encompass operations. However, software architects often focus primarily on technical architecture—how the software components fit together—but that is only one dimension of a software project. If architects want to create an architecture that can evolve, they must consider all the interconnected parts of the system that change affects. Just like we know from physics that everything is relative to everything else, architects know there are many dimensions to a software project. To build evolvable software systems, architects must think beyond just the technical architecture. For example, if the project includes a relational database, the structure and relationship between database entities will evolve over time as well. Similarly, architects don’t want to build a system that evolves in a manner that exposes a security vulnerability. These are all examples of dimensions of architecture—the parts of architecture that fit together in often orthogonal ways. Some dimensions fit into what are often called architectural concerns (the list of “-ilities” referred to earlier), but dimensions are actually broader, encapsulating things traditionally outside the purview of technical architecture. Each project has dimensions the architect role must consider when thinking about evolution. Here are some common dimensions that affect evolvability in modern software architectures: Technical The implementation parts of the architecture: the frameworks, dependent libraries, and implementation language(s). Data Database schemas, table layouts, optimization planning, and so on. The database administrator generally handles this type of architecture. Security Defines security policies and guidelines, and specifies tools to help uncover deficiencies. Operational/System Concerns how the architecture maps to existing physical and/or virtual infrastructure: servers, machine clusters, switches, cloud resources, and so on. Each of these perspectives forms a dimension of the architecture—an intentional partitioning of the parts supporting a particular perspective. Our concept of architectural dimensions encompasses traditional architectural characteristics (“-ilities”) plus any other role that
  • 24. contributes to building software. Each of these forms a perspective on architecture that we want to preserve as our problem evolves and the world around us changes. When architects think in terms of architectural dimensions, it provides a mechanism by which they can analyze the evolvability of different architectures by assessing how each important dimension reacts to change. As systems become more intertwined with competing concerns (scalability, security, distribution, transactions, etc.), architects must expand the dimensions they track on projects. To build an evolvable system, architects must think about how the system might evolve across all the important dimensions. The entire architectural scope of a project consists of the software requirements plus the other dimensions. We can use fitness functions to protect those characteristics as the architecture and the ecosystem evolve together through time, as illustrated in Figure 1-2. Figure 1-2. An architecture consists of requirements and other dimensions, each protected by fitness functions In Figure 1-2, the architects have identified auditability, data, security, performance, legality, and scalability as the additional architectural characteristics important for this application. As the business requirements evolve over time, each of the architectural characteristics utilizes fitness functions to protect its integrity as well. While the authors of this text stress the importance of a holistic view of architecture, we also realize that a large part of evolving architecture concerns technical architecture patterns and related topics like coupling and cohesion. We discuss how technical architecture coupling affects
  • 25. evolvability in Chapter 5 and the impacts of data coupling in Chapter 6. Coupling applies to more than just structural elements in software projects. Many software companies have recently discovered the impact of team structure on surprising things like architecture. We discuss all aspects of coupling in software, but the team impact comes up so early and often that we need to discuss it here. Evolutionary architecture helps answer two common questions that arise among architects in the modern software development ecosystem: How is long-term planning possible when everything changes all the time? and Once I’ve built an architecture, how can I prevent it from degrading over time? Let’s explore these questions in more detail. How Is Long-Term Planning Possible When Everything Changes All the Time? The programming platforms we use exemplify constant evolution. Newer versions of a programming language offer better APIs to improve the flexibility of or applicability to new problems; newer programming languages offer a different paradigm and different set of constructs. For example, Java was introduced as a C++ replacement to ease the difficulty of writing networking code and to improve memory management issues. When we look at the past 20 years, we observe that many languages still continually evolve their APIs while totally new programming languages appear to regularly attack newer problems. The evolution of programming languages is demonstrated in Figure 1-3. Figure 1-3. The evolution of popular programming languages Regardless of the particular aspect of software development—the programming platform, languages, operating environment, persistence technologies, cloud offerings, and so on—we expect constant change. Although we cannot predict when changes in the technical or domain landscape will occur, or which changes will persist, we know change is inevitable. Consequently,
  • 26. we should architect our systems knowing the technical landscape will change. If the ecosystem constantly changes in unexpected ways, and if predictability is impossible, what is the alternative to fixed plans? Enterprise architects and other developers must learn to adapt. Part of the traditional reasoning behind making long-term plans was financial; software changes were expensive. However, modern engineering practices invalidate that premise by making change less expensive through the automation of formerly manual processes and other advances such as DevOps. For years, many smart developers recognized that some parts of their systems were harder to modify than others. That’s why software architecture is defined as “the parts that are hard to change later.” This convenient definition partitioned the things you can modify without much effort from truly difficult changes. Unfortunately, this definition also evolved into a blind spot when thinking about architecture: developers’ assumption that change is difficult becomes a self- fulfilling prophecy. Several years ago, some innovative software architects revisited the “hard to change later” problem: what if we build changeability into the architecture? In other words, if ease of change is a bedrock principle of the architecture, then change is no longer difficult. Building evolvability into architecture in turn allows a whole new set of behaviors to emerge, upsetting the dynamic equilibrium again. Even if the ecosystem doesn’t change, what about the gradual erosion of architectural characteristics that occurs? Architects design architectures but then expose them to the messy real world of implementing things atop the architecture. How can architects protect the important parts they have defined? Once I’ve Built an Architecture, How Can I Prevent It from Degrading Over Time? An unfortunate decay, often called bit rot, occurs in many organizations. Architects choose particular architectural patterns to handle the business requirements and “-ilities,” but those characteristics often accidentally degrade over time. For example, if an architect has created a layered architecture with presentation at the top, persistence at the bottom, and several layers in between, developers who are working on reporting will often ask permission to directly access persistence from the presentation layer, bypassing the other layers, for performance reasons. Architects build layers to isolate change. Developers then bypass those layers, increasing coupling and invalidating the reasoning behind the layers. Once they have defined the important architectural characteristics, how can architects protect those characteristics to ensure they don’t erode? Adding evolvability as an architectural characteristic implies protecting the other characteristics as the system evolves. For example, if an architect has designed an architecture for scalability, they don’t want that characteristic to degrade as the system evolves. Thus, evolvability is a meta-characteristic, an architectural wrapper that protects all the other architectural characteristics.
  • 27. The mechanism of evolutionary architecture heavily overlaps with the concerns and goals of architectural governance—defined principles around design, quality, security, and other quality concerns. This book illustrates the many ways that evolutionary architecture approaches enable automating architectural governance. Why Evolutionary? A common question about evolutionary architecture concerns the name itself: why call it evolutionary architecture and not something else? Other possible terms include incremental, continual, agile, reactive, and emergent, to name just a few. But each of these terms misses the mark. The definition of evolutionary architecture that we state here includes two critical characteristics: incremental and guided. The terms continual, agile, and emergent all capture the notion of change over time, which is clearly a critical characteristic of an evolutionary architecture, but none of these terms explicitly captures any notion of how an architecture changes or what the desired end-state architecture might be. While all the terms imply a changing environment, none of them covers what the architecture should look like. The guided part of our definition reflects the architecture we want to achieve—our end goal. We prefer the word evolutionary over adaptable because we are interested in architectures that undergo fundamental evolutionary change, not ones that have been patched and adapted into increasingly incomprehensible accidental complexity. Adapting implies finding some way to make something work regardless of the elegance or longevity of the solution. To build architectures that truly evolve, architects must support genuine change, not jury-rigged solutions. Going back to our biological metaphor, evolutionary concerns the process of having a system that is fit for purpose and can survive the ever-changing environment in which it operates. Systems may have individual adaptations, but as architects, we should care about the overall evolvable system. Another useful comparison architects can make is between evolutionary architecture and emergent design, and why there is not such a thing as an “emergent architecture.” One common misconception about agile software development is the alleged lack of architecture: “Let’s just start coding and the architecture will emerge as we go.” However, this depends on how simple the problem is. Consider a physical building. If you need to build a dog house, you don’t need an architecture; you can go to the hardware store and buy lumber and bang it together. If, on the other hand, you need to build a 50-floor office building, architecture is definitely required! Similarly, if you are building a simple catalog system for a small number of users, you likely don’t need a lot of up-front planning. However, if you are designing a software system that needs strict performance for a large number of users, planning is necessary! The purpose of agile architecture isn’t no architecture; it’s no useless architecture: don’t go through bureaucratic processes that don’t add value to the software development process. Another complicating factor in software architecture is the different types of essential complexity architects must design for. When evaluating trade-offs, it’s often not the easy simple versus
  • 28. complex system distinction but rather systems that are complex in different ways. In other words, each system has a unique set of criteria for success. While we discuss architectural styles such as microservices, each style is a starting point for a complex system that grows to look like no other. Similarly, if an architect builds a very simple system, they can afford to pay little attention to architectural concerns. However, sophisticated systems require purposeful design, and they need a starting point. Emergence suggests that you can start with nothing, whereas architecture provides the scaffolding or structure for all the other parts of the system; something must be in place to begin. The concept of emergence also implies that teams can slowly crescendo their design toward the ideal architectural solution. However, like building architecture, there is no perfect architecture, only different ways architects deal with trade-offs. Architects can implement most problems in a wide variety of different architecture styles and be successful. However, some of them will fit the problem better, offering less resistance and fewer workarounds. One key to evolutionary architecture is the balance between how much structure and governance is necessary to support long-term goals and needless formality and friction. Summary Useful software systems aren’t static. They must grow and change as the problem domain changes and the ecosystem evolves, providing new capabilities and complexities. Architects and developers can gracefully evolve software systems, but they must understand both the necessary engineering practices to make that happen and how best to structure their architecture to facilitate change. Architects are also tasked with governing the software they design, along with many of the development practices used to build it. Fortunately, the mechanisms we uncover to allow easier evolution also provide ways to automate important software governance activities. We take a deep dive into the mechanics of how to make this happen in the next chapter.
  • 29. Chapter 2. Fitness Functions The mechanics of evolutionary architecture cover the tools and techniques developers and architects use to build systems that can evolve. An important gear in that machinery is the protection mechanism called a fitness function, the architectural equivalent of a unit test for the domain part of an application. This chapter defines fitness functions and explains the categories and usage of this important building block. An evolutionary architecture supports guided, incremental change across multiple dimensions. As noted in our definition, the word guided indicates that some objective exists that architecture should move toward or exhibit. We borrow a concept from evolutionary computing called fitness functions, which are used in genetic algorithm design to define success. Evolutionary computing includes a number of mechanisms that allow a solution to gradually emerge via mutation—small changes in each generation of the software. The evolutionary computing world defines a number of types of mutations. For example, one mutation is called a roulette mutation: if the algorithm utilizes constants, this mutation will choose new numbers as if from a roulette wheel in a casino. For example, suppose a developer is designing a genetic algorithm to solve the traveling salesperson problem to find the shortest route between a number of cities. If the developer notices that smaller numbers supplied by the roulette mutation yield better results, they may build a fitness function to guide the “decision” during mutation. Thus, fitness functions are used to evaluate how close a solution is to ideal. What Is a Fitness Function? We borrow this concept of fitness functions from the evolutionary computing world to define an architectural fitness function: An architectural fitness function is any mechanism that provides an objective integrity assessment of some architectural characteristic(s). Architectural fitness functions form the primary mechanisms for implementing evolutionary architecture. As the domain part of our solution evolves, teams have developed a wide variety of tools and techniques to manage integrating new features without breaking existing ones: unit, functional, and user acceptance testing. In fact, most companies bigger than a certain size have an entire department dedicated to managing domain evolution, called quality assurance: ensuring that existing functionality isn’t negatively affected by changes. Thus, well-functioning teams have mechanisms for managing evolutionary change to the problem domain: adding new features, changing behaviors, and so on. The domain is typically
  • 30. written in a fairly coherent technology stack: Java, .NET, or a host of other platforms. Thus, teams can download and use testing libraries suited to their combination of technology stacks. Fitness functions are to architecture characteristics as unit tests are to the domain. However, teams cannot download a single tool for the wide variety of validations possible for architecture characteristics. Rather, fitness functions encompass a wide variety of tools in different parts of the ecosystem, depending on the architecture characteristics the team is governing, as illustrated in Figure 2-1. Figure 2-1. Fitness functions encompass a wide variety of tools and techniques As shown in Figure 2-1, architects can use many different tools to define fitness functions: Monitors DevOps and operational tools such as monitors allow teams to verify concerns such as performance, scalability, and so on. Code metrics Architects can embed metrics checks and other verifications within unit tests to validate a wide variety of architecture concerns, including design criteria (many examples follow in Chapter 4). Chaos engineering This recently developed branch of engineering practices artificially stresses remote environments by injecting faults to force teams to build resiliency into their systems. Architecture testing frameworks In recent years, testing frameworks dedicated to testing architecture structure have appeared, allowing architects to encode a wide variety of validations into automated tests. Security scanning
  • 31. Security—even if supervised by another part of the organization—affects design decisions that architects make and thus falls under the umbrella of concerns that architects want to govern. Before we define the categories of fitness functions and other factors, an example will help make the concept less abstract. The component cycle is a common antipattern across all platforms with components. Consider the three components in Figure 2-2. Figure 2-2. A cycle exists when components have a cyclic dependency Architects consider the cyclic dependency shown in Figure 2-2 an antipattern because it presents difficulties when a developer tries to reuse one of the components—each of the entangled components must also come along. Thus, in general, architects want to keep the number of cycles low. However, the universe is actively fighting the architect’s desire to prevent this problem via convenience tools. What happens when a developer references a class whose namespace/package they haven’t referenced yet in a modern IDE? It pops up an auto-import dialog to automatically import the necessary package. Developers are so accustomed to this affordance that they swat it away as a reflex action, never actually paying attention. Most of the time, auto-importing is a great convenience that doesn’t cause any problems. However, once in a while, it creates a component cycle. How do architects prevent this? Consider the set of packages illustrated in Figure 2-3.
  • 32. Figure 2-3. Component cycles represented as packages in Java ArchUnit is a testing tool inspired by (and using some of the facilities of) JUnit, but it’s used to test various architecture features, including validations to check for cycles within a particular scope, as illustrated in Figure 2-3. An example of how to prevent cycles using ArchUnit appears in Example 2-1. Example 2-1. Preventing cycles using ArchUnit public class CycleTest { @Test public void test_for_cycles() { slices(). matching("com.myapp.(*).."). should().beFreeOfCycles() } In this example, the testing tool “understands” cycles. An architect who wants to prevent cycles from gradually appearing in their codebase can wire this testing into a continuous build process and never have to worry about cycles again. We will show more examples of using ArchUnit and similar tools in Chapter 4. We first define fitness functions more rigorously, and then examine conceptually how they guide the evolution of the architecture. Don’t mistake the function part of our definition as implying that architects must express all fitness functions in code. Mathematically speaking, a function takes an input from some allowed set of input values and produces an output in some allowed set of output values. In software, we also generally use the term function to refer to something implementable in code. However, as with acceptance criteria in agile software development, the fitness functions for evolutionary architecture may not be implementable in software (e.g., a required manual process for regulatory reasons). An architectural fitness function is an objective measure, but architects may implement that measure in a wide variety of ways.
  • 33. As discussed in Chapter 1, real-world architecture consists of many different dimensions, including requirements around performance, reliability, security, operability, coding standards, and integration, to name a few. We want a fitness function to represent each requirement for the architecture, requiring us to find (and sometimes create) ways to measure things we want to govern. We’ll look at a few examples and then consider the different kinds of functions more broadly. Performance requirements make good use of fitness functions. Consider a requirement that all service calls must respond within 100 ms. We can implement a test (i.e., fitness function) that measures the response to a service request and fails if the result is greater than 100 ms. To this end, every new service should have a corresponding performance test added to its test suite (you’ll learn more about triggering fitness functions in Chapter 3). Performance is also a good example of the vast number of ways architects can think about common measures. For example, performance may suggest request/response timing, as measured by a mentoring tool, or another metric such as first contentful paint, a mobile device performance metric provided by Lighthouse. The purpose of a performance fitness function is not to measure all types of performance but ones that architects deem important for governance. Fitness functions also can be used to maintain coding standards. A common code metric is cyclomatic complexity, a measure of function or method complexity available for all structured programming languages. An architect may set a threshold for an upper value, guarded by a unit test running in continuous integration, using one of the many tools available to evaluate that metric. Despite need, developers cannot always implement some fitness functions completely because of complexity or other constraints. Consider something like a failover for a database from a hard failure. While the recovery itself might be fully automated (and should be), triggering the test itself is likely best done manually. Additionally, it might be far more efficient to determine the success of the test manually, although developers should still encourage scripts and automation. These examples highlight the myriad forms that fitness functions can take, the immediate response to failure of a fitness function, and even when and how developers might run them. While we can’t necessarily run a single script and say “our architecture currently has a composite fitness score of 42,” we can have precise and unambiguous conversations about the state of the architecture. We can also entertain discussions about the changes that might occur on the architecture’s fitness. Finally, when we say an evolutionary architecture is guided by the fitness function, we mean we evaluate individual architectural choices against the individual and the system-wide fitness functions to determine the impact of the change. The fitness functions collectively denote what matters to us in our architecture, allowing us to make the kinds of trade-off decisions that are both crucial and vexing during the development of software systems. You may think, “Wait! We’ve been running code metrics as part of continuous integration for years—this isn’t new!” You would be correct: the idea of validating parts of software as part of an automated process is as old as automation. However, we formerly considered all the different
  • 34. architecture verification mechanisms as separate—code quality versus DevOps metrics versus security, and so on. Fitness functions unify many existing concepts into a single mechanism, allowing architects to think in a uniform way about many existing (often ad hoc) “nonfunctional requirements” tests. Collecting important architecture thresholds and requirements as fitness functions allows for a more concrete representation for previously fuzzy, subjective evaluation criteria. We leverage a large number of existing mechanisms to build fitness functions, including traditional testing, monitoring, and other tools. Not all tests are fitness functions, but some tests are—if the test helps verify the integrity of architectural concerns, we consider it a fitness function. Categories Fitness functions exist across a variety of categories related to their scope, cadence, result, invocation, proactivity, and coverage. Scope: Atomic Versus Holistic Atomic fitness functions run against a singular context and exercise one particular aspect of the architecture. An excellent example of an atomic fitness function is a unit test that verifies some architectural characteristic, such as modular coupling (we show an example of this type of fitness function in Chapter 4). Thus, some application-level testing falls under the heading of fitness functions, but not all unit tests serve as fitness functions—only the ones that verify architecture characteristic(s). The example in Figure 2-3 represents an atomic fitness function: it checks only for the presence of cycles between components. For some architectural characteristics, developers must test more than each architectural dimension in isolation. Holistic fitness functions run against a shared context and exercise a combination of architectural aspects. Developers design holistic fitness functions to ensure that combined features that work atomically don’t break in real-world combinations. For example, imagine an architecture has fitness functions around both security and scalability. One of the key items the security fitness function checks is staleness of data, and a key item for the scalability tests is number of concurrent users within a certain latency range. To achieve scalability, developers implement caching, which allows the atomic scalability fitness function to pass. When caching isn’t turned on, the security fitness function passes. However, when run holistically, enabling caching makes data too stale to pass the security fitness function, and the holistic test fails. We obviously cannot test every possible combination of architecture elements, so architects use holistic fitness functions selectively to test important interactions. This selectivity and prioritization also allows architects and developers to assess the difficulty in implementing a particular testing scenario, thus allowing an assessment of how valuable that characteristic is. Frequently, the interactions between architectural concerns determine the quality of the architecture, which holistic fitness functions address.
  • 35. Cadence: Triggered Versus Continual Versus Temporal Execution cadence is another distinguishing factor between fitness functions. Triggered fitness functions run based on a particular event, such as a developer executing a unit test, a deployment pipeline running unit tests, or a QA person performing exploratory testing. This encompasses traditional testing, such as unit, functional, and behavior-driven development (BDD) testing, among others. Continual tests don’t run on a schedule but instead execute constant verification of architectural aspect(s), such as transaction speed. For example, consider a microservices architecture in which the architects want to build a fitness function around transaction time—how long it takes for a transaction to complete, on average. Building any kind of triggered test provides sparse information about real-world behavior. Thus, architects build a continual fitness function that simulates a transaction in production while all the other real transactions run, often using a technique called synthetic transactions. This allows developers to verify behavior and gather real data about the system “in the wild.” SYNTHETIC TRANSACTIONS How do teams measure complex, real-world interactions between services in a microservices architecture? One common technique employs synthetic transactions. For this practice, requests into the system have a flag that indicates that a particular transaction may be synthetic. It follows exactly the normal course of interactions in the architecture (often tracked via a correlation ID for forensic analysis) until the last step, where the system evaluates the flag and doesn’t commit the transaction as a real one. This allows architects and DevOps to learn exactly how their complex system performs. No advice about synthetic transactions is complete without mentioning the tale of hundreds of appliances showing up accidentally because someone forgot to flip the “synthetic” flag, which can itself be governed by a fitness function—make sure that any fitness function identified as a synthetic transaction (e.g., via an annotation) has the flag set. Notice that using a monitoring tool does not imply that you have a fitness function, which must have objective outcomes. Rather, using a monitoring tool in which the architect has created an alarm for deviations outside the objective measure of the metric converts the mere use of monitors into a fitness function. Monitoring-driven development (MDD) is another testing technique gaining popularity. Rather than relying solely on tests to verify system results, MDD uses monitors in production to assess both technical and business health. These continual fitness functions are necessarily more dynamic than standard triggered tests and fall into the broader category called fitness function- driven architecture, discussed in more detail in Chapter 7. While most fitness functions trigger either on change or continually, in some cases architects may want to build a time component into assessing fitness, leading to a temporal fitness function. For example, if a project uses an encryption library, the architect may want to create a
  • 36. temporal fitness function as a reminder to check if important updates have been performed. Another common use of this type of fitness function is a break upon upgrade test. In platforms like Ruby on Rails, some developers can’t wait for the tantalizing new features coming in the next release, so they add a feature to the current version via a back port, a custom implementation of a future feature. Problems arise when the project finally upgrades to the new version because the back port is often incompatible with the “real” version. Developers use break upon upgrade tests to wrap back-ported features to force re-evaluation when the upgrade occurs. Another common use of a temporal fitness function comes from an important but not urgent requirement that arises on virtually every project eventually. Many developers have experienced the pain of upgrading more than one major version number of a core framework or library their project depends upon—so many changes occur between major point releases, it’s often quite difficult to leap versions. However, upgrading a core framework is time-consuming and not deemed as critical, making it more likely to accidentally slip too far behind. Architects can use a temporal fitness function in conjunction with a tool like Dependabot or snyk, which tracks releases, versions, and security patches for software, to create increasingly insistent reminders to upgrade once the corporate criteria (e.g., first patch release) have been met. Case Study: Triggered or Continuous? Often the choice of continuous versus triggered fitness function comes down to trade-offs between the approaches. Many developers in distributed systems such as microservices want the same kind of dependency check but on allowed communication between services rather than cycles. Consider the set of services illustrated in Figure 2-4, a more advanced version of the cyclic dependency fitness function shown in Figure 2-3.
  • 37. Figure 2-4. Set of orchestrated microservices, where communication should not exist between nonorchestrator services In Figure 2-4, the architect has designed the system so that the orchestrator service contains the state of the workflow. If any of the services communicates with each other, bypassing the orchestrator, the team won’t have accurate information about the workflow state. In the case of dependency cycles, metrics tools exist to allow architects to do compile-time checks. However, services aren’t constrained to a single platform or technology stack, making it highly unlikely that someone has already built a tool that exactly matches a particular architecture. This is an example of what we alluded to earlier—often, architects must build their own tools rather than rely on third parties. For this particular system, the architect can build
  • 38. either a continuous or a triggered fitness function. In the continuous case, the architect must ensure that each of the services provides monitoring information (typically via a particular port) that broadcasts who the service calls during the course of workflows. Either the orchestrator service or a utility service monitors those messages to ensure that illegal communication doesn’t occur. Alternatively, rather than using monitors, the team could use asynchronous message queues, have each domain service publish a message to the queue indicating collaboration messages, and allow the orchestrator to listen to that queue and validate collaborators. This fitness function is continuous because the receiving service can react immediately to disallowed communication. For example, perhaps this fault indicates a security concern or other detrimental side effect. The benefit of this version of the fitness function is immediate reaction: architects and other interested parties know immediately when governance has been violated. However, this solution adds runtime overhead: monitors and/or message queues require operation resources, and this level of observability may have a negative impact on performance, scalability, and so on. Alternatively, the team may decide to implement a triggered version of this fitness function. In this case, on a regular cadence, the deployment pipeline calls a fitness function that harvests logfiles and investigates communication to determine if it is all appropriate. We show an implementation of this fitness function in “Communication Governance in Microservices”. The benefit of this fitness function is lack of possible runtime impact—it runs only when triggered and looks at log records. However, teams shouldn’t use a triggered version for critical governance issues such as security where the time lag may have negative impacts. As in all things in software architecture, the decision between triggered and continuous fitness functions will often provide different trade-offs, making this a case-by-case decision. Result: Static Versus Dynamic Static fitness functions have a fixed result, such as the binary pass/fail of a unit test. This type encompasses any fitness function that has a predefined desirable value: binary, a number range, set inclusion, and so on. Metrics are often used for fitness functions. For example, an architect may define acceptable ranges for average cyclomatic complexity of methods in the codebase. Dynamic fitness functions rely on a shifting definition based on extra context, often real-time content. For example, consider a fitness function to verify scalability along with request/response responsiveness for a number of users. As the number of concurrent users rises, the architects will allow responsiveness to degrade slightly, but they don’t want it to degrade past the point where it will become a problem. Thus, a responsiveness fitness function will take into account the number of concurrent users and adjust the evaluation accordingly. Notice that dynamic and objective do not conflict—fitness functions must evaluate to an objective outcome, but that evaluation may be based on dynamic information. Invocation: Automated Versus Manual
  • 39. Architects like automated things—part of incremental change includes automation, which we delve into deeply in Chapter 3. Thus, it’s not surprising that developers will execute most fitness functions within an automated context: continuous integration, deployment pipelines, and so on. Indeed, developers and DevOps have performed a tremendous amount of work under the auspices of Continuous Delivery to automate many parts of the software development ecosystem previously thought impossible. However, as much as we’d like to automate every single aspect of software development, some parts of software development resist automation. Sometimes architects cannot automate away a critical dimension within a system, such as legal requirements or exploratory testing, which leads to manual fitness functions. Similarly, a project may have aspirations to become more evolutionary but not yet have appropriate engineering practices in place. For example, perhaps most QA is still manual on a particular project and must remain so for the near future. In both of these cases (and others), we need manual fitness functions that are verified by a person-based process. The path to better efficiency eliminates as many manual steps as possible, but many projects still require manual procedures. We still define fitness functions for those characteristics and verify them using manual stages in deployment pipelines (covered in more detail in Chapter 3). Proactivity: Intentional Versus Emergent While architects will define most fitness functions at project inception as they elucidate the characteristics of the architecture, some fitness functions will emerge during development of the system. Architects never know all the important parts of the architecture at the beginning (the classic unknown unknowns problem we address in Chapter 7), and thus must identify fitness functions as the system evolves. Architects write intentional fitness functions at project inception and as part of a formal governance process, sometimes in collaboration with other architect roles such as enterprise architects. Fitness functions not only verify the initial assumptions by architects on projects, but they also provide ongoing governance. Thus, it’s common for architects to notice some behavior that would benefit from better governance, leading to an emergent fitness function. Architects should keep a wary eye open for misbehavior in a project, especially those that can be verified via fitness functions, and add them aggressively. These two sometimes form a spectrum, beginning as intentional protection for some aspect but evolving into a more nuanced or even different fitness function over time. Just like unit tests, fitness functions become part of the team’s codebase. Thus, as architectural requirements change and evolve, the corresponding fitness functions must change similarly. Coverage: Domain-Specific Fitness Functions? We are sometimes asked if some particular problem domains tend toward certain architectural fitness functions. While nothing is impossible in software architecture and you might use the same automated testing framework to implement some fitness functions, generally fitness
  • 40. functions are used only for abstract architectural principles, not with the problem domain. What we see in practice if you use the same test automation tools is a separation of tests. One set of tests will focus on testing domain logic (e.g., traditional unit or end-to-end tests) and another set of tests on fitness functions (e.g., performance or scalability tests). This separation is utilitarian to avoid duplication and misguided effort. Remember, fitness functions are another verification mechanism in projects and are meant to coexist alongside other (domain) verifications. To avoid duplicating efforts, teams are wise to keep fitness functions to pure architecture concerns and allow the other verifications to handle domain issues. For example, consider elasticity, which describes a website’s ability to handle sudden bursts of users. Notice that we can talk about elasticity in purely architectural terms—the website in question could be a gaming site, a catalog site, or a streaming movie site. Thus, this part of the architecture is governed by a fitness function. In contrast, if a team needed to verify something like a change of address, that requires domain knowledge and would fall to traditional verification mechanisms. Architects can use this as a litmus test to determine where the verification responsibility lies. Thus, even within common domains (such as finance), it is difficult to predict a standard set of fitness functions. What each team ultimately views as important and valuable varies to an annoyingly wide degree between teams and projects. Who Writes Fitness Functions? Fitness functions represent the architectural analog to unit tests and should be treated similarly in terms of development and engineering practices. In general, architects write fitness functions as they determine the objective measures for important architecture characteristics. Both architects and developers maintain the fitness functions, including preserving a passing state at all times— passing fitness functions are an objective measure of an architecture’s fitness. Architects must collaborate with developers in the definition and understanding of both the purpose and utility of fitness functions, which add an extra layer of verification to the overall quality of the system. As such, they will occasionally fail as changes violate governance rules—a good thing! However, developers must understand the purpose of the fitness function so that they can repair the fault and continue the build process. Collaboration between the two roles is critical so that developers don’t misunderstand the governance as a burden rather than a useful constraint to preserve important features. TIP Keep knowledge of key and relevant fitness functions alive by posting the results of executing fitness functions somewhere visible or in a shared space so that developers remember to consider them in day-to-day coding. Where Is My Fitness Function Testing Framework?
  • 41. For testing the problem domain, developers have a wide variety of platform-specific tools because the domain is purposefully written in a particular platform/technology stack. For example, if the primary language is Java, developers can choose from a wide array of unit, functional, user acceptance, and other testing tools and frameworks. Consequently, architects look for the same level of “turnkey” support for architecture fitness functions—which generally doesn’t exist. We cover a few easy-to-download-and-run fitness function tools in Chapter 4, but such tools are sparse compared to domain testing libraries. This is due mostly to the highly varied nature of fitness functions, as illustrated in Figure 2-1: operational fitness functions require monitoring tools, security fitness functions require scanning tools, quality checks require code-level metrics, and so on. In many cases, a particular tool doesn’t exist for your particular blend of architectural forces. However, as we illustrate in future chapters, architects can use a bit of programming “glue” to compose useful fitness functions with little effort, just not as little as downloading a prebuilt framework. Outcomes Versus Implementations It is important for architects to focus on the outcomes—the objective measures for architecture characteristics—rather than implementation details. Architects often write fitness functions in technology stacks other than the main domain platform, or utilize DevOps tools or any other convenient process that enables them to objectively measure something of interest. The important metaphorical analogy with function in the term fitness function implies something that takes inputs and produces outputs without side effects. Similarly, a fitness function measures an outcome—an objective evaluation of some architecture characteristic. Throughout the book, we show examples of fitness function implementations, but it is important for readers to focus on the outcome and why we measure something rather than how an architect makes a particular measurement. PENULTIMATEWIDGETS AND THE ENTERPRISE ARCHITECTURE SPREADSHEET When the architects for PenultimateWidgets decided to build a new project platform, they first created a spreadsheet of all the desirable characteristics: scalability, security, resiliency, and a host of other “-ilities.” But then they faced an age-old question: if they built the new architecture to support those features, how can they ensure it maintains that support? As developers add new features, how would they keep unexpected degradation of these important characteristics from occurring? The solution was to create fitness functions for each of the concerns in the spreadsheet, reformulating some of them to meet objective evaluation criteria. Rather than occasional, ad hoc verification of their important criteria, they wired the fitness functions into their deployment pipeline (discussed more fully in Chapter 3). Although software architects are interested in exploring evolutionary architectures, we aren’t
  • 42. attempting to model biological evolution. Theoretically, we could build an architecture that randomly changed one of its bits (mutation) and redeployed itself. After a few million years, we would likely have a very interesting architecture. However, we don’t have millions of years to wait. We want our architecture to evolve in a guided way, so we place constraints on different aspects of the architecture to rein in undesirable evolutionary directions. A good example is dog breeding: by selecting the characteristics we want, we can create a vast number of differently shaped canines in a relatively short amount of time. We can also think about the system-wide fitness function as a collection of fitness functions with each function corresponding to one or more dimensions of the architecture. Using a system-wide fitness function aids our understanding of necessary trade-offs when individual elements of the fitness function conflict with one another. As is common with multifunction optimization problems, we might find it impossible to optimize all values simultaneously, forcing us to make choices. For example, in the case of architectural fitness functions, issues like performance might conflict with security due to the cost of encryption. This is a classic example of the bane of architects everywhere—the trade-off. Trade-offs dominate much of an architect’s headaches during the struggle to reconcile opposing forces, such as scalability and performance. However, architects have a perpetual problem of comparing these different characteristics because they fundamentally differ (an apples to oranges comparison) and all stakeholders believe their concern is paramount. System-wide fitness functions allow architects to think about divergent concerns using the same unifying mechanism of fitness functions, capturing and preserving the important architectural characteristics. The relationship between the system-wide fitness function and its constituent smaller fitness functions is illustrated in Figure 2-5.
  • 43. Figure 2-5. System-wide versus individual fitness functions The system-wide fitness function is crucial for an architecture to be evolutionary, as we need some basis to allow architects to compare and evaluate architectural characteristics against one another. Unlike with the more directed fitness functions, architects likely will never try to “evaluate” the system-wide fitness function. Rather, it provides guidelines for prioritizing decisions about the architecture in the future. While fitness functions may not help resolve the trade-off, they help architects more clearly understand the forces at play, with objective measures, so that they can reason about the necessary system-wide trade-offs. A system is never the sum of its parts. It is the product of the interactions of its parts. —Dr. Russel Ackoff Without guidance, evolutionary architecture becomes simply reactionary architecture. Thus, for architects, a crucial early architectural decision for any system is to define important dimensions such as scalability, performance, security, data schemas, and so on. Conceptually, this allows architects to weigh the importance of a fitness function based on its importance to the system’s overall behavior. Summary The original seed of the idea of applying fitness functions to software architecture occurred to Rebecca when she realized she could use some of her experience derived from another technical
  • 44. domain (evolutionary computing) and apply it to software: fitness functions. Architects have verified parts of architecture forever, but they haven’t previously unified all the different verification techniques into a single overarching concept. Treating all these different governance tools and techniques as fitness functions allows teams to unify around execution. We cover more aspects of operationalizing fitness functions in the next chapter.
  • 45. Chapter 3. Engineering Incremental Change In 2010, Jez Humble and Dave Farley released Continuous Delivery, a collection of practices to enhance engineering efficiency in software projects. They provided the mechanism for building and releasing software via automation and tools but not the structure of how to design evolvable software. Evolutionary architecture assumes these engineering practices as being prerequisites but addresses how to utilize them to help design evolvable software. Our definition of evolutionary architecture is one that supports guided, incremental change across multiple dimensions. By incremental change, we mean the architecture should facilitate change through a series of small changes. This chapter describes architectures that support incremental change along with some of the engineering practices used to achieve incremental change, an important building block of evolutionary architecture. We discuss two aspects of incremental change: development, which covers how developers build software, and operational, which covers how teams deploy software. This chapter covers the characteristics, engineering practices, team considerations, and other aspects of building architectures that support incremental change. Incremental Change Here is an example of the operational side of incremental change. We start with the fleshed-out example of incremental change from Chapter 1, which includes additional details about the architecture and deployment environment. PenultimateWidgets, our seller of widgets, has a catalog page backed by a microservices architecture and engineering practices, as illustrated in Figure 3-1.
  • 46. Figure 3-1. Initial configuration of PenultimateWidgets’ component deployment PenultimateWidgets’ architects have implemented microservices that are operationally isolated from other services. Microservices implement a share nothing architecture: each service is operationally distinct to eliminate technical coupling and therefore promote change at a granular level. PenultimateWidgets deploys all its services in separate containers to trivialize operational changes. The website allows users to rate different widgets with star ratings. But other parts of the architecture also need ratings (customer service representatives, shipping provider evaluation, etc.), so they all share the star rating service. One day, the star rating team releases a new version alongside the existing one that allows half-star ratings—a significant upgrade, as shown in Figure 3-2.
  • 47. Figure 3-2. Deploying with an improved star rating service showing the addition of the half-star rating The services that utilize ratings aren’t required to migrate to the improved rating service but can gradually transition to the better service when convenient. As time progresses, more parts of the ecosystem that need ratings move to the enhanced version. One of PenultimateWidgets’ DevOps practices is architectural monitoring—monitoring not only the services but also the routes between services. When the operations group observes that no one has routed to a particular service within a given time interval, they automatically disintegrate that service from the ecosystem, as shown in Figure 3-3.
  • 48. Figure 3-3. All services now use the improved star rating service The mechanical ability to evolve is one of the key components of an evolutionary architecture. Let’s dig one level deeper in the abstraction above. PenultimateWidgets has a fine-grained microservices architecture, where each service is deployed using a container—such as Docker—and using a service template to handle infrastructure coupling. Applications within PenultimateWidgets consist of routes between instances of running services—a given service may have multiple instances to handle operational concerns like on-demand scalability. This allows architects to host different versions of services in production and control access via routing. When a deployment pipeline deploys a service, it registers itself (location and contract) with a service discovery tool. When a service needs to find another service, it uses the discovery tool to learn the location and version suitability via the contract. When the new star rating service is deployed, it registers itself with the service discovery tool and publishes its new contract. The new version of the service supports a broader range of values —specifically, half-point values—than the original. That means the service developers don’t have to worry about restricting the supported values. If the new version requires a different contract for callers, it is typical to handle that within the service rather than burden callers with
  • 49. resolving which version to call. We cover that contract strategy in “Version Services Internally”. When the team deploys the new service, they don’t want to force the calling services to upgrade to the new service immediately. Thus, the architect temporarily changes the star-service endpoint into a proxy that checks to see which version of the service is requested and routes to the requested version. No existing services must change to use the rating service as they always have, but new calls can start taking advantage of the new capability. Old services aren’t forced to upgrade and can continue to call the original service as long as they need it. As the calling services decide to use the new behavior, they change the version they request from the endpoint. Over time, the original version falls into disuse, and at some point, the architect can remove the old version from the endpoint when it is no longer needed. Operations is responsible for scanning for services that no other services call anymore (within some reasonable threshold) and for garbage collecting the unused services. The example shown in Figure 3-3 shows evolution in the abstract; a tool that implements this style of cloud-based evolutionary architecture is Swabbie. All the changes to this architecture, including the provisioning of external components such as the database, happen under the supervision of a deployment pipeline, removing the responsibility of coordinating the disparate moving parts of the deployment from DevOps. Once they have defined fitness functions, architects must ensure that they are evaluated in a timely manner. Automation is the key to continual evaluation. A deployment pipeline is often used to evaluate tasks like this. Using a deployment pipeline, architects can define which, when, and how often fitness functions execute. Deployment Pipelines Continuous Delivery describes the deployment pipeline mechanism. Similar to a continuous integration server, a deployment pipeline “listens” for changes, then runs a series of verification steps, each with increasing sophistication. Continuous Delivery practices encourage using a deployment pipeline as the mechanism to automate common project tasks, such as testing, machine provisioning, deployments, and so forth. Open source tools such as GoCD facilitate building these deployment pipelines. CONTINUOUS INTEGRATION VERSUS DEPLOYMENT PIPELINES Continuous integration is a well-known engineering practice in agile projects that encourages developers to integrate as early and as often as possible. To facilitate continuous integration, tools such as ThoughtWorks CruiseControl, Jenkins, and other commercial and open source offerings have emerged. Continuous integration provides an “official” build location, and developers enjoy the concept of a single mechanism to ensure working code. However, a continuous integration server also provides a perfect time and place to perform common project tasks such as unit testing, code coverage, metrics, functional testing, and…fitness functions! For many projects, the continuous integration server includes a list of tasks to perform whose successful culmination indicates build success. Large projects eventually build an impressive list of tasks.
  • 50. Deployment pipelines encourage developers to split individual tasks into stages. A deployment pipeline includes the concept of multistage builds, allowing developers to model as many post–check-in tasks as necessary. This ability to separate tasks discretely supports the broader mandates expected of a deployment pipeline—to verify production readiness— compared to a continuous integration server primarily focused on integration. Thus, a deployment pipeline commonly includes application testing at multiple levels, automated environment provisioning, and a host of other verification responsibilities. Some developers try to “get by” with a continuous integration server but soon find they lack the level of separation of tasks and feedback necessary. A typical deployment pipeline automatically builds the deployment environment (a container like Docker or a bespoke environment generated by a tool like Puppet, or Chef) as shown in Figure 3- 4. Figure 3-4. Deployment pipeline stages By building the deployment image that the deployment pipeline executes, developers and operations have a high degree of confidence: the host computer (or virtual machine) is declaratively defined, and it’s a common practice to rebuild it from nothing. The deployment pipeline also offers an ideal way to execute the fitness functions defined for an architecture: it applies arbitrary verification criteria, has multiple stages to incorporate differing levels of abstraction and sophistication of tests, and runs every single time the system changes in any way. A deployment pipeline with fitness functions added is shown in Figure 3-5.
  • 51. Figure 3-5. A deployment pipeline with fitness functions added as stages Figure 3-5 shows a collection of atomic and holistic fitness functions, with the latter in a more complex integration environment. Deployment pipelines can ensure the rules defined to protect architectural dimensions execute each time the system changes. In Chapter 2, we described PenultimateWidgets’ spreadsheet of requirements. Once the team adopted some of the Continuous Delivery engineering practices, they realized that the architecture characteristics for the platform work better in an automated deployment pipeline. To that end, service developers created a deployment pipeline to validate the fitness functions created both by the enterprise architects and by the service team. Now, each time the team makes a change to the service, a barrage of tests validate both the correctness of the code and its overall fitness within the architecture. Another common practice in evolutionary architecture projects is continuous deployment—using a deployment pipeline to put changes into production contingent on successfully passing the pipeline’s gauntlet of tests and other verifications. While continuous deployment is ideal, it requires sophisticated coordination: developers must ensure changes deployed to production on an ongoing basis don’t break things. To solve this coordination problem, a fan-out operation is commonly used in deployment pipelines in which the pipeline runs several jobs in parallel, as shown in Figure 3-6.
  • 52. Figure 3-6. Deployment pipeline fan-out to test multiple scenarios As shown in Figure 3-6, when a team makes a change, they have to verify two things: they haven’t negatively affected the current production state (because a successful deployment pipeline execution will deploy code into production) and their changes were successful (affecting the future state environment). A deployment pipeline fan-out allows tasks (testing, deployment, etc.) to execute in parallel, saving time. Once the series of concurrent jobs illustrated in Figure 3- 6 completes, the pipeline can evaluate the results and, if everything is successful, perform a fan- in, consolidating to a single thread of action to perform tasks like deployment. Note that the deployment pipeline may perform this combination of fan-out and fan-in numerous times whenever the team needs to evaluate a change in multiple contexts. Another common issue with continuous deployment is business impact. Users don’t want a barrage of new features showing up on a regular basis and would rather have them staged in a more traditional way, such as in a “Big Bang” deployment. A common way to accommodate both continuous deployment and staged releases is to use feature toggles. A feature toggle is typically a condition in code that enables or disables a feature, or switches between two implementations (e.g., new and old). The simplest implementation of a feature toggle is an if- statement that inspects an environment variable or configuration value and shows or hides a feature based on the value of that environment variable. You also can have more complex feature toggles that provide the ability to reload configurations and enable or disable features at runtime. By implementing code behind feature toggles, developers can safely deploy new changes to production without worrying that users see their changes prematurely. In fact, many teams performing continuous deployment utilize feature toggles so that they can separate operationalizing new features from releasing them to consumers.
  • 53. QA IN PRODUCTION One beneficial side effect of habitually building new features using feature toggles is the ability to perform QA tasks in production. Many companies don’t realize they can use their production environment for exploratory testing. Once a team becomes comfortable using feature toggles, they can deploy those changes to production because most feature toggle frameworks allow developers to route users based on a wide variety of criteria (IP address, access control list [ACL], etc.). If a team deploys new features within feature toggles to which only the QA department has access, they can test in production. Using deployment pipelines in engineering practices, architects can easily apply project fitness functions. Figuring out which stages are needed is a common challenge for developers designing a deployment pipeline. However, once the fitness functions inside a deployment pipeline are in place, architects and developers have a high level of confidence that evolutionary changes won’t violate the project guidelines. Architectural concerns are often poorly elucidated and sparsely evaluated, often subjectively; creating them as fitness functions allows better rigor and therefore better confidence in the engineering practices. Case Study: Adding Fitness Functions to PenultimateWidgets’ Invoicing Service Our exemplar company, PenultimateWidgets, has an architecture that includes a service to handle invoicing. The invoicing team wants to replace outdated libraries and approaches but wants to ensure these changes don’t impact other teams’ ability to integrate with them. The invoicing team identified the following needs: Scalability While performance isn’t a big concern for PenultimateWidgets, the company handles invoicing details for several resellers, so the invoicing service must maintain availability service-level agreements. Integration with other services Several other services in the PenultimateWidgets ecosystem use invoicing. The team wants to make sure integration points don’t break while making internal changes. Security Invoicing means money, and security is an ongoing concern. Auditability Some state regulations require that changes to taxation code be verified by an independent accountant. The invoicing team uses a continuous integration server and recently upgraded to on-demand
  • 54. provisioning of the environment that runs their code. To implement evolutionary architecture fitness functions, they implement a deployment pipeline to replace the continuous integration server, allowing them to create several stages of execution, as shown in Figure 3-7. Figure 3-7. PenultimateWidgets’ deployment pipeline PenultimateWidgets’ deployment pipeline consists of six stages: Stage 1: Replicate CI The first stage replicates the behavior of the former CI server, running unit and functional tests. Stage 2: Containerize and deploy Developers use the second stage to build containers for their service, allowing deeper levels
  • 55. Random documents with unrelated content Scribd suggests to you:
  • 56. wide sweep from out the lane, dragging after them a huge, open, omnibus sleigh. As the great ark ranges in front of the hotel, and its mad team subsides into comparative quiet, forth issue from the thronged piazzas crowds of village belles and beaux. Can it be that so many may find room aboard the sleigh, capacious as it is? Leave that to the Genius who presides over expeditions of this sort. In a sleigh, large or small, there is always room for one more. In the meantime the doors of the private dwellings have been opened, and from each emerges a beshawled, bemuffed, behooded, and overshod damsel—or two or three perhaps. Their happy beaux, clad in overcoats of pilot-cloth, in seal-skin caps, red worsted leggings, and buckskin gloves, escort them to the sleighs. The procession is formed in front of the hotel. Twenty sleighs, besides the teeming omnibus. The last in the line is a crockery crate, mounted upon a rude pair of runners and hitched behind a tandem team. The leader is a three-year old colt, wild and but half broken, and now, crazy with the noise, he is kicking and plunging like mad. In the crate stands the dare-devil of the village; a rich, handsome, graceless, good-natured scamp—the darling of the girls, the marvel of the boys, the terror of the piously disposed, and the favorite of all. He prefers to ride alone. Now all is ready—the band strikes up—the driver of the omnibus stands erect and tightens his reins—crack, goes the long whiplash—the horses plunge and start, the snow creaks, the bells jingle, the boys and loafers hurrah, the beaux laugh as the girls scream, and away flies the long caravan, like an express train, down the broad street, thundering, cracking, screaming, laughing. They turn the corner, all but the daredevil and his crockery crate, they are upset in a snow-drift, but before the army of boys and loafers can reach the scene of the mishap, all is right side up again, and the last seen of dare-devil he is driving by the whole train, his frantic leader touching the snow only once in a rod. Two hours afterward six reeking horses drag the omnibus up to the hotel piazzas again—a string of sleighs come in behind—one by one the stragglers arrive. Dare-devil and his team are among the missing, and on inquiry are reported as seen last, the one kissing the landlady at a tavern ten miles away, and the other engrossing the
  • 57. attention, and calling into active exercise all the strength and agility of the landlord and his negro hostler. In the meantime twenty miles of snow path have been scoured over by the merry, frost-covered throng disembarking on the steps. Thousands of merry speeches have been said—a whole jest-book full of funny stories have been told. Every pretty hand in the company has been squeezed. Every pretty cheek has been kissed, and, we doubt not, almost every pretty lip. At least nine flirtations have been commenced. The moon has drawn together three pairs of twin hearts, and set them throbbing in unison—and one little question has been put and answered, very satisfactorily to the absorbed couple in yonder sleigh, which is arriving late, closely pursued by the shouting dare-devil and his prancing team. All night the glaring windows of the ball-room shake and rattle. The inspiring music, to which they keep time, the sound of the dancers’ feet, the merry ringing of lamps, and the buzz of conversation are heard by the sleepy watchers in the bar-room below, who while away the hours, except when disturbed by eruptions of the beaux from above, in quest of confectionary and lemonade, or perhaps stronger beverages, by playing checkers, drinking flip, smoking cigars, and endlessly discussing the points and merits of divers horses of the neighborhood. The pale moon lights home the revelers, just in time to save her sister Aurora the trouble. The young May moon has been justly celebrated by the poets, and many have supposed, that at this season the hearts of lovers are more susceptible than at any other time. Truly the moonlight of May is very beautiful and love inspiring—but the August and September moon is the time of times—when the air is clear and warm, without cloud or chill, and rich and faint with the odors of the ripe fruits—when the corn and grain and all that grows from the earth’s bosom are at full height and verging toward maturity—when other leaves than those of tall trees rustle in the night wind—when the katy-did and cricket hold cheerful conversation, and fill the air with noisy clamor, near akin to silence—when the nights have grown longer and cooler than in the fierce mid-summer—when the moon
  • 58. seems larger and fuller than its wont, and its light has a deeper tone —then is the time to enjoy, in perfection, moonlight nights and lunatic fancies. Nights we say—not evenings. In the evenings one sees company and receives calls, takes wearying walks, hears commonplace remarks about the beauty of the weather and the prospects of the crops, eats ice-creams, drinks sherry-cobblers, or, it may be, smokes cigars and reads the evening newspaper. It is a border ground, upon which the people of the work-day world make forays. But “the small hours,” far in “the stilly night,” from twelve to three, contain the true romance of moonlight. The dull world is asleep, there is a new heaven and a new earth, peopled only by fairies, lunatics, ghosts and poets. Bright heavenly hours! Methinks in praise of them we could “mark out a measure of verse.” They may tell of the sunlight’s brilliant dyes When the day in the Orient breaks; Of the splendid glare which dazzles the eyes As his noontide course he takes; They may talk of the gorgeous hues that glow In the western sky at eve, When, in gaudy pomp and with gilded show, Of the world he takes his leave. They may praise the Aurora’s wayward gleam, As far up the northern sky The ruddy flashes fitfully stream, Then suddenly fade and die; And flash anew, and again sink low, Like the love of a fickle swain; While the shadows flicker over the snow That covers the wintry plain. The poets sing of the twilight hour, The twilight hour of eve; And teach that it hath a magic power To soothe the hearts that grieve; That lovers prefer this gentle time— To courting it gives such a zest— And, as for themselves, for the stringing of rhyme That the twilight hour’s the best.
  • 59. There are some who delight in a starlight night, And some like a chandelier; And others a grate-full of anthracite, Or of hickory burning clear, And some the religious light that is shed Adown in a church’s aisle— And some will turn out from a nice, warm bed To gaze on a burning pile. But the light that we love far better than all Is the light of the golden moon At the sweet, short hour “ayont the twal,” Just past the summer night’s noon. Oh! then ’tis sweet to roam alone, Or to sit in the shaded bower! No enchantment, we ween, on earth is known Like the magic of such an hour. ’Tis sweet when the night by the moon is graced To wander with her we love; Or to sit with our arm around her waist, While we coax from her hand the glove; And to teaze in a whisper for one sweet kiss Till we gain the darling boon! Oh! for making love ne’er a time like this— By the light of the August moon. “And so on,” as Elia says, “one might proceed in this strain forever.” Give to us, then, the moonlit nights of fragrant August and mature September. There is a body to them, a delicate aroma withal —the intoxication is heavenly, such as nectar might produce. Then it is that heaven seems descended to the earth, and fairy land restored. Then it is, that, if we find ourselves alone with one of the other sex, by the soft light, we are prone to imagine her to be our better self, our other moiety, the twin soul for which we have longed in our dreams, and—hence the propriety of a proper selection of moonlight company, judiciously made, before sunset. Then it is that we like to talk but little, and only in whispers and low tones. Then it is that our souls grow large, and we cannot believe ourselves mortal.
  • 60. Deep ardent longings seize us for something we know not what. Tears, neither of sadness or joy, spring to our eyes. Delicious, incomprehensible emotions agitate our hearts. Strange things seem easy of credence, and to see a troop of fairies dancing on the green lawn, or the placid ghost of a dear friend, half hidden in the shade of yonder vine, would startle us but little, and would seem all in keeping. Then we grow poetical—romantic—at peace with all the world—then chilly—then—ah! poor human nature!—then sleepy! and when, six hours after, we rise, at the third call, to a late cold breakfast, eggs, rolls and coffee seem to us of great importance, and occupy the whole attention of a soul, which, but lately, held the whole world in its embrace and felt a void the while. Gentle reader—while we write the pale, exhausted moon is setting behind the distant ridge of Talcott mountain. The tall tower of Montevideo stands like a lonely, belated giant, in full relief against the silver-gray western sky. Our hair is damp with dew—our numb and weary fingers can hardly retain the blunt pencil with which we have indited the preceding extravagances. There is a faint, ruddy glow in the east—we hear the neigh of Aurora’s steeds. Good night then, dear, lunatic reader. May the morn find you sane—the night mad again—and long may it be ere the soft light of the full moon shall rest upon the green sod of your grave, and glow, reflected from the marble of your monument. TO MISS MARTHA GRIFFITH. ——— BY G. D. P. ———
  • 61. Beautiful girl, I have wandered far, Toward the rising sun and the evening star, I have roamed ’mid the Northern wastes of snow, And strayed where the soft magnolias blow, But I never gazed on a face as bright As thine, sweet spirit of young delight. Beautiful girl, thou art bright and fair As an angel-shape in the moonlight air, No shadow rests on thy brow of snow Save that of thy tresses drooping low, Love’s own dear light is wandering oft O’er thy gentle lip of carmine soft, Thy lovely cheek, where the rich, red glow Of the warm blood melts through the virgin snow, Is sweetly blending in one rich dye The woven beauties of earth and sky; Truth, holy truth in its freshness dwells Deep, deep in thy dark eyes’ shaded wells, And fancies wild from their clear depths gleam, Like shadows of stars from a trembling stream, And thy thoughts are a dream of Eden’s bowers, And thy words are garlands of flowers, bright flowers. Beautiful girl, I have seen thee move A floating creature of joy and love, As light as a mist on the sunrise gale, Or the buoyant sway of a bridal veil, Till I almost looked to see thee rise Like a soaring thought to the free blue skies, Or melt away in the thin blue air, Like a vision of fancy painted there. Thy low sweet voice, as it thrills around, Seems less a sound than a dream of sound; Softly and wildly its clear notes swell Like the spirit-tones of a silver bell,
  • 62. And the lips whence the fairy music flows Is to fancy’s eye like a speaking rose. Beautiful, beautiful girl, thou art A vision of joy to the throbbing heart, A star sent down from a world of bliss And all undimmed by the shades of this; A rainbow pictured by love’s own sun On the clouds of being, beautiful one. Beautiful girl, ’tis a weary year Since thy sweet voice fell on my ravished ear. ’Tis a long, long year of light and gloom Since I gazed on thy young cheek’s lovely bloom— Yet thy gentle tones of music still Through the holiest depths of memory thrill Like tones of a fount, or breeze, or bird, In the long gone years of childhood heard. And oft in my dark and lonely moods, When a demon-wing o’er my spirit broods, Thine image seems on my soul to break Like the sweet young moon o’er a gloomy lake, Filling its depths as the shadows flee, With beauty and love and melody. Beautiful girl, thou art far away, And I know not where thy steps now stray; But oh! ’tis sweet, it is very sweet, In the fairy realms of dreams to greet Thy cheek of roses, thy brow of pearl, And thy voice of music, beautiful girl. PICTURE OF CHILDHOOD.
  • 63. ——— BY WM. ALEXANDER. ——— Forth issuing from a craggy mountain’s side, A stream is seen. Anon, with gilded prow And silvery oars, a bark appears to glide, Bearing a happy infant, on whose brow, Pictured are Joy and Wonder. Onward still Over the widening stream’s wild waves, eke, skims It merrily. The tiny steersman hymns His roundelay of Joy, or at his will, Plucks the gay flowers of early morn, Which diamond dew-drops, silver-like, adorn— Unmindful that such pleasures fade away, That youth, and love, and beauty soon decay— Life is a launch—we voyage to the grave, We venture on, unthoughtful of the whelming wave. MINNIE DE LA CROIX: OR THE CROWN OF JEWELS. ——— BY ANGELE DE V. HULL. ——— (Concluded from page 304.) “Lord bless us, my children! what a noise,” cried Mr. de la Croix on the morrow as he entered the store-room. “I am deaf! give me some claret and water some of you! I am thirsty enough to swallow
  • 64. bottle and all. I have had lamps fastened to every other tree in the avenue and every column around the piazza.” Minnie brought him the iced wine and ran off to work again. She was beating eggs for a mayonnaise, and directing the servant behind her in chopping celery and chicken for salad. Lisa was standing on a table pouring from an immense bowl a stream of icing over a pyramid of cake that stood in a salver on the floor. Rose was frothing eggs for something else, Kate was churning syllabub, and Blanche was pounding almonds. Mr. de la Croix stopped his ears and called out as loudly as he could, “Halt! order! I want to talk. Where are those great china bowls to be placed, and the pride of Rose’s existence, the diamond- cut wonder—the crystal one? No one can carry them among you here, and I must tell Sampson to do it.” “The two first on the piazza, the glass one in the middle of the table,” answered Lisa, looking up from her task. “I only hope Sampson will not serve them like Philistines, with the exertion.” “Do you think there is too much strength under those woolly locks of his, Lisa, or do you fear a superfluity of grace in his ‘fantastic toe?’” said Kate. “I know that his ‘fantastic toe,’ as you are pleased to dignify it, kicked over a pan of milk an hour ago, when I sent him to the dairy, and these tricks have not certainly power to make angels smile.” “Samp want to white hisself for to-night,” said his wife, showing her ivory as she looked at him. “Miss Lisa never scold him for it, but you may know I did, Miss Kate. What he do such ladicalous things for?” “He could not help it, Aunt Winny,” said Minnie as she turned her dish of well frothed eggs to prove her skill. “Now here is a magnificent float for your ‘island.’ You know I always said that you should make your favorite dish for my wedding-supper, and this is an occasion quite as important. Here is the sugar, sand and every thing you want.” “Thank’ee, Miss Minnie. I’ll make it splendid, you may know that. But dis an’t no wedding-supper, my child, and it musn’t be so grand a floatin’ island as the bride’s. Ah! didn’t I make two for Miss Kate
  • 65. and Miss Blanche if dey wos married in de mornin’. I nussed you all —fine gals you is! Dey an’t such young ladies for miles round, and please God! I may live to see you all happy and lovin’ your pardners as them do. My old mistress herself would love to see ’em so.” And Winny left the room majestically—a pan on her head and one in each hand, six little nigs at her heels, each dismissed with a lump of sugar as they went along in a straight line to the kitchen. “Winny grows eloquent, as she gets older,” said Lisa. “If every body believed her, we would all be like Miranda with every creature’s best. I wonder what she will say when she sees us all dressed to- night.” Winny was not the only one delighted with her young mistresses as they made their appearance in the hall, one after another, and surveyed the beautifully decorated walls of the several apartments opened for the occasion. Festoons of cedar were hung around and above, and beneath each were large bouquets of fresh flowers, arranged in perfect taste. The orchestra hung in scarlet cloth, was wreathed in roses and evergreens, and surrounded by lamps placed so as to illuminate these fairy bowers independent of the glittering row of lights for the musicians. Stands of exotics occupied one side of the hall, the fair and tender buds throwing out a thousand perfumes on the air, yet even these were not more fragrant than the flowers of the season that hung around, the delicate maiden’s-blush and the pale tea-rose. Long after the chilly autumn winds have made us close our casements and doors, these sweet sisters are blooming in the gardens without, and from Mr. de la Croix’s thick and extended hedges he had found a harvest for his daughter’s ball. Nothing could be more brilliant than the tout ensemble of garden, house and avenue. Every nook and corner had its light, every room its comfort, and before the guests began to assemble Lisa had satisfied herself that the arrangements for their enjoyment were indeed complete. Her queenly form well became the blue tarlatan with its moss-roses in bunches of half opened buds. Her hair was simply twisted, and in satin-like bands over her ears. Blanche and Kate floated about in their pure white, their elegance conspicuous from their simplicity, while Rose and Minnie,
  • 66. like twin roses, were radiant with beauty. The excitement had deepened the color on their cheeks and brightened their eyes into stars. Who wonders then at the father’s pride as he looked at his crown of jewels this night? Who wonders that the guests loved their pleasant smiles, and treasured their gentle welcomes? No one was neglected by them, not one in the whole crowd felt forgotten or slighted, and the hours flew by as though Time had laid his hour- glass in the green bowers and slept at its side. “Minnie, Minnie!” whispered Blanche, “you talk too heedlessly. Be more quiet, my dear girl.” “Ah, do not scold me to-night,” cried she, as she leant half panting for breath upon her partner’s arm. “Is it not a shame to scold me now?” And she raised her bright eyes to his with a look that dazzled him. “It is a shame ever to do so,” replied he earnestly. “Surely Mrs. Stuart you are not so cruel?” “Only prudent, Mr. Milton, that is all; remember this is my little sister’s ‘first appearance.’” “You mean that she is one of the unsophisticated,” said he laughing. “And by far more bewitching in consequence,” was added in a whisper. Blanche smiled and shook her head at him, but they whirled off in a waltz before she could reply, so she returned to her station by Kate, who was talking in a very old-fashioned kind of way to—her husband. “Paul and I were thinking the same,” said Kate, as she placed her arm within hers. “Minnie is tant soit peu inclined to flirtation, and we must warn her before it becomes a passion.” “A passion, Kate!” said her husband smiling. “Yes; a passion for admiration—for change, and a sickly love of flattery that is beneath a girl like our Minnie. How I do hope she will preserve that perfect freedom from all affectation that is one of her greatest charms.” Paul made no answer, but as the quadrille broke up, went forward to the object of this enconium as she accepted her partner’s offer of a quiet promenade after her dance.
  • 67. “Minnie,” said he, “you have not danced with me this evening.” “Because you have not asked me,” replied she, putting her arm through his with an affectionate smile. “I have felt myself quite neglected by you and Kenneth, I assure you.” “I was just coming to claim you, Minnie,” said Mr. Stuart, who had heard her last remark. “But since I am supplanted this time, we are engaged for the next.” She nodded to him and passed on to a group of young girls who were talking gayly, and joined them. One, a fair-haired blonde with a pair of melting blue orbs, accosted her with a congratulatory remark upon the entire success of her fête. “We are all delighted with every thing—with you and with ourselves, par parentheses. But why does not your father dance, Minnie?” “Go and ask him,” said she laughing. “I have not seen him dance since I was a little girl.” “Well, he shall dance with me then,” exclaimed the pretty questioner, “and I am going to invite him for the very next quadrille.” And off she tripped to find Mr. de la Croix. “Dance with you, my sweet young lady,” cried he. “And what will all these gay and handsome fellows say to my usurping their place?” “That I show very good taste in my selection of a cavalier,” was the reply. “You must dance with me Mr. de la Croix because—I have said that you must.” “The little maid would have her will,” quoted he, much amused. “So come, my little conqueror, I could not refuse, even if an old man’s bygone steps are shocking to polka lovers and sliding graces.” “I have gained a victory,” said Miss Ashton, as he led her to a place among the dancers. “See, Minnie! I have chosen my own partner, in spite of ceremony and etiquette.” “Age has its privileges,” observed Mr. de la Croix, with a courtly bow, “and this is one of its most pleasant advantages. I had never been so honored but for my silver-streaked head.” “Ah, Mr. de la Croix!” said his young companion archly, “your youth has only to return to put us to the test. I’m sure you could tell us of bright eyes that followed you wistfully in days of yore.”
  • 68. “Little flatterer!” exclaimed he, as the music struck up. “My age again has helped me to this.” But the gay girl bounded forward, and he watched her graceful movements with so much pleasure that he almost forgot his own part. Minnie was opposite too, and seemed so delighted at seeing her father dance, that he quite enjoyed an amusement that had been for so many years discarded, as one too frivolous for a père de famille. Mr. Selby had to follow his example, as Minnie declared it his duty to do so, and thus her “first party” was a perfect triumph, as not only the younger but the older heads were giddy with their exertions to amuse and be amused. It was nearly daylight before Sampson had finished his task of putting out the lights, and the hall, like all other banquet halls, deserted. There were no heavy hearts carried away, though many perhaps were lost to merciful finders, and Minnie laid her young head on her pillow with a feeling of consciousness that her debut had been one of unusual and brilliant success. And so it proved, for during the season that followed, no party of pleasure—no crowded ball was complete without her presence. She was a perpetual sunbeam, shedding light by her winning smile and sweet temper. Her sisters accompanied her by turns, and watched her flying steps with affectionate pride; but Kate’s fears were partly verified, and her young sister too fond of admiration to escape that love of sway over the hearts of the many that seemed to live but in her glances. In vain they warned—in vain they lectured, Minnie had been too long careless of advice to heed it now in this whirlpool of constant gayety. Still artless, still unaffected, she dispensed her smiles too lavishly, and fanned the flame her varied charms had kindled, where she might have spared her victims many a pang, had she heeded the voice of reason. “Would you have me cross to people?” said she to Kate. “No, Minnie; but seemingly less pleased with their attentions. Did not Mr. Douglas have reason to complain that you had encouraged him, when you refused his offer last week?”
  • 69. “Who told you that?” asked Minnie, crimsoning to the temples. “Who told you that, Kate?” “Himself, and I could not but feel for his disappointment,” said Kate earnestly. “I have seen you look pleased at his assiduities—so pleased, that I could not wonder at the reproach he made you.” “I granted him no more than I did to others,” said the girl tearfully. “But you have a way, Minnie, of accepting homage that is flattering to those who offer it.” “I am flattered, and return only what I receive.” “But you do not, my dear sister. What they offer is too often sincere; they, then, according to your mode of reasoning, have a right to expect the same. Harry Lamfear left here in consequence of your refusal, for, as he said, he could not bear to meet you wherever he went, and I own that I thought you were partial to him from a promise I heard you make, to wear no bouquets but his for one month.” “You are making mountains of mole-hills,” said Minnie, blushing again. “I never dreamed that such a promise was equivalent to ‘Certainly, sir! go and order the furniture.’ I did like Harry Lamfear exceedingly, but love was no part of the liking. I told him more than once—more than twice, since I must defend myself, that it was useless for him to expect any thing more than friendship from me. I could not refuse to speak to him—it will not do to insult a man because he wants to marry you, will it?” “Decidedly no; but then you should have refused to dance with him more than once in the evening—you should have denied yourself on more occasions than one, when he called. I saw you one morning get up from the sofa, where you were suffering actually with a headache, and dress your hair as becomingly as you knew how, with a morning-cap that was really a charming set-off to your piquante style, and go in the parlor to receive him. You told him of your indisposition of course, and his inference was, that there must have been something more than friendship to rouse you in the midst of pain, to the exertion of entertaining him. Did it look like indifference?”
  • 70. “I was wrong there, sister,” said Minnie, rising and seating herself beside her. “Tell me what I must do.” “Be kind and courteous to all, my little pink-cheek, and do not listen with such a ready ear to the honied words that make you giddy. Do not every week or month select one on whom to bestow your favors, but treat all alike indifferently until you really find your own feelings enlisted. Then I need not advise, your own delicacy, your own natural modesty will make you every thing you ought to be. But for heaven’s sake do not give people the idea, that you are caught like a candle-fly by every glare, and wear a battered down heart after your first winter is over.” “Oh, Kate, how matter-of-fact you are! Why didn’t you say ‘pretty moth,’ and ‘withered heart?’ You shock me with your every day- isms.” “You have very fastidious ears, Minnie, and I am not jesting. There is one thing more to be said and I have done. Beware of trifling with young Freeman. He will not suffer himself to be led like his predecessors if he is serious. And if he is, as I think, merely playing your game of flirting, he will make you regret ever having seen him. I do not like him—I cannot look at him without a feeling of uneasiness.” “How foolish!” cried Minnie, laughing, “and how ungrateful! he is always praising my charming sister Mrs. Linden.” “Yes, so as to tell you immediately afterward how much you resemble her,” said Kate gravely. “I am not old, Minnie, but I am sorrowed, and feel no longer young. Let what I have said this morning be of some benefit to you, for your own sake, if not for mine. I must watch and warn you, heedless as you are to all counsel, and in so doing I make a sacrifice that costs me something, for I might be conversing pleasantly on other subjects, and feel secure that my sister Minnie does not think me harsh and disagreeable,” and her eyes filled with tears. “How unjust!” cried Minnie, throwing her arms around Kate’s neck, and kissing her affectionately. “How very unjust! Do I not know how to value your advice, Kate—am I so heartless in your
  • 71. eyes? Heedless I am indeed, but not heartless, and I will try and remember what you have said, that I may act upon it.” And so she did until it was forgotten, and young Freeman’s devotion became once more a triumph to the unreflecting Minnie. Her sisters rejoiced as the end of the season drew nigh, as the entire summer would be undisturbed by these constant amusements. They would once more live in quiet after the gay and to them tiresome winter, passed in following their young charge from place to place, and in the meantime a change might come over the “spirit of her dream.” It was at the opera that Minnie sat once more, while Mme. —— enchanted and fascinated her audience. Her bright eyes were fixed upon the sweet singer, and she did not perceive the door of her box opened to admit a gentleman, who took his seat and gazed in silence at the lovely form before him. Ever and anon he turned to Mr. Stuart, who stood behind with a smile of pleasurable surprise upon his fine open countenance, and watched with some impatience the close of the second act of “Jerusalem,” in spite of his love of music and the beauty of this particular opera. But the curtain fell, and Minnie turned to speak her delight to her brother. She started as she recognized Harry Selby! He could not but be flattered at the expression of pleasure upon that speaking countenance, and the fluttering of the little hand, which, for a moment, rested in his; while Minnie read in those dark eloquent eyes a story that sent the tell-tale blush to her cheek, and forced her into a silence that provoked and embarrassed her. But Rose came to her aid, and poured inquiries into his not over attentive ear. When did he arrive—when did he sail? Where was his uncle? “I arrived this morning—I sailed three weeks ago from Liverpool to New York, and lost not a minute in coming south, and left my uncle at home.” “You are a perfect telegraph,” said Minnie, recovering her speech. “Your friends must feel highly flattered at your haste to reach them.” “Ah!” exclaimed he, fixing his eyes upon her, “I felt that I could not trust myself to remain absent any longer! I had so much to
  • 72. learn! so much to lose!” Minnie turned to the stage and lifted her opera-glass, while Rose smiled in spite of herself. Here was a lover comme il y’en a peu. And as she contemplated his handsome countenance expressive of high and noble qualities, his attractive manner and pleasant flow of words, she felt that Minnie was a conqueror indeed. “Come and dine with us to-morrow, Harry,” whispered she, as he handed her in the carriage. “And bring your uncle with you. Tell him I have a japonica in full bloom and he must see it.” “Ah, Rose!” was the reply, “you are an angel! You do not mock the ear with promises—you mean to keep them.” And they drove off at a rapid pace, leaving him to rejoice over the beauty and fascination of his youthful love, while she leaned back and wondered at the beating of that hitherto quiet heart—the strange but pleasurable emotion that seemed gushing from its depths. “How remarkably he has improved!” exclaimed she, turning to her sister. “How proud his uncle must be.” “Proud indeed!” replied Rose. “And Harry’s worth does not consist in his good looks, he has a well-regulated, intelligent mind, a noble heart, and that rare pride that scorns an unworthy thought. I saw him constantly when I was in Paris, and I am certain that he will fully justify the opinion I formed of him.” The carriage stopped at Mrs. Bliss’s door for Kenneth and Blanche, and Mr. Selby came out to meet his favorite. Minnie parried his questions as well as she could, but Rose’s congratulations upon his nephew’s arrival and appearance satisfied him, and he accepted her invitation to dinner with unmistakeable pleasure. He had intended to take them by storm, but now Lisa would have warning, and be able to fuss over them as they deserved, and he bade them “good night” with a hearty shake of the hand. Down the pleasant avenue wandered two graceful forms a few weeks after this, the gentle tones of a young girl’s voice mingling with the deeper, more tender ones of a youth, who was gazing earnestly on her deepening cheek.
  • 73. “I need not have told you, Minnie, for you knew it that night at the opera,” said he pleadingly. “You could not but see that I loved you as few love—that in spite of time and space your image had remained within my heart, its fondest remembrance. Tell me, Minnie,” and he paused as they reached a vine-covered bower, and led her to a seat beneath its shade, “tell me honestly, did you not read all this ere now?” She trembled—her lot now was to be cast, her fate determined, and there seemed a spell upon her, for she could not speak; but there was no shade upon that fair smooth brow, no anger in those softened looks, and Harry, like many a one before him, dared to interpret for himself what her own lips at length were able to affirm. And now to them the world seemed a paradise indeed, and life one long summer day, o’er which no cloud could ever come, to shadow their sunny hopes. The blue sky seemed clearer above their heads—the flowers were brighter, and the fair earth fairer still. Happiness was theirs, for they were all to one another, and as the hours passed unheeded, and the gleaming stars burst forth into the quiet heavens, they raised their eyes and likened their love to the quenchless beauty of its countless lamps. Alas, poor dreamers! ye are granted this one momentary perfection of bliss! Ye can linger for once over this dawn of promised light—for once ye are convinced of its duration. But the sky must darken, the lamps must go out—the flowers must perish—the hopes must wither! There is but one hope—one home of happiness—the home that is not to be won without its pains, its fierce and mighty struggles, its chastenings, that purify and fit the soul for the presence of Him who promised it to the pure of heart. Poor Minnie had to wake from her dream of love, but not yet— not until she was once more in the giddy round of engagements for the spring. It was at Mrs. Bliss’s last soirée that she was seen flying about like a vision of light, while Harry Selby watched her every glance. He had a right to be proud of her, for she was his own—his promised one, and proud he was. But a shade passed over his face as he beheld her extending to another the same smiles she gave to him; exerting for another the same fascinations that bound him
  • 74. captive from the hour he first beheld her. He did not intend, dear reader, that Minnie should give up all for him; he did not expect her to be less gay or less fond of dancing, but he could see no difference now between her conduct to those around her, and to him alone. He had a right to more than they, but although Minnie’s engagement was generally known, she allowed her lover to be pitied or jested with upon the danger of marrying a flirt, who cared more for admiration than for the love he bore her. I am no advocate for the exactions or fastidiousness of the stronger sex, exactions that in all cases become that conjugal tyranny that drives us with broken hearts to an early and welcome tomb. I cannot uphold that constant recurrence to the difference of duties and deportment that marked the single and the married woman. The ceremony that binds in a few moments, cannot change the disposition of eighteen or twenty years—cannot blanch the dark braids of the bride into a matron’s sober locks; and yet there are few husband’s in the world who do not frown and wonder, if before the honey-moon is half over, he sees in his young wife the same ways and manners of the unfettered creature he had sworn so perfect, that her faults, if faults she could have, were virtues. He had vowed that his life was a curse without her, that he asked only her love in return for his passionate devotion. But no sooner is she won, no sooner is she the wife who has bound herself to him “for better, for worse,” than he expects, God help her! the sacrifice of every thought she has to his prejudices, and never dreams how often she has been shocked at faults and habits that tore from her eyes the veil her own youth and inexperience had helped to weave. But Harry Selby was not as a lover more exacting than was natural and proper, and he had imbibed some of Kate’s opinions concerning young Freeman, knowing too, more than she did, to justify his aversion. His devotion to Minnie de la Croix was not at first sincere, for his object was merely to triumph over others, and win a wager he had already made to do so. But her indifference to all his protestations enraged him, and her subsequent betrothal had made him jealous, and proved how madly he had learned to love her. He swore that he would force her to dismiss his rival, and
  • 75. Minnie’s acceptance of his attentions allowed him to dream of success in spite of her coldness to his suit, and laughing answers to his serious questions. He was well aware of his powers; he was one of the most attractive of his sex, witty, entertaining, and having that peculiar expression of high respect in his manner, that is particularly pleasing to women. Many would have given up, with more success than he could boast of, but he had vowed to revenge himself on Harry Selby, and his friends had heard him; so around poor Minnie a web was forming which her own thoughtlessness but helped to strengthen. She was convinced that Mr. Freeman fully comprehended her sentiments, and thus excused herself for carrying him in her train, unwilling to give up one who added so much to her amusement, and the splendor of her triumphs. In the midst of a merry argument upon the rights of two waltzers that stood before her, Harry approached. “Will you dance with me?” he asked, and offering his arm to her. “I have waited patiently until now, you were so surrounded!” “Why, do you not see these two importunate creatures teasing my life out? They want me to waltz, when I am tired to death and want to rest,” replied she, with a toss of the head that became her amazingly. “But I ask you to dance,” said Harry, earnestly. “It is not so fatiguing, and I am but too happy to remain here until the quadrilles recommence.” At this moment the band began a waltz, a sweet, bird-like clarionet pouring out its enchanting sounds, and the young girl bounded from her seat. “Come, Mr. Freeman, I cannot resist that!” cried she laughing. “I must surely have been bitten by a tarantula.” Harry drew back, and an expression of pain and anger crossed his face as he watched Minnie and her partner, who glanced at him with a look of haughty triumph. A hand was laid upon his arm, and Kate Linden stood beside him. “As much as I dislike him, Harry, I must put Minnie in the wrong. For God’s sake, let there be no quarrels between men—I will speak to Minnie. She loves you dearly, but—”
  • 76. “She loves adulation more,” said he bitterly. “Would to God I were not so madly fond!” But the dance ended and Minnie returned to her place, with brightened eyes and flushed cheeks. Sending her companion for an ice, she turned to Harry. “Now I will dance with you, patient creature, if you will wait a little longer.” “You are very kind,” said he, more bitterly than before. She started and looked at him, but laughed lightly as she said— “You are very particular in commending my goodness, but you do not seem pleased.” “No, Minnie; for I am too unhappy to conceal it,” was his reply. “I had thought you loved me better.” “And since I did confess that love,” said she haughtily, and coloring deeply, “by what right do you doubt it?” “Ask others beside myself, Minnie; ask all the world here, if this very hour you have not given me cause to think myself weighed in the balance with another?” “You are jealous then. I had not deemed your breast capable of harboring so base a passion,” said she scornfully. “My actions are yet uncontrolled, and I must beg leave to decline any dictation of terms from your lips.” He turned pale with suffering, but remembered her youth, and calmly met her eye. “You do me injustice, Minnie; I had no such intention I assure you.” At this moment Mr. Freeman handed her a plate of frozen strawberries, and a smile flitted over his features as he remarked their own. It was evident to him—there had been a dispute and he chose the opportunity. Quietly approaching the musicians, he gave them an order, and they began a mazourka then much in vogue. Harry’s head was turned away, and Minnie gave him a hurried glance as a most melodious voice was entreating her to dance. “Ah!” said Mr. Freeman, smiling and gazing at her, “is it forbidden already?”
  • 77. “I do not understand,” replied she in some confusion; but when Harry looked up she was gliding over the floor again, after reminding him of his own invitation. He rushed from the room, and making his adieus to Mrs. Bliss, drove rapidly home. It was not easy to imagine his state of mind, but Kate followed her sister until the mazourka ended, to warn her of a coming storm. Taking her arm, she bowed coldly to Mr. Freeman, who bit his lip and fell back among a group of gentlemen, some of whom had heard his wager and now laughed at his defeat. “Defeat,” echoed he. “I have driven il caro off in despair, and a few words more will settle all between the charming Minnie and myself. Not that I care particularly for her, but rejoice in the downfall of Mr. Harry Selby.” “Nous verrons,” said a young man, who surveyed him with a look of disgust. “Miss de la Croix may like to flirt, but she loves Mr. Selby more. And I for one doubt your success.” “Had I but one quarter of an hour alone with her, she would no longer dream of him. She loves me now, and I will prove it yet.” Some one touched him as he walked away, and Paul Linden beckoned him to another room. “My sister’s name is not to be sullied by such lips as yours, Mr. Freeman. I hold you accountable for what I have heard to-night, and trust you to prepare yourself to be made so.” They passed into the street, and angry words rose between them, but when once more Minnie’s name was pronounced, Paul passed his hand across the face of the speaker and left him. Poor Kate! little knew she the “business” that detained him the next day, and when at length Blanche came to her with a white face and trembling lips to prepare her for the dreadful news, she seemed unable to understand until it had been repeated—that her own husband was dangerously, though not mortally wounded, in a duel with Mr. Freeman. With a loud shriek she became insensible, and thus they lifted her into the carriage, while the rest followed. Paul had been conveyed to her aunt’s, and there lay weak and fainting from pain and loss of blood. The ball had been extracted, and his poor Kate
  • 78. was told to be calm! lest her agony prove fatal to the one she loved beyond all earthly things. Calm! when her heart was torn and bleeding, when there was perhaps no chance of his recovery! But woman-like, she strove against her misery and bent down to kiss him, half fainting as she gazed at his pale face. He turned to her with such a look of love! “Do not blame me, Kate, I would have died to spare you a moment’s unhappiness, as careless as this may seem of your feelings,” murmured he. “Hush, Paul! for God’s sake hush!” cried she clasping his hand. “Do I not know your love for me? Do not speak my own husband— be assured that I would never blame you. But for my own happiness be careful and follow the doctor’s advice—be quiet.” He fell asleep with his hand in hers, and she sat beside him motionless as a statue, the big tears falling over her face the while. She knew how much she had at stake, she knew by what a mere thread that precious life was hung, but she nerved herself to restrain her wretchedness, to keep silent her torturing fears, and tried to hope. Poor Minnie! throwing herself upon her knees she entreated her forgiveness for the pain she had caused—the tempest of grief her fault had raised. Kate gently put her head against her breast. “My poor Minnie! my darling! who could refuse your forgiveness? God knows you are suffering sufficiently now—but oh! if he should die!” Her composure gave way out of her husband’s presence, and her convulsive sobs seemed too much for her strength. They gathered around her frightened and weeping, beseeching her to cease, lest her cries reached Paul himself. A composing draught at length relieved her, and this was her last indulgence of her sorrow while a prey to such anguish as in vain assailed her. From that day her fortitude never forsook her, and neither loss of sleep or appetite were able to affect her. Minnie shared her vigils—both were mere shadows of their former selves, both watching with pale faces and sunken eyes the patient sufferer. Minnie left the room only when Harry Selby’s watch came round. She had not seen him since the fatal evening, nor mentioned his name after writing him when the
  • 79. meeting took place. It was a touching letter, and Harry bowed his head over it with a burst of manly grief. It ran thus: “I write to say that you are free—you cannot but wish it, after what has passed. You cannot but hate one so apparently void of all feeling—so wickedly frivolous. Forgive me for the pain I cause you, God knows I am in need of pity! Should the worst happen, I will be guilty of my brother’s blood, a thought that maddens me. Farewell, I will always pray for your happiness. “Minnie de la Croix.” And she drooped day by day, with a weight of iron on her soul. Her sister’s sorrow—Paul’s suffering, and the separation from her young heart’s treasure were cankers, to eat away its hopes, and wither its freshness. Her father, too—how much he had changed, how gray he had become! How sad her sisters were, how gravely Kenneth spoke! The thought of their now deserted home, of its once happy aspect. She thought of its cheerful, merry-hearted inmates, and the light voices that were now so low and sad. She remembered her mother and the last blessing, the prayer that they might be forever united—she remembered the dead infant and Kate’s return— poor Kate! that she should be the only sufferer! Gladly would she have laid down her now darkened life for her sister—gladly would she have sunk into the tomb, to hide her bursting, breaking heart! One night she sat at the head of Paul Linden’s bed after entreating Kate to go once around her aunt’s garden and breathe the sweet spring air. Her face was buried in her hands, and by the deep sighs that shook her frame a portion of that young creature’s misery might be conceived. On the opposite side of the bed sat another, watching her, by the darkened light of the sick room, with a look of deep compassion. He had entered unperceived, and there was a start of surprise as his eyes fell upon the drooped figure. He could never mistake it—he knew the outline of that once loved form —he knew the little hands that were clasped across her knees, and
  • 80. he held his breath least even that should rouse her. Involuntarily he held out his arms, but at a movement from the invalid she sprung to his side, and her companion bent down to raise him as he asked for some water. Minnie held the glass to his lips, and replaced it on the table without raising her eyes to his face, for she thought it was Kenneth; when she turned to seat herself her eyes fell upon the figure of him she loved! The blood forsook her cheeks, and with a low smothered cry she covered her face once more. When she looked again he was still there, and his hand was held out beseechingly toward her. Slowly she gave him hers, it was no bond of renewed faith, she thought merely that he offered her forgiveness, and he seemed now further from her than ever, as she remembered this and looked at the wounded man upon the bed. Sick at heart she sunk back upon her chair and buried her head in the clothes. The silence around them was painful now in the extreme, and Paul’s heavy breathing fell like a reproach upon her tortured heart. Years seemed to pass, and when Blanche came in to take her place, she breathed a prayer of thankfulness for the relief a change afforded. She hurried from the room out into the garden to give vent to her wretchedness. She had then seen him again—seen him, she resolved for the last time. She had suffered too much for the last half hour to dare it again, and she dwelt upon the remembrance of his loved features as if to impress them more deeply yet upon her heart. Alas! how wildly she clung to him, now that she had bid him a last farewell! how intense grew the love she had lavished upon him with a woman’s bounty! She returned no more that night to her brother’s chamber, for she knew who watched beside him, but the lowly vigil she kept within her own was an eternity of grief. Toward daylight Lisa entered with a face of joy. Clasping Minnie in her arms, she burst into tears as she spoke. “Minnie, my poor child! he is saved! saved at last!” She sunk upon the floor in a swoon, and during Paul’s convalescence, another of the household lay at death’s door. Day after day her fearful ravings smote their heavy hearts, and a gloom seemed hanging like a vast pall over them. Father, brothers and
  • 81. sisters, grew pale and thin; but there sat one beside that bed who seemed to grow old as he looked upon the distorted countenance of his Minnie. His poor blighted flower! The physicians did not despair, but they did not bid them hope, and so a week passed—a week that dragged by like a lengthened chain that overpowered them. Then there came a gleam of light— And Minnie opened her eyes once more to life. Who can tell their joy—their prayers of thankfulness as at length she knew them all? At the door now, sat her lover, not daring to enter lest his presence prove fatal, but as the tones of her sweet feeble voice reached him, he leaned against the wall for support. Rose wept silently at his side, and pressed his hand as he called on Minnie’s name——they might yet be happy! Minnie’s first coherent inquiry was for Paul Linden, and the news of his recovery was the first and surest step to her own. He came to see her as soon as he heard it, and tenderly kissing that pale thin cheek, remained sitting by her with his hand in hers. “Will you forgive me, Paul?” she asked, her eyes filling with tears. “Dear child,” replied he tenderly, “did you imagine all this time that I could ever do aught but love you? So do not speak of forgiveness again, we are all too happy at your recovery to think of any thing but joy.” How gratefully Minnie listened to all this, and how much she prized the affection each in their turn was striving to prove! She had awakened from a dream of horror to a new existence. She had grown wiser—the trial had purified her, and if at times her thoughts would turn to the happy hours of the past—to the blessing his love had seemed, she struggled against the regret that stung so sharply, and bowed her head to the justice of her punishment. It never occurred to her, poor penitent! that Harry could love her still, she thought her own conduct fully justified his accepting the freedom she had offered him, and heavy as the stroke came—deeply as it was felt, Minnie looked upon it as her due, and bound herself to suffer in silence—to battle with her troubles. One morning her father carried her out into the garden, and seated her under a climbing jessamine that covered a bower at the
  • 82. side of the house. Few would have recognized the once gay and blooming girl in the delicate creature that leaned back exhausted in the chair—few could have realized the active little sprite, the idol of the ball-room, in this languid, helpless figure; but to her father and sisters there was something sweeter than ever in their suffering Minnie. A placid smile overspread her features at the sight of the sweet flowers that bloomed around her, and she held out her hand toward a cluster of fragrant Lady Banks that grew near. “I can tell you a secret of the loveliest bouquet you ever saw, Minnie,” said Rose, gathering the bunch of tiny roses for her sister. “A bouquet that was sent an hour ago by a friend of yours and mine. It is the eighth received to-day, and I reserved this one as a bonne bouche, after all the rest. Now I am going to get it while you sit here, and papa will watch you until I get back.” Her father looked tenderly at his poor bird, and stooped to kiss her. She smiled so gratefully in return, that the tears sprung to his eyes. “We will go home soon, father,” said she, holding his hand; “we will go back to the old homestead. I pine for my native air like a caged bird, and long to be there again.” He assented with a look of joy, for it was the first time she had mentioned her home, and he fancied she was stronger as she spoke. Rose came running back with the bouquet, and the sick girl bent forward to receive it. Rare exotics and simple flowers lay lovingly together, and round the edge were rows of double violets—sweet flowers of spring that gladdened her heart. How many times she had sought them in the thickly bordered beds at home! How often she had kissed them with childish delight, when the fresh perfume had come like a message to tell her the spring had breathed upon them. And now they whispered of the old place and its past joys—of the time that had elapsed since she had been there, and the warm tears fell upon the leaves like shining drops of dew. “And who sent this bouquet, Rose?” asked she, as her father walked toward the house. “Who sent it?” “One who loves you dearly, Minnie, and who longs to see you,” replied she. “Will you let me bring him here, dear sister?”
  • 83. “Him!” murmured the girl, as the color stole slowly over her cheek. “Him, Rose!” A rustling among the leaves was heard—Rose fled, and once more Harry Selby and Minnie were alone! She gazed at him for a moment, and burst into tears. “Harry! why are you here, for God’s sake!” she cried, as he knelt beside her and wound his arm around the fragile form he had so longed to see. “Why am I here, Minnie?” said he reproachfully. “Can you ask me? Is it not to tell you once more how dear you are to me—how wretched I have been?” “You love me still, then?” she said feebly, and fixing her eyes upon him. “I am not worthy of your love, Harry; I have deserved to lose it.” “Minnie! Minnie! say not so! Whom could I ever love as I love you? Whose memory has followed me through long years but yours —what torture have I not endured since last we met?” A look of gladness beamed from those beautiful eyes, and she clasped her hands together. “My God!” she whispered, “he loves me then in spite of all!” and she bowed her head upon her knees. “Loves me! after all that I have caused him and others to suffer.” “And have you not suffered likewise, my own Minnie? How little you knew me, if you supposed for an instant that I could ever be happy without you!” She learned to know him, reader; she learned to feel how deeply he loved her, how noble and just he could be, and the next day he bore her into the carriage that was to take them to Oakwood, and took his seat opposite to her, that he too might watch her through the drive. It was a gala day that—father and sisters, husbands and the lover, his happy uncle and Mr. and Mrs. Bliss followed Minnie to instal her with new honors in her old home. Winny and Sampson headed the procession that came to meet them, and mingled their tears with the rest. Paul had become a hero to them, Minnie a greater pet than ever, and they both accepted the ovation as kindly as it was meant.
  • 84. After dinner, as Minnie sat playing with her beautiful fan, Harry took it gently from her hand. “There is a secret in this fan, Minnie, unknown to any but myself. Shall I unfold it for you?” She assented, and touching a spring in the little mirror at the side of the fan, he held it up to her. It disclosed a small, but perfect miniature of himself! She gave an exclamation of surprise. “Why, Harry! your own dear self! Now I know who gave me this fan—now I guess the sender of this exquisite gift. To think how often I have used it, too, without knowing its real value.” He smiled and pressed the soft hand he held. “And do you not think me a vain fellow, Minnie, mine, for having my own self, set into a frame like this? See on the other side, dearest, what I dared to do?” It flew open there and a ring fell out, a tiny bouquet of the brightest diamonds upon it, and an opal in the centre that changed its hue at every motion of the hand. Harry placed the circle upon that taper finger, and held captive the hand that owned it. “Now, Minnie! I loved you so dearly that I vowed to strive and win the very privilege I have taken, of placing this ring upon your hand myself. I will not let you go until you now tell me when I may put another where this now is, that will bind us closer yet. Tell me, Minnie, and make my happiness complete.” And I suppose that Minnie told him, reader, for the last time I was at Oakwood there was the happiest bond assembled that earth can show. Kate, my poor Kate! was the delighted mother of another girl called Minnie, while a little Paul that ran about had a decided resemblance to Harry Selby, the proudest man alive. Blanche was beginning to look matronly with her three treasures, and Rose was wandering down the avenue with another nephew of Mr. Selby’s. Lisa, my queen-bee, was herself still—I could not say more for her, and Mr. de la Croix sat at the hall door watching his children and grand-children with a happy look. “They have suffered enough,” said he to me; “but my crown of jewels, my friend, is brighter than ever, after the breath of adversity for a while dimmed its lustre. Kate and
  • 85. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com