1 / 60

Winter is coming (Johannes vs Johanes

Winter is coming (Johannes vs Johanes. Nets DevDay 2012 Johannes Brodwall , Principal Architect Steria Norway @ jhannes. Why dependency detox ?. <? xml version = "1.0" encoding = "UTF-8" ?> < beans default-autowire = " constructor " >

Télécharger la présentation

Winter is coming (Johannes vs Johanes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Winter is coming(Johannes vsJohanes Nets DevDay 2012 Johannes Brodwall, Principal Architect Steria Norway @jhannes

  2. Whydependencydetox?

  3. <?xmlversion="1.0" encoding="UTF-8"?> <beansdefault-autowire="constructor"> <beanclass="no.steria.spring.ApplicationServiceImpl" /> <beanclass="no.steria.spring.IncrementService" /> <beanclass="no.steria.spring.ReportService" /> <beanclass="no.steria.winterapp.provided.JdbcEntryDao" /> <beanclass="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean> </beans>

  4. publicstaticvoid main(String[] args){ ApplicationContextcontext = newClassPathXmlApplicationContext("..."); ApplicationServiceapplicationService=context.getBean(ApplicationService.class); applicationService.incrementAndReport(new Date()); }

  5. In what <import> is that bean defined? Who created that object? Is that setter still in use? The “Service” here does nothing! Where is the business logic?! Are we sure @Transactional is picked up? How does @Transaction work?!

  6. Less magic

  7. publicstaticvoid main(String[] args) { ApplicationServiceapplicationService = newApplicationService(createDataSource()); applicationService.incrementAndReport(newDate()); }

  8. Explicitcoupling

  9. publicclassApplicationService { privateIncrementServiceincrementService; privateReportServicereportService; publicApplicationService(DataSourcedataSource) { this(newIncrementService(dataSource), newReportService(dataSource)); } publicApplicationService(IncrementServiceincrementSvc,ReportServicereportSvc) { this.incrementService = incrementService; this.reportService = reportService; } publicvoidincrementAndReport(Date date) { incrementService.increment(date); reportService.printReport(); } }

  10. publicclassIncrementService { privateEntryDaoentryDao; publicIncrementService(DataSourcedataSource) { this(newJdbcEntryDao(dataSource)); } publicIncrementService(EntryDaoentryDao) { this.entryDao = entryDao; } publicvoidincrement(Date date) { entryDao.insertEntry(newEntry(date)); } }

  11. Better quality Less searching Compiler errors

  12. ”You know you are working on clean code when each routine you read turns out to be pretty much what you expected.” Ward Cunningham:

  13. Whence Spring framework?

  14. EJB 2.0 … reallysucked … onefeature: Transactions!

  15. Java design in 2003 … reallysucked … Singleton craze … neededdependencycontrol … needed more magic

  16. What’s relevant today?

  17. EJB 2.0 … um… no!

  18. Transactions … it’sreally not that hard! … let me show you

  19. publicinterfaceTransactionManager { TransactionbeginTransaction(); } publicinterfaceTransactionextendsCloseable { voidsetCommit(); voidclose(); }

  20. @Test publicvoidrollbackTransaction() throws Exception { doThrow(newRuntimeException()).when(targetObject).doIt(); try { transactional(targetObject).doIt(); fail("Shouldthrowexception"); } catch (RuntimeException e) { // expected } verify(tx, never()).setCommit(); verify(tx).close(); }

  21. protected<T> T transactional(final T targetObject) { returnProxy.newProxyInstance(getClass().getClassLoader(), …, newInvocationHandler() { @Override public Object invoke(…, Method method, Object[] args) { Transactiontransaction = txMgr.beginTransaction(); try { method.invoke(targetObject, args); transaction.setCommit(); } finally { transaction.close(); } returnnull; } }); } Since Java 1.4!

  22. voidinTx(ExampleInterfacetargetObject) { try (Transactiontx = txMgr.beginTransaction()) { targetObject.doIt(); // if doIt() throws, we never get here // – then close() rolls back tx.setCommit(); } } Java 1.7

  23. Dependency management … Goingwaaaay over board

  24. Person-Controller Person-Service Person-Repository PersonDao Person-Controller-Impl Person-ServiceImpl Person-Repository Impl PersonDao Impl Session-Factory

  25. Customer Invoice Order Product

  26. How many real configured things do we have?

  27. <?xmlversion="1.0" encoding="UTF-8"?> <beansdefault-autowire="constructor"> <beanclass="no.steria.spring.ApplicationServiceImpl" /> <beanclass="no.steria.spring.IncrementService" /> <beanclass="no.steria.spring.ReportService" /> <beanclass="no.steria.winterapp.provided.JdbcEntryDao" /> <beanclass="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/primaryDs" /> </bean> </beans>

  28. DataSource (Other resources) Hibernate SessionFactory Web Services (URLs)

  29. Varying for tests

  30. For test publicclassPersonServletextendsHttpServlet { privatePersonDaopersonDao; publicvoidsetPersonDao(PersonDaopersonDao) { this.personDao = personDao; } @Override publicvoidinit() throwsServletException { setPersonDao(newHibernatePersonDao("jdbc/personDs")); } } New? Wut?!?! For realz

  31. Hmmm… publicclassHibernatePersonDaoimplementsPersonDao { publicHibernatePersonDao(StringjndiDataSource) { Configurationcfg = newConfiguration(); cfg.setProperty(Environment.DATASOURCE, jndiDataSource); …; cfg.addAnnotatedClass(Person.class); this.sessionFactory = cfg.buildSessionFactory(); } Hmmm…

  32. publicclassPersonServletextendsHttpServlet { privatePersonDaopersonDao; publicvoidsetPersonDao(PersonDaopersonDao) { this.personDao = personDao; } @Override publicvoidinit() throwsServletException { setPersonDao(HibernatePersonDao.getInstance()); } } Singleton FTW!

  33. 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. Jason Gorman http://codemanship.co.uk/parlezuml/blog/?postid=1097

  34. Intermezzo

  35. Whichone is right?

  36. Messy picture Well-architected picture

  37. com.app.person OR com.app.controller

  38. Now… aboutdependencyinjection

  39. Don’t inject hard stuff

  40. PersonController Service Repository Session-Factory

  41. Hard stuff publicclassPersonController { privatePersonServicepersonService; @Autowired publicPersonController(SessionFactorysf) { this.personService = newPersonServiceImpl(sf); } publicclassPersonServiceImplimplements … { privatePersonRepositorypersonRepo; publicPersonServiceImpl(SessionFactorysf) { this.personRepo = newPersonRepositoryImpl(sf); } Hard stuff

  42. For Spring publicclassPersonController { privatePersonServicepersonService; @Autowired publicPersonController(SessionFactorysf) { this.personService = newPersonServiceImpl(sf); } publicPersonControllerImpl(PersonServiceps) { this.personService = ps; } For mocking

  43. SPRING! PersonController Service Repository InvoiceController Service Repository Session-Factory ReportsController FooController FooServiceImpl

  44. Collapse service chains

  45. SPRING! PersonController Service Repository InvoiceController Repository Session-Factory ReportsController FooController FooServiceImpl

More Related