Case Study: The British Library Reader

seedjaggedInternet and Web Development

Nov 12, 2013 (3 years and 9 months ago)

74 views

G53ELC

Or: Plug
-
ins, the first step to D.I.

Case Study: The British
Library Reader

G53ELC

Real Life Now…


Legentis Ltd submitted a proposal to the British
Library in response to a RFT


We got the contract


a pilot study for ≈10K, with
a potentially enormous follow up contract if we
succeed


We have 10 weeks from last Friday to deliver


Legentis is only me (with Colin on this one) and
already has two large contracts plus University
work
-

P a n i c !


Time to recruit some of you lot?


But the “mythical man
-
month” applies…

G53ELC

User Stories


The user selects a directory full of
scanned images of readers request chits.
Where possible these are read and stored
in a database without manual intervention.
Where the result is in doubt the chit
together with the recognised result is
presented to the operator for correction

G53ELC

An example chit

Anonymous

There are six different styles of chit

The database model is easily derived from these chits

G53ELC

First cut data model

G53ELC

An enterprise application?


The pilot can be a standalone desktop
application (i.e. No)


The full project would involve on or more
servers, a back
-
end database and a
number of client workstations (i.e. Yes)


It makes sense to build the prototype so
that it can be reconfigured to become a
thin client, a set of business processes
and a persistence layer


less work later

G53ELC

What might it look like?

A mock
-
up


allows immediate
feed
-
back from user

G53ELC

An
agile

approach needed


We will follow the principles of XP


Frequent small releases


Unit testing


Continuous integration


Value simplicity


Refactor often


Can’t pair program but will check each
other’s code


G53ELC

Set up your development
infrastructure


Visual Studio 2005 or later or Eclipse
[VS2008]


Source code control


Subversion
[
svn
]


Project manager / bug tracker
[
Trac
]


Qt toolkit
[Qt 4.4 commercial]


Build tools (Maven, ant)
[
nant
]


Unit testing frameworks
Junit

[
QtTest
]


Cruise control (
.Net

version)
[
CC.Net
]


Code and style
validators

(
DevPartner
,
valgrind
,
Javabugs
… )


Documentation tools


[Latex, EA 7.1,
Doxygen
]

I set this up on Saturday
in 2 hours


it will repay
that effort a hundred
times over

G53ELC

We need to work
FAST


No time to agonise over the curse of
computing today:


that is:
Too many choices!


I chose:


C++ for application logic (unmanaged)


Qt (
Trolltech
) for the client interface (C++)


Hibernate for persistence (managed C++)


Async

SOA using WCF and
.Net

Remoting

for enterprise application (managed C++)

G53ELC

The domain model

G53ELC

Editor domain model

G53ELC

What do I do next?

G53ELC

The scary part


I don’t know how to
make these components


I want to get something
basic working fast


I will want to try several
methods for most of the
components


The code is going to be
a mess all over the
desk…

G53ELC

The Solution


Make a framework with
interfaces defined for
each component


Build “mock”
components as plug
-
ins


Code each plug
-
in
separately and just drop
it into the plug
-
in folder
to activate it.


Tidy, agile, testable,
modifiable and reusable!

G53ELC

That is “loose coupling”


An object does not know what object it will
call merely that it conforms to a defined
contract or interface.


We can change the called object without
changing the caller


HUGE ADVANTAGE


We inject the dependencies


in this case
by dropping them in the plug
-
in directory


If we separate objects from “their wiring”
and get a framework to configure that we
have D.I.


for Example “Spring”

G53ELC

D.I. Following Martin Fowler


Originally called Inversion of Control; IOC


Dependency Injection is a better term; D.I.


Closely related to Aspect Oriented
Programming; AOP


leave that for now

G53ELC

What is Spring?



Also referred to as a lightweight container


Necessity is the mother of invention


Born of the need to escape the failures of
EJBs


Inversion of Control (IoC) Container



What is IoC?

G53ELC




Dependency Resolution


Plain old way


‘new’ your dependencies


Service Locator


use a ‘locator’ to get instances of your
dependencies


Dependency Injection


Get your dependencies handed to you.


These all imply certain couplings…

G53ELC

Plain old dependency creation


Example
:


public class Foo {



private IBar bar;


private IBaz baz;



public Foo() {




bar = new SomeBar();




baz = new SomeBaz();


}

}




