Here is a brief presentation on adopting agile practices based on an ignite-style talk I gave recently at a local meetup.
#2 Separate Presentation From Domain Entity
Many projects that you undertake might have a presentation component to it – it could be a browser based app, thick client on a desktop, or even a kiosk-type interface. Regardless of specific the presentation technology, you have to ensure that your domain or business logic is effectively decoupled from the user interface code. This is in fact the foundation of the Model View Controller design pattern. You can move business logic in the model layer, presentation logic in the view layer, and the glue code that orchestrates across user actions and domain entities into the controller layer. Often times this separation might not reveal itself in a clean way. In those cases it is important to refactor the code appropriately.
Here is an example – say you have a class named Organization which holds a collection of Units and a collection of Employees. For the sake of integration ease, the Organization class contains a toString() method that generates HTML markup code that formats an Organization object into a neat nested table structure. If you change the way the markup is generated or change rendering output format from HTML to PDF you will end up touching the Organization class. Not a good idea from a reuse standpoint. You want Organization to be about the business entity and nothing else. The fact that it was generated for a web application should be decoupled from the core domain object. You can refactor this class in a number of ways. One way to refactor would be to remove HTML code from the object’s toString() method and move it to a OrganizationFormatter class. This new class could be in a new package structure that is specific to a presentation. If you envision need to support multiple formats you can make OrganizationFormatter an interface and have multiple implementations – a HTMLFormatter, a PDFFormatter, and so on. Based on need a SimpleFactory can be used to return the appropriate formatter at runtime to generate the output. Regardless of the format, you can reuse the Organization class as-is.
Another case where this is needed is when your domain entities make assumptions about the user interface layer. This would require refactoring for enabling reuse as well – will elaborate on this in a future post.