-
//Domain object pojo impl that should not be visible to other layers of app.
//hence declared as package protected.
package org.xwt.domain.general
class AddressImpl implements Address {
private String street1;
private String state;
AddressImpl(String street1, String state){
this.street1 = street1;
this.state = state;
}
public String getStreet1() {
return street1;
}
public String getState() {
return state;
}
}
//Here is the public interface, which defines the contract.
package org.xwt.domain.general
public interface Address {
public String getStreet1();
public String getState();
//other methods
//Interface provides a factory to create the pojos of different types potentially.
public static class Factory {
private Factory(){}
//provide static methods for constructors
public static Address getAddress(String street, String state) {
return new AddressImpl(street, state);
}
public static Address getUSAddress(String street, String state) {
return new USAddressImpl(street, state);
}
}
}
//I don't need a central DomainObjectFactory which will become cluttered with alot of static methods.
usage:
package org.xwt.app.ui
import org.xwt.domain.general;
public class MyController {
public void execute(HttpServletRequest request){
Address address = Address.Factory.getAddress(request.getParameter("street"),
request.getParameter("state"));
}
}
-
Have you tried Ruby? I hear it solves everyone's problems!
-
Dependency Injection accomplishes this as well. Have you looked at something like Spring's BeanFactory?
-
I know the spring 2.0 has a mechanism for Injecting domain object POJOs with other POJOs. But how do we use spring to hide concrete domain pojo impls from other classes. Here are the two ways I could think of via spring DI.
DI option1:Doing DI for domain objects would mean I would have to define that many POJOs in the spring context xml file. Then for all my other beans that need Domain objects would need to have corresponding setters. This could cause issues in maintenance, especially if I have a lot of domain objects.
DI option2:Configure a domain object factory for instantiating domain pojos. This I wanted to avoid due to maintenance and readability issues for the factory.
Instead of a centralized factory I was thinking of distributing the functionality to each respective interface.
-
You should really make sure you read and understand the GoF AbstractFactory pattern. On a side note, having a separate static method to get US addresses is a really bad idea that defeats the purpose of having a factory. Your code should be agnostic to the type of address it uses. That's the whole point of having an interface. The easiest way to achieve this is using a push model instead of a pull model a.k.a dependency injection. Spring is not required to use dependency injection.
-
you don't need a factory pattern in this situation at all.
You all may flame me...but i use a Manager ontop of DAOs, and the Manager(still in domain layer) is used by Services(business layer)
The Manager creates Domain objects from parameters and passes it to the lower layers.
I always use a Delegate that looks up "services" via Spring ApplicationContext, the delegate is the only class the Action Classes(struts) which would be in the presentation layer uses,etc..
of course the delegate could simply be a Spring Bean as well. But i use it as a "ServiceLocator"
//Address could even be a hibnerate object,etc..
package org.xwt.Address
public class Address {
private String street1;
private String state;
Address(String street1, String state){
this.street1 = street1;
this.state = state;
}
public String getStreet1() {
return street1;
}
public String getState() {
return state;
}
}
public AddressDAOImpl
implements AddressDAO{
public void save(Address address )
//save
}
public AddressManagerImpl
implements AddressManager
private AddressDAO addressDAO = null;
public Address saveAddress(String street,String state){
Address address = new Addresss();
address.setState(state);
..
addressDAO.save(address);
}
public class SomeService(){
private AddressManager addressManager = null;
public void someUseCase(){
...
addressManager.saveAddres(....)
}
public class MyDelegate()
private ApplicationContext context = null;
public void saveUserAddress(String state,String city,String userId,etc..){
SomeService someService = (SomeService)context.getBean("someService");
someService.someUseCase(...)
....
}
-
a manager to each DAO(only crude methods).
-
Remove the function getUSAddress
Modify the function getAddress as follows
public static Address getAddress(String street, String state) {
String className=determineClassName(street, state);
Address a=(Address)Class.forName(className).newInstance();
return a;
}
determineClass(String street, String state)
{
//Determine class from property file
//Downstreet.NY=USAddressImpl
}
}
-
Creating interfaces for POJO is bad solution anyway, although a lot of people do this.
-
Creating interfaces for POJO is bad solution anyway, although a lot of people do this.
I tend to agree. The whole idea of POJO is that they are *plain* objects. Once you start figuring out interfaces and implementations for your pojo it
*may be* the first sign of overcomplication of the design
*or* misuse of terminology of POJO.
IMHO, once POJO gets some complex or framework specific implementation it stops being POJO.
This is all subjective and a matter of interpretation of course - I merely expressed my opinion :)
-
You're designing abstraction for abstraction's sake. How often do you expect your Address implementation to change? The answer is probably never. Use a POJO, ditch the interface, and if the implementation ever changes (generally this is HIGHLY unlikely) then make the code change. You'll have spent less time in total than you did conceiving of and implementing the abstraction.
My 2 cents.