winter is coming (johannes vs johanes

60
Winter is coming (Johannes vs Johanes Nets DevDay 2012 Johannes Brodwall, Principal Architect Steria Norway @jhannes

Upload: ginger-mcdowell

Post on 01-Jan-2016

79 views

Category:

Documents


1 download

DESCRIPTION

Winter is coming (Johannes vs Johanes. Nets DevDay 2012 Johannes Brodwall , Principal Architect Steria Norway @ jhannes. Why dependency detox ?. < beans default-autowire = " constructor " > - PowerPoint PPT Presentation

TRANSCRIPT

Winter is coming

(Johannes vs JohanesNets DevDay 2012

Johannes Brodwall, Principal ArchitectSteria Norway

@jhannes

Why dependency detox?

<?xml version="1.0" encoding="UTF-8"?><beans default-autowire="constructor">

<bean class="no.steria.spring.ApplicationServiceImpl" />

<bean class="no.steria.spring.IncrementService" />

<bean class="no.steria.spring.ReportService" />

<bean class="no.steria.winterapp.provided.JdbcEntryDao" />

<bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean></beans>

public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("..."); ApplicationService applicationService = context.getBean(ApplicationService.class); applicationService.incrementAndReport(new Date());}

Who created that object?

Is that setter still in use?

Are we sure @Transactional is

picked up?

How does @Transaction

work?!

In what <import> is that bean defined?

Where is the business logic?!

The “Service” here does nothing!

Less magic

public static void main(String[] args) { ApplicationService applicationService = new ApplicationService(createDataSource()); applicationService.incrementAndReport(new Date()); }

Explicit coupling

public class ApplicationService {

private IncrementService incrementService; private ReportService reportService;

public ApplicationService(DataSource dataSource) { this(new IncrementService(dataSource), new ReportService(dataSource)); }

public ApplicationService(IncrementService incrementSvc, ReportService reportSvc) { this.incrementService = incrementService; this.reportService = reportService; }

public void incrementAndReport(Date date) { incrementService.increment(date); reportService.printReport(); }

}

public class IncrementService {

private EntryDao entryDao;

public IncrementService(DataSource dataSource) { this(new JdbcEntryDao(dataSource)); }

public IncrementService(EntryDao entryDao) { this.entryDao = entryDao; }

public void increment(Date date) { entryDao.insertEntry(new Entry(date)); }

}

Better quality• Less searching• Compiler errors

Ward Cunningham:

”You know you are working on clean code when each

routine you read turns out to be pretty much what you

expected.”

Whence Spring framework?

EJB 2.0… really sucked

… one feature: Transactions!

Java design in 2003… really sucked

… Singleton craze

… needed dependency control

… needed more magic

What’s relevant today?

EJB 2.0… um… no!

Transactions… it’s really not that hard!

… let me show you

public interface TransactionManager {

Transaction beginTransaction();

}

public interface Transaction extends Closeable {

void setCommit();

void close();}

@Testpublic void rollbackTransaction() throws Exception { doThrow(new RuntimeException()).when(targetObject).doIt();

try {

transactional(targetObject).doIt();

fail("Should throw exception"); } catch (RuntimeException e) { // expected }

verify(tx, never()).setCommit(); verify(tx).close();}

protected<T> T transactional(final T targetObject) { return Proxy.newProxyInstance(getClass().getClassLoader(), …, new InvocationHandler() { @Override public Object invoke(…, Method method, Object[] args) { Transaction transaction = txMgr.beginTransaction(); try {

method.invoke(targetObject, args); transaction.setCommit(); } finally { transaction.close(); } return null; } });}

Since Java 1.4!

void inTx(ExampleInterface targetObject) { try (Transaction tx = txMgr.beginTransaction()) { targetObject.doIt(); // if doIt() throws, we never get here // – then close() rolls back tx.setCommit(); }}

Java 1.7

Dependency management… Going waaaay over board

Person-Controller

Person-Controller-

Impl

Person-Service

Person-ServiceImpl

Person-Repository

Person-Repository

Impl

PersonDao

PersonDaoImpl

Session-Factory

Customer

Invoice

Order

Product

How many real configured things

do we have?

<?xml version="1.0" encoding="UTF-8"?><beans default-autowire="constructor">

<bean class="no.steria.spring.ApplicationServiceImpl" />

<bean class="no.steria.spring.IncrementService" />

<bean class="no.steria.spring.ReportService" />

<bean class="no.steria.winterapp.provided.JdbcEntryDao" />

<bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean></beans>

• DataSource• (Other resources)

• Hibernate SessionFactory• Web Services (URLs)

Varying for tests

public class PersonServlet extends HttpServlet {

private PersonDao personDao;

public void setPersonDao(PersonDao personDao) { this.personDao = personDao; }

@Override public void init() throws ServletException { setPersonDao(new HibernatePersonDao("jdbc/personDs")); }}

For test

New? Wut?!?!

For re

alz

public class HibernatePersonDao implements PersonDao {

public HibernatePersonDao(String jndiDataSource) { Configuration cfg = new Configuration(); cfg.setProperty(Environment.DATASOURCE, jndiDataSource); …; cfg.addAnnotatedClass(Person.class); this.sessionFactory = cfg.buildSessionFactory(); }

Hmmm…

Hmmm…

public class PersonServlet extends HttpServlet {

private PersonDao personDao;

public void setPersonDao(PersonDao personDao) { this.personDao = personDao; }

@Override public void init() throws ServletException { setPersonDao(HibernatePersonDao.getInstance()); }}

Singleton FTW!

Jason Gormanhttp://codemanship.co.uk/parlezuml/blog/?postid=1097

Announcing A Powerful New Framework:

Programming Language is a powerful new framework that enables developers to quickly and easily handle Dependency Injection, Inversion of Control, Model-View-Controller and many other

common design problems.

Intermezzo

Which one is right?

Messy picture

Well-architected picture

com.app.person

OR

com.app.controller

Now… about dependency injection

Don’t inject hard stuff

Session-Factory

PersonController

ServiceRepository

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); }

public class PersonServiceImpl implements … { private PersonRepository personRepo;

public PersonServiceImpl(SessionFactory sf) { this.personRepo = new PersonRepositoryImpl(sf); }

Hard stuff

Hard stuff

public class PersonController { private PersonService personService;

@Autowired public PersonController(SessionFactory sf) { this.personService = new PersonServiceImpl(sf); } public PersonControllerImpl(PersonService ps) { this.personService = ps; }

For Spring

For mocking

SPRING!

Session-Factory

PersonController

ServiceRepository

InvoiceController

FooServiceImpl

ReportsController

FooController

ServiceRepository

Collapse service chains

SPRING!

Session-Factory

PersonController

ServiceRepository

InvoiceController

Repository

FooServiceImpl

ReportsController

FooController

Going cold turkey!

Session-Factory

PersonServlet

Locator(singleton O_O)

”Injected” by servlet

public class PersonController extends HttpServlet { private PersonService personService; public PersonController() { } public PersonController(PersonService personService) { this.personService = personService; } @Override public void init() throws ServletException { SessionFactory sf = HibernateLookup.getInstance(getServletContext()); this.personService = new PersonServiceImpl(sf); }

For mocking

Look, ma! No Spring!

Service Locator

Session-Factory

PersonController

ServiceRepository

InvoiceController

Repository

FooServiceImpl

ReportsController

FooController

<<locator injection>>

<<locator injection>>

<<locator injection>>

<<locator in

jection>>

What Spring taught me

Be aware of dependencies!

Avoid differences between test and prod

Stay the heck away from frameworks!

Goal: «Pretty much what you expected»

Takk for [email protected]

http://johannesbrodwall.com

http://sterkblanding.no

http://twitter.com/jhannes