I asked a similar question earlier today, but now I am told that the requirements have changed.
I have 3 classes - Product
, ProductOffering
(PO) and ProductOfferingLists
(POL). Product contains PO, and PO contains POL. All those classes extend an abstract class called CMS.
I want to attach PO to P, and POL to PO, but I am looking for a re-usable method, since the logic is identical, except for the class names.
Unfortunately, my tester class is requiring two methods, and the hierarchy classes are requiring a cast to fulfill the abstract CMS contract.
This is driving me nuts. How can I make this more reusable, so I don't have multiple methods and casting?
package puzzler;
import java.util.ArrayList;
import java.util.List;
public class Tester {
public static void main(String[] args) {
Product p = new Product();
PO pa = new PO();
POL po = new POL();
List<PO> lpa = new ArrayList<PO>();
List<POL> lpo = new ArrayList<POL>();
attachChildToParent(lpa, p);
attachChildToParent(lpo, pa);
}
static void attachChildToParent(List<PO> listChild, Product parent) {
for (PO po : listChild) {
parent.attach(po);
}
}
static void attachChildToParent(List<POL> listChild, PO parent) {
for (POL po : listChild) {
parent.attach(po);
}
}
}
The CMS Class:
package puzzler;
abstract class CMS {
abstract void attach(CMS childNode);
}
Product Class - the top of the hierarchy that owns PO:
package puzzler;
import java.util.List;
public class Product extends CMS {
List<PO> lpo;
public List<PO> getLpo() {
return lpo;
}
public void setLpo(List<PO> lpo) {
this.lpo = lpo;
}
@Override
void attach(CMS childNode) {
this.getLpo().add((PO)childNode);
}
}
Product Offering, owned by Product and in turn owns a Product Offering List
package puzzler;
import java.util.List;
public class PO extends CMS {
List<POL> lpol;
public List<POL> getLpo() {
return lpol;
}
public void setLpo(List<POL> lpol) {
this.lpol = lpol;
}
@Override
void attach(CMS childNode) {
this.getLpo().add((POL)childNode);
}
}
Product Offering List (POL) owned by PO
package puzzler;
public class POL extends CMS {
@Override
void attach(CMS childNode) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
(Java 7 syntax used, but easy to adapt for Java 6)
Define your CMS class as follows:
public abstract class CMS<C extends CMS<?>> {
public abstract void attach(C childNode);
}
Then your Product class can look like this:
public class Product extends CMS<PO> {
private List<PO> lpo = new ArrayList<>();
public List<PO> getLpo() {
return lpo;
}
public void setLpo(List<PO> lpo) {
this.lpo = lpo;
}
@Override
public void attach(PO childNode) {
getLpo().add(childNode);
}
}
Then your PO class can look like this:
public class PO extends CMS<POL> {
private List<POL> lpol = new ArrayList<>();
public List<POL> getLpo() {
return lpol;
}
public void setLpo(List<POL> lpol) {
this.lpol = lpol;
}
@Override
public void attach(POL childNode) {
getLpo().add(childNode);
}
}
Then your POL class can look like this:
public class POL extends CMS<CMS<?>> {
@Override
public void attach(CMS<?> child) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
And finally, your Tester class can look like this:
public class Tester {
public static void main(String[] args) {
Product p = new Product();
PO po = new PO();
List<PO> pos = new ArrayList<PO>();
List<POL> pols = new ArrayList<POL>();
attachChildToParent(pos, p);
attachChildToParent(pols, po);
}
private static <C extends CMS<?>> void attachChildToParent(List<C> childNodes, CMS<C> parent) {
for (C childNode : childNodes) {
parent.attach(childNode);
}
}
}
Only one method needed, no casts.