Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

244 lines (239 sloc) 16.958 kb
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>High Level Concepts</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body>
<TABLE cellSpacing="5" cellPadding="0" width="100%" border="0" height="100%" ID="Table1">
<TR>
<TD valign="top" width="210" class="form">
<p align="center">
<A href="http://sourceforge.net"><IMG src="http://sourceforge.net/sflogo.php?group_id=104740&amp;type=5" width="210" height="62"
border="0" alt="SourceForge.net Logo"></A>
</p>
<P style="LINE-HEIGHT: 25px">
<A href="default.htm">Home</A><BR>
<a href="http://sourceforge.net/projects/structuremap">StructureMap on SourceForge</a><br>
<A href="Basic Architecture.htm">Basic Architecture</A><BR>
<A href="Concepts.htm">Concepts</A><BR>
<A href="StructureMap-API.chm">API Documentation</A><BR>
<A href="FAQ.htm">FAQ</A><BR>
<A href="Configuration.htm">Configuration Schema</A><BR>
&nbsp;&nbsp;&nbsp; <a href="MementoSources.htm">Memento Sources</a><BR>
&nbsp;&nbsp;&nbsp; <a href="NodeNormalized.htm">Node Normalized Xml</a><BR>
&nbsp;&nbsp;&nbsp; <a href="AttributeNormalized.htm">Attribute
Normalized Xml</a><BR>
&nbsp;&nbsp;&nbsp; <a href="Attributes.htm">Attribute Usage</a><BR>
&nbsp;&nbsp;&nbsp; <a href="Scoping.htm">Instance Lifecyle Scoping</a><BR>
<A href="ConfigurationManagement.htm">Configuration Management</A><BR>
&nbsp;&nbsp;&nbsp; <A href="StructureMapDoctor.htm">StructureMapDoctor</A><BR>
&nbsp;&nbsp;&nbsp; <A href="StructureMapExplorer.htm">StructureMapExplorer</A><BR>
&nbsp;&nbsp;&nbsp; <A href="structuremap.deployment.htm">deployment Task</A><BR>
&nbsp;&nbsp;&nbsp; <A href="structuremap.verification.htm">verification Task</A><BR>
&nbsp;&nbsp;&nbsp; <A href="ValidationAttribute.htm">ValidationMethod Attribute</A><BR>
&nbsp;&nbsp;&nbsp; <A href="NAnt Tasks.htm">Other NAnt Tasks</A><BR>
<A href="Troubleshooting.htm">Troubleshooting</A><BR>
<A href="SingletonInjection.htm">Singleton Injection</A></P>
</TD>
<TD valign="top" style="PADDING-LEFT: 25px">
<h1>High Level Concepts</h1>
<h3>Object Oriented Design</h3>
<p>Object oriented systems are composed of a myriad array of objects communicating
by sending messages to exposed interfaces. To a large degree, the qualities of
an OO design are determined by the structure, organization, and responsibility
assignments of the objects in a system.&nbsp; The qualities of a system most
affected by structure are flexibility, extensibility, maintainability, and
testability.&nbsp; Applications usually meet their demise when the system is
determined to be too difficult or costly to change. The symptoms of a dying
application are a loss of clearly defined structure,&nbsp;an unclear division
of&nbsp;responsibilities in the code,&nbsp;and difficulty&nbsp;testing and
troubleshooting the application.&nbsp;&nbsp;</p>
<P>Over the years a series of rules and principles have been discovered and
developed to describe well-structured systems.&nbsp; Possibly most important is <EM>
Separation of Concerns</EM> – pulling separate aspects of the system like
persistence, security, or business logic&nbsp;into separate classes and
packages.&nbsp; Another key concept is the combination of highly cohesive
classes in a loosely coupled structure. The more highly coupled two components
of a system are, the more difficult the system is to maintain, test, and reuse.
A class should have a cohesive set of responsibilities in a narrow
domain.&nbsp; In other words, simpleton classes that do only one thing are much
easier to code and test than <EM>God</EM> classes that take on far too many
unrelated responsibilities.&nbsp;
</P>
<P>By itself, StructureMap does not improve an application.&nbsp; StructureMap
simply makes using good design techniques for structuring an application
easier.</P>
<h3>Impact of Test Driven Development and Emergent Design</h3>
<p>The advent of Test Driven Development (TDD) techniques and emergent design
methodologies like Extreme Programming has refined the way that we build OO
systems.&nbsp; Taking an evolutionary approach to OO design and structure is
best accomplished through supple code.&nbsp; The desire to express design
through automated unit tests requires and enforces a very fine grained approach
to class design.&nbsp; Both practices are maximized by loose coupling between
classes.</p>
<P>
Another wrinkle is the desire to test classes either in isolation or in small
clusters of classes. Because each class is small, it depends on many of its
neighboring classes to provide services in order to accomplish anything.&nbsp;
In order to truly test a class in isolation, TDD practitioners use <a href="Concepts.htm#stub">
Service Stub</a> objects&nbsp;or <a href="Concepts.htm#_Mock_Object">Mock
Objects</a> as stand-ins for the external dependencies of the class being
tested. Utilizing these testing techniques requires a mechanism to substitute
the dependencies at runtime. The responsibility for discovering and attaching
dependencies can be removed from a class to maximize testing automation
opportunities. Much of the goal of StructureMap or any IoC container is to
provide an easy mechanism to attach and assemble dependency chains.</P>
<p>&nbsp;</p>
<h3>Building Blocks of Object Oriented Programming</h3>
<p>At the coding level, the building blocks of an object oriented design are
encapsulation, polymorphism, and inheritance. Encapsulation is important for
the sake of loose coupling.&nbsp; As an example from classic 3-tier systems, a
user interface object calls a business logic object that will in turn call
database access objects to persist new data. The UI code should not need to be
bound to any kind of database engine or really know anything about how the
business objects process the requests.&nbsp; Using encapsulation, the UI code
does not have to be so tightly coupled to the internal mechanisms of the
business logic code. On the other hand, we want the dependencies of the
business logic objects to be externally attached to enable reuse and testing,
so how does the UI code create and utilize the business logic without breaking
encapsulation? One answer is separate constructor functions on the business
logic classes, one for testing and one for production. Another alternative is
to use an IoC container like StructureMap to instantiate and assemble the
business logic objects.&nbsp; The UI code only needs to ask StructureMap for an
instance of the business logic type.</p>
<p>Polymorphism is the ability for multiple objects to be interchangeable by
exposing the same interface.&nbsp; Polymorphism is the single most important
abstraction technique in object oriented design.&nbsp; By making a class
dependent on a public interface, the class should be able to work with multiple
implementations of the interface.&nbsp; The extensibility of a system is
greatly improved with the ability to <i><a href="Concepts.htm#_Plugin_Pattern_(Fowler)">
plugin</a></i> a new implementation class into an existing interface
slot. Mock objects and service stubs use polymorphic interfaces to allow the
real functionality to be replaced with hard-coded testing implementations for
automated testing in isolation. Polymorphism is an abstraction however. At some
point the proper implementation of an interface needs to be created and
attached to the necessary calling classes.&nbsp; A common technique in TDD is
to use an interface as a point of abstraction to enable mock objects in order
to isolate a class for testing.&nbsp; StructureMap can be used as a generic
mechanism to utilize polymorphic instances as an alternative to hard-coded <i>factory</i>
and <i>builder</i> classes.</p>
<p>&nbsp;</p>
<h3>Inversion of Control (IoC) Containers</h3>
<p>Inversion of Control containers like StructureMap, PicoContainer, and Spring are
an attempt to improve OO designs by minimizing the effort necessary to utilize
existing OO techniques. The <EM>Inversion of Control</EM> moniker refers to the
indirection of object instantiation and linkage. Objects do not directly create
and call other objects, StructureMap "injects" dependencies into an object
instance through the object's constructor or public properties.</p>
<P>StructureMap is not really a "Container" of anything except the knowledge of
which classes to create for a requested interface.&nbsp; The term "Container"
originates from the J2EE world when the early IoC frameworks were considered to
be simple, lightweight replacements for heavier J2EE application servers.&nbsp;
StructureMap does not track created instances or manage instance lifecycle like
most of the Java IoC Containers.</P>
<p>&nbsp;</p>
<h3><A name="DI"></A>Dependency&nbsp;Injection / Inversion of Control (IoC)</h3>
<p>In a well-factored OO design, a class may have dependencies on other classes to
perform useful tasks. These dependencies can be attached in roughly two ways,
the class can create its own dependencies, or the dependencies can be
“injected” into the class instance.&nbsp; Removing the responsibility for
creating dependencies from a class is called Dependency Injection, or Inversion
of Control.</p>
<P>
Dependency Injection has a couple of variants.&nbsp; The dependencies can be
attached by either setting properties&nbsp;or using a constructor function to
setup all dependencies at instantiation. StructureMap primarily uses the <EM>Constructor
Injection</EM> variant of IoC. The advantage of this method is a guarantee
that the proper dependencies are setup before any execution can take place on
the new class instance.&nbsp;The constructor function can become a contract
stating the dependencies of one class on the services provided by other
classes. &nbsp;Another advantage is a streamlining of a classes public
interface by negating the need for public <i>setter</i> properties.&nbsp;</P>
<P>New in version 0.90 is the ability to use <EM>Setter Injection</EM> as
well.&nbsp; This is particularly important when using StructureMap to configure
and create class objects that are external to your application code.</P>
<p>&nbsp;</p>
<h3><a name="_Plugin_Pattern_(Fowler)"></a>Plugin Pattern (Fowler)</h3>
<p>This pattern refers to a mechanism of creating an object instance of a certain
interface at runtime.&nbsp; The actual configuration and implementation of the
instance is usually controlled by external configuration.&nbsp; Using a Plugin
pattern allows a new class to be “plugged” into an existing codebase without
modifications to the existing code.&nbsp; StructureMap can be used as a generic
Plugin mechanism.&nbsp; This pattern is very common in application frameworks.</p>
<p>&nbsp;</p>
<h3>Memento Pattern (GoF)</h3>
<p>A Memento pattern is an object that models the internal state of another object
instance.&nbsp; The purpose of a Memento is to externalize the configuration of
an object instance so the object can be recreated with the same state at a
later time. Another way to think of a Memento is as a dehydrated object.&nbsp;
Just add just runtime water, and presto, an object instance of the same
configuration.&nbsp; The intrinsic Xml and binary serialization capabilities of
.NET are examples of the Memento pattern in .NET.&nbsp; StructureMap uses the
Memento pattern to store configuration information.
</p>
<p>&nbsp;</p>
<h3><a name="_Open/Closed_Principle"></a>Open/Closed Principle (OCP)</h3>
<p><EM>A module should be open for extension but closed for modification</EM></p>
<p>Software systems are never completed, only abandoned when the ability to change
or extend a system is compromised by poor structure or amount of rework
necessary to implement the new changes.&nbsp; In situations where system
requirements will be changing, the Open/Closed Principle can be utilized in
conjunction with a Plugin pattern to extend an existing codebase by adding a
new module with minimal or no changes to existing code.&nbsp;&nbsp;</p>
<P>OCP is frequently employed in user interface frameworks.&nbsp; Using OCP, new
screens and menu commands could be added to the user interface by configuring
the application to use the new classes without changing existing code.&nbsp;
Another common example would be adding security rules or business rules to
frequently changing application.</P>
<p>&nbsp;</p>
<h3><a name="_Dependency_Inversion_Principle"></a>Dependency Inversion Principle
(DIP)</h3>
<p><i>Depend upon Abstractions. &nbsp;Do not depend upon concretions</i></p>
<p>Simply put, the Dependency Inversion Principle is about creating a firebreak
around volatile or simply difficult to test modules.&nbsp; Using DIP removes a
direct coupling between two classes, enabling the usage of mock objects,
service stubs, and different implementations of the dependency.&nbsp; In a TDD
process, DIP is often used for no other purpose than to facilitate automated
unit testing.&nbsp; A common example from the .NET Framework is the IDb*
interfaces in ADO.NET.&nbsp; Building a system around the abstract interfaces
instead of Oracle or Sql Server classes avoids a tight coupling to a specific
database.engine.</p>
<P>&nbsp;</P>
<h3><a name="stub"></a>Service Stub</h3>
<p><i>Removes dependence upon problematic services during testing.</i></p>
<p>A Service Stub replaces an external dependency with a static stand-in
object.&nbsp; Service Stub's are typically used to hard code return
values.&nbsp; A classic example would be a data access class that returns a
DataSet.&nbsp; A Service Stub for this object might return a DataSet read from
a static&nbsp;file instead of pulling the information from a database.&nbsp;
During testing, the data returned by the data access interface would always be
known, so that the processed outcome of the data from other classes should also
be static -- facilitating automated testing.</p>
<p>&nbsp;</p>
<h3><a name="_Mock_Object"></a>Mock Object</h3>
<p><i>A debug replacement for a real-world object</i></p>
<p>A <i>mock object</i> is particularly useful for dependencies on external systems
that are difficult to test.&nbsp; Mock objects enable the runtime replacement
of a real object that might be slow, difficult to setup,
or&nbsp;non-deterministic with a&nbsp;well behaved “Mocked” object that behaves
in a known way.&nbsp; The goal of mocking is to test one
class&nbsp;independently, even though it cannot function without interacting
with&nbsp;the class's dependencies.&nbsp;</p>
<P>StructureMap was largely developed&nbsp;during a WinForms "Smart Client"
project.&nbsp; The user interface used a <EM>Model-View-Controller</EM> design
for all screens.&nbsp; Each controller class interacted with a view, and other
classes like web service proxies and object caches.&nbsp; In unit testing for a
typical controller class, both the view and web service proxies would be mock
objects to test the controller interfaction with its dependencies.</P>
<P>Mock objects are active participants in the testing process.&nbsp; StructureMap
directly supports using the NMock framework for dynamically mocking
classes.&nbsp;&nbsp;StructureMap can also inject static mocks or stubs at
runtime.&nbsp;</P>
</TD>
</TR>
</TABLE>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.