Play!> framework design pattern #3 : Avoid Anemic Domain Model
In my last post about data integrity, I noticed that with the MVC model of Play, you tend to put many logic in the controller, even a part of the domain model, thus creating an Anemic Domain Model as described by Martin Fowler.
And it’s what I made in my Codebaord Project to test Play! Framework. In my model, I have a class Domain
that is only a database wrapper (with only annotations), and a controller Domains
that has code that should be in the model (see old controller source with this wrong choice).
So, I started replace domain code in the domain classes.
Now the controller class is lighter :
public class Domains extends Admin { public static void list() { List<Domain> domains = Domain.find("order by position asc").fetch(); render(domains); } public static void create() { Domain domain = new Domain(); render("@edit", domain); } public static void edit(Long id) { Domain domain = Domain.findById(id); render(domain); } public static void setDefault(Long id) { Domain domain = Domain.findById(id); domain.setDefault(); Map summary = new HashMap(); summary.put(0, 1); summary.put(1, Messages.get("domain_as_default")); summary.put(2, id); renderJSON(summary); } public static void save(@Valid Domain domain) { if (Validation.hasErrors()) { params.flash(); // add http parameters to the flash scope validation.keep(); // keep the errors for the next request render("@edit", domain); } domain.save(); list(); } public static void delete(Long id) { Domain domain_to_delete = Domain.findById(id); Map summary = new HashMap(); try { domain_to_delete.delete(); summary.put(0, 1); summary.put(1, Messages.get("domain_deleted")); summary.put(2, domain_to_delete.id); } catch (UnsupportedOperationException e) { summary.put(0, 0); summary.put(1, Messages.get(e.getMessage())); summary.put(2, domain_to_delete.id); } renderJSON(summary); } public static void move(Long id) { String to = params.get("move_to"); Domain domain_to_move = Domain.findById(id); domain_to_move.move(to); Map summary = new HashMap(); summary.put(0, Messages.get("domain_moved")); summary.put(1, domain_to_move.id); summary.put(2, domain_to_move.position); renderJSON(summary); } }
and the model class is no more “empty” :
@Entity public class Domain extends Model { public String name; public long position; public boolean isPublic; public boolean isDefault; public String toString() { return name; } public Domain delete() { if (! isDefault) { super.delete(); } else { throw new UnsupportedOperationException("dont_delete_default"); } List<Domain> domains = Domain.find("position > ?", position).fetch(); for (Iterator iterator = domains.iterator(); iterator.hasNext(); ) { Domain domain = (Domain) iterator.next(); domain.position = domain.position - 1; domain.save(); } return this; } public Domain setDefault() { Domain defaultDomain = Domain.find("isDefault = ?", true).first(); if (defaultDomain != null) { defaultDomain.isDefault = false; defaultDomain.save(); } isDefault = true; save(); return this; } public void move(String to) { if (to.equals("highest")) { List<Domain> domains = Domain.find("position < ?", position).fetch(); for (Iterator iterator = domains.iterator(); iterator.hasNext();) { Domain domain = (Domain) iterator.next(); domain.position = domain.position +1; domain.save(); } position = 1; } else if (to.equals("higher")) { Domain domain_to_swap = Domain.find("position = ?", position - 1).first(); domain_to_swap.position = position; position = position - 1; domain_to_swap.save(); } else if (to.equals("lower")) { Domain domain_to_swap = Domain.find("position = ?", position + 1).first(); domain_to_swap.position = position; position = position + 1; domain_to_swap.save(); } else if (to.equals("lowest")) { List<Domain> domains = Domain.find("position > ?", position).fetch(); for (Iterator iterator = domains.iterator(); iterator.hasNext();) { Domain domain = (Domain) iterator.next(); domain.position = domain.position - 1; domain.save(); } position = Domain.count(); } save(); } }
About this entry
You’re currently reading “Play!> framework design pattern #3 : Avoid Anemic Domain Model,” an entry on Java Thoughts
- Published:
- January 20, 2013 / 11:28 pm
No comments yet
Jump to comment form | comment rss [?] | trackback uri [?]