All entries for Friday 16 June 2006

June 16, 2006

Day 2 Session 5: What's new in Spring 2

  • extensible simplified configuration

util:map and util:list look especially helpful

  • AOP

aop:* tags, AspectJ pointcut language and @Aspect annotation support. Very easy to add AOP functionality

  • MVC updates + SWF
    convention over configuration in MAC, form tag library, Portlet MVC framework

  • Simplified TX
    tx:advice + aop:advisor or tx:annotation + @Transactional

  • Task Executor

– execute some arbitrary runnable, sync, asynch, Thread pooling etc.

  • Asynch JMS

MessageListenerContainer – wraps POJOs and binds to a MessageListener

  • Data Access
    JPA support – make it easy to switch betwen providers, fill in the gaps in the spec. @Repository tag automagically (AOP) does exception translation for you on DAOs. AbstractJPATest allows you to inject EntityManagerFactory, DataSource and TXManager into your tests

  • Multilanguage support

– groovy, jruby, bsh, etc


Day 2 Session 4: Spring usage patterns

Principles

  • SoC
  • Multi–tier applications + layered applications

Component

  • loosely coupled components allow for re–use throughout the enterprise (I think this is a dodgy assertion; code re-use strategies are unsuccessful more often than not )
  • Spring perspective: components are just POJOs – technology neutral and therefore more likely to survive technology shifts. Still requires careful thought to achive reuse though

Container patterns:

  • Container provides the technical concerns which have been separated out from the functional components
  • DI/IoC container used to be clearly separated from app. server, but the distinction is becoming more blurred as spring picks up TaskExecutor, ShadowingClassLoader etc.

Component Interface

  • Component clients only access interfaces, not implementations
  • In spring can use a standard java class's public methods; no need for anything heavier weight unless the domain model requires it

Component Home

  • Locator for obtaining configured components
  • Largely just disappeared in Spring; DI means that clients don't need to be aware of the BeanFactory

Virtual Instance

  • Stub instances for entities that exist within the system that aren't needed right now; pooling, passivation, etc.
  • Spring support for this is more flexible (not restricted to session beans, can be any expensive object), but rarely used;

Interception

  • Container adds code to components by intercepting requests
  • Spring AOP is much more powerful

Lifecycle callback

  • have to be able to tell a component to change it's logical identity when used, also to clean up resources on exit
  • Spring lifecyle is much simpler than EBJ2: Just have startup and shutdown events, because most of the complexity went away with virtual instances

Spring API abstractions

  • ExceptionTranslator – convert checked or unhelpful exceptions into sensible ones
  • Template – manage acquisition and release of resources before and after business code
  • Exporter – Adapter to API–required classes e.g. the JMXExporter converts an arbitrary bean into an MBean
  • Proxy – Adapter from the (remote) return object of an API call, proxies the object and facades away checked exceptions and so on. (Exporter and proxy are 2 sides of the same thing)


Day 2 Session 3: Unit testing with spring

– Testing == good. Making test run fast == good. Automated tests == good
– Dont' use the container in your unit test; that's an integration test. Unit tests should be almost instant and they should not require elaborate setup.
– Mocks are helpful but not a silver bullet.

– Some things can't be sensibly unit–tested: configuration; JDBC code; OR mapping, and (of course) how classes work together. Also need to think about how we test non–java artefacts like DB schemas, config / mapping files, JSPs / other views.

Some stuff isn't worth testing: Hibernate doesn't leak connections and there's no point having a test to prove it. isolate the code that doesn't need testing or can't be tested into DAOs or other similar service objects.

Out–of–container testing is vital – much faster, easier to debug, easier to run individual tests. Spring integration testing is a good alternative. (org.springframework.test, in spring–mock.jar)

Spring integration testing provides context loading / caching, DI, (n.b. AutoWireUtils in spring 2) data access and TX management

Neat tip for TDD: configure the eclipse template for a new method to throw UnsupportedOperationException


Day 2 Session 2: Patterns of SOA

