I would like to solicit advice on everyone's thoughts on how best to combat the Anemic Domain Model anti-pattern when building out a system based on web services.
One of our goals is to build a set of core web services that expose the most basic services we reuse repeatedly in our organization, which is the creating of domain models. Right now we have a small library that we share and reuse but as we grow our team it would be much nicer to centralize these basic services. Over time our systems are going to change as some of the data may come from the cloud (Salesforce.com or AWS) so we're not just isolating basic DAO code in a web service but also application integration.
For example, our customer data comes from the accounting, CRM, and order processing systems. Configuration is a real pain because every app that ships needs to be bundled with the core library and configuration on each system. I would like to centralize the creation of models, ala, SOA, but retain a rich model higher up in the Service Layer / Facade.
If you think in general that this is a bad I'd be interested in hearing why!
My thought is to define a domain object Employee
that has an EmployeeService
injected. At runtime the EmployeeService
implementation is an EmployeeWebServiceClientImpl
that implements said interface. EmployeeWebServiceClientImpl
uses a web service proxy to the server.
On the server-side of the web service we have EmployeeWebService
invoking EmployeeDao
to query the database. Could just as easily be a class calling out to Salesforce.com to get data. We would share a library that contained the domain model and interface so you would deserialize the web service response directly into a class that contained the needed business logic.
Below is some example code in order from client to server:
//Example of client
public static void main(String[] args) {
try {
Employee employee = Employee.getEmployee("james");
if (employee.isEligibleForRaise()) {
System.out.println("Give that man a raise!");
}
} catch (RuntimeException e) {
System.out.println("Oh no!");
}
}
//Employee Domain Object
public class Employee {
private String name;
private String username;
private static EmployeeService service;
public static Employee getEmployee(String username) {
return service.getEmployee(username);
}
public static List<Employee> getAllEmployees() {
return service.getAllEmployees();
}
public boolean isEmployeeEligibleForRaise() {
//business logic here
return true;
}
//Getters & Setters
...
}
//EmployeeWebServiceClientImpl
public class EmployeeWebServiceClientImpl implements EmployeeService {
//A client web service proxy to our core basic services
BaseWebServiceProxy proxy;
@Override
public Employee getEmployee(String username) {
return proxy.getEmployee(username);
}
@Override
public List<Employee> getAllEmployees() {
return proxy.getAllEmployees();
}
}
//On the server-side we have EmployeeWebService
public class EmployeeWebService implements EmployeeService {
EmployeeDao employeeDao;
@Override
public List<Employee> getAllEmployees() {
return employeeDao.getAllEmployees();
}
@Override
public Employee getEmployee(String username) {
return employeeDao.getEmployee(username);
}
}
Is that making sense? Basically the plan is to keep core business logic in the Employee
domain object but isolate the data access logic in a web service.
Thoughts?