Characteristics


Cons


Your class depends upon all it’s
dependencies depend on.


Your class must know how to
assemble instances of it’s
dependencies and their
dependencies.


Hard to change behavior without
opening code


Hard to test as you must also test
depends. Cannot use mocks.


Pros


Easy to understand

G53ELC

Service Locator


Example:


public class Foo {



private IBar bar;


private IBaz baz;


private IServiceLocator locator;



public Foo(IServiceLocator locator_) {




locator = locator_;




bar = locator.Get(




ServiceNames.BAR



);




baz = new SomeBaz(




ServicesNames.BAZ



);


}

}


Characteristics



Cons


Your class depends upon the service
locator


You must still get the locator to the
class


either statically (yuk) or via…
some sort of injection like mechanism



Pros


Easy to understand


Testable


Flexible


Extensible


Enforces separation of interface from
implementation


G53ELC

Inversion of Control


Example:


public class Foo {


private IBar bar;


private IBaz baz;


public Foo(IBar bar_, IBaz baz_) {




bar = bar_;





baz = baz_;


}

}


Characteristics



Cons


You must create dependencies to
pass along



Pros


Easy to understand


Testable


Flexible


Extensible


Enforces separation of interface
from implementation


Code is simple and clear


G53ELC

Inversion Of Control


Inversion Of Control, Dependency
Injection, The Hollywood Principal etc.


In stead of instantiating concrete class
references in your class, depend on an
abstraction and allow your concrete
dependencies to be given to you.

G53ELC

Injection Types


Setter Injection


Pass dependencies in via mutators/ property
setters



Constructor Injection


Pass dependencies in via constructor




G53ELC

Without IoC

G53ELC

Concrete Class Dependency

G53ELC

Dependency passed in

G53ELC

Same thing with property

setter

G53ELC

The problem with IoC by itself



To build these objects now takes
assembling the whole object graph of
dependencies!!!


What a pain!!!


G53ELC




Containers to the rescue


The solution is a container


to manage
the complex creation, lifecycle, etc.


This is where Spring comes in.


To manage complex object assembly


I ask for object named “Y”


the container gets any
dependencies for that type, creates then or gets
cached instances


gives them to the object I am
trying to get and returns me that object. I then use
this object as I normally would.


To manage object lifecycles


Singleton
-
ness or Non
-
Singleton
-
ness

G53ELC

Spring’s Heart




At it’s core


Spring is a framework for wiring up
your entire application.

G53ELC

Object Factory


Object Factory


The thing that creates object instances for you


You ask the object factory for a named item


it
returns an instance to you


either a singleton or a
prototype.


Singleton


There is 1 and only 1 instance


Each time you ask the object factory for one


you get
the same one


Prototype


This is a ‘non
-
singleton’


Each time you ask the object factory for one


you get
a new one

G53ELC



33

Why IoC with a Container


Support programming best practices:


Separation of interface from implementation


Allows you to substitute implementations


Code is smaller and cleaner


program your
intent first

G53ELC

Some Principles


The Dependency Inversion Principle (DIP)


Depend upon Abstractions. Do not depend
upon concretions (is that a word)


stated by
Robert Martin.


The Open Closed Principle (OCP)


A module should be open for extension but
closed for modification (Bertrand Meyer).


Prefer composition to inheritance


GOF patterns often use this principle as
composition is a looser form of coupling


G53ELC

Why use the DI pattern?


Testability


You can substitute implementation


specifically pass in a Mock object so you only
write code to test the code you are writing.
You are NOT testing the code in your
dependencies.


Manages assembly of complex objects for you!


Reduce the coupling of code


Easy reconfiguration or modification


Reusability is better due to decreased coupling

G53ELC

Some other IoC Frameworks


Hivemind


Pico Container


EJB 3


JBoss Seam

G53ELC



37

Spring for Java

G53ELC



38

Spring for .Net

Core

AOP

Services

Data Access

Web

Desktop

Windows Services


3
rd

Party
Integration

G53ELC

Should I have used Spring?


My Plug
-
in approach is
already fully decoupled


It has only one level of
dependency injection


Is that enough?


Yes! So no great
advantage from Spring
wiring things up for us


Our solution was good
enough here

G53ELC



An example using Guice
coming soon…