[I switched to this session from the 'introduction to Spring 2 because Gregor gave such an engaging keynote]

SOA is a shift in the way that we think about assembing systems – thinking about coupling, asynchrony, conversations and document exchange. It's really about reducing the degree of control one system exerts on another.

– Exists at a level of abstraction above the code; your compiler can't tell you if you're violating SOA principles

– Looks conceptually simple, but the devil is in the details; object–>document mapping is as hard as ORM; declarative programming and document transformation is hard to maintain; event–based programming; and business process modelling is hard when you try to do a complete design (long–running–processes & conpensating transactions (since 2PC isn't really applicable)

– Graphical tools tend to be a thin veneer over a complex / unfamiliar programming paradigm
– Understanding technology – process is something like {syntax=>constructs(e.g. in java classes, objects, interfaces etc)=>principles(SoC, open–closed principle)=>patterns}
– patterns are expressed in the constructs of the language, to support the principles of the language
SOA patterns are different to OO patterns because the constructs &vocabulary of SOA are not those of OO

– request–reply pattern – starts out very simple, but gets a bit more complex fairly quickly (return–address and correlation–id required to locate endpoints and re–produce state if you have more than 1 producer / consumer) It's possible to use a pattern like this in reverse; i.e. if you don't have a correlation ID, then you can't have multiple provider; if you don't have a return address you can't have multiple consumers. When you introdroduce retries, it gets more complex again as you move into heuristics about how long to keep trying.

– dynamic discovery – broadcast request for service, providers respond, requestor chooses 'best' provider from response, requestor starts using provider. DHCP is a good example of this.

– Subscribe–notify – subscriber expresses an interest in receiving notifications, provider starts sending messages; subscriber does not reply, after some event the provider stops sending messages and notifies subscriber that it is done.

– sub–patterns for the end refresh e.g. automatic expiration (e.g. DHCP lease&renew), renewal request (e.g. magazine model). Generally try to avoid allowing the subscriber to control when the subscription ends because it doesn't cope with the subscriber going away

Orchestration: a facade co–ordinating the calling of multiple services (which may in turn orchestrate their own conversations)
Orchestration patterns: switches: XOR, OR, ;merges: synchronized, multiple, discriminator;
(not all orchestration environments support all orchestration patterns)

Patterns and standards interact; standards tell you how to express a pattern in code; patterns act as the requirements for the standard. There's a feedback cycle between patterns and standards; but it happens very slowly when you're dealing with cross–organisational standards.


SpringOne day 2 keynote

Gregor Hohpe – Where did all my beautiful code go?

– Why is it that, even with a fantastically rich toolset, and the best and brightest developers, we still get crappy stupid code being written? (Gregor provided some examples from the google codebase)

– Its all about having a good representation of the business domain

– understand your domain

– choose your models

– choose a language to represent the model

– map the model well to the language

– protect your model

– program for humans, not for machines
– models – UI flow, state/workflow models, class identifications and object associations.. Models don't have to be executable; shouldn't necessarily be a direct input to generating code; might just be a useful way of looking at the problem domain.

– declarative DSLs (XSLT, BPEL, etc) – can be very expressive, but they're almost impossible to debug and the tooling is generally not as good

– Don't allow cruft from APIs to bleed into the domain classes; facade away things like java.util.Calendar & associated horibbleness

– protecting your model – if you make your code accessible then people are more likely to understand it enough not to break it – program for people, not for machines.


Some thoughts on layering

One of the topics that's come up repeatedly at SpringOne so far is the notion that Separation of Concerns, and layering, is essential if your app is going to be 'well designed'. I'm not sure I agree.

I absolutely agree that SoC is important. You shouldn't have one class interacting with, say, the HTTP APIs and the Hibernate APIs, (nor even your Accounting API and your Authorisation API) unless your app is truly tiny. But I don't agree that, in order to do this, you need to have an inviolable set of layers (DAO, BO, Service, Web…) that each class needs to be pigeon–holed into. Just keep your classes small, well–encapsulated and consistent, and the SoC will take care of itself.

I suppose that if you're working on a truly huge project, with hundreds of developers and tens of thousands of classes, then maybe some kind of stronger layering is appropriate. But suggesting that this implies it should be used on all projects is like saying that when I build a wall in my garden, I should do a wind–loading finite element analysis and an earthquake–proofing design. It's just never going to matter.

Our most complex projects (sitebuilder2, blogbuilder) have less than a thousand classes each, not including tests, and usually only 3 or 4 developers. And those are fairly complicated applications; IME they're fairly representative of the kind of apps that a lot of people are writing; many of our apps are much simpler than this. It doesn't seem like we should loose a lot of sleep trying to adopt an architecture that's suited to super–massive apps.


Most recent entries

Loading…

Search this blog

on twitter...


    Tags

    Not signed in
    Sign in

    Powered by BlogBuilder
    © MMXX