Avoiding the DRY Principle with beans
dhinojosa Jul 11, 2006 1:21 AMQuestion, I find myself doing something wrong with seam beans....and that is copying and pasting ad nauseum and violating the DRY Priniciple (Don't Repeat Yourself). Here is a prime example
package com.evolutionnext.session; import com.evolutionnext.data.Employee; import java.io.Serializable; import javax.ejb.Stateful; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import org.hibernate.validator.Valid; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; @Stateful @Scope(value=ScopeType.SESSION) @Name(value="employeeBean") public class EmployeeBean implements Serializable, EmployeeLocal { @PersistenceContext(unitName="hrsystem", type=PersistenceContextType.EXTENDED) private EntityManager entityManager; @In @Valid private Employee employee; /** Creates a new instance of EmployeeBean */ public EmployeeBean() { } public void setEmployee(Employee employee) { this.employee = employee; } @In @Valid public Employee getEmployee() { return employee; } public String update() { entityManager.merge(employee); return "Success"; } public String create() { entityManager.persist(employee); return "Success"; } public String delete() { entityManager.remove(employee); return "Success"; } }
All is well with this code...now what happens if I want the same functionality for uh...department, well I would need to copy and paste this code. This would violate the dry principal and make my app fragile in the process.
One solution I thought would be to create a superclass and refactor my create, update, and delete methods. This is almost an elegant solution but still has some copy/pasting problems. Here is the code...
package com.evolutionnext.session; import java.io.Serializable; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; public abstract class PersistentBean implements Serializable, PersistentLocal { @PersistenceContext(unitName="hrsystem", type=PersistenceContextType.EXTENDED) private EntityManager entityManager; private Object object; public abstract void setObject(Object object); public abstract Object getObject(); public String update() { entityManager.merge(object); return "Success"; } public String create() { entityManager.persist(object); return "Success"; } public String delete() { entityManager.remove(object); return "Success"; } }
My EmployeeBean would like this now:
package com.evolutionnext.session; import javax.ejb.Stateful; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; /** * * @author Administrator */ @Stateful @Scope(value=ScopeType.SESSION) @Name(value="employeeBean") public class EmployeeBean extends PersistentBean { /** Creates a new instance of EmployeeBean */ public EmployeeBean() { } private Object object; public void setObject(Object object) { this.object = object; } @In(value="employee") @Out(value="employee") public Object getObject() { return object; } }
I am not even sure if this type of subclassing works in Seam. Is this what I have to look to as far as abstraction. Let me know. ;)