Re: Constructor Conundrum



Hi Lash,

I suggest to use a factory method:

public class ConcreteProblem extends AbstractProblem {
//ConcreteSolver _cs = new ConcreteSolver(); // obsolent, see
factory-meth.

public ConcreteProblem(ConcreteSolver _cs) { // perhabs change to
private
super(_cs);
_cs.setParam(/* ... */);
}

public static ConcreteProblem getInstance () {
ConcreteSolver _cs = new ConcreteSolver();
return new ConcreteProblem (_cs);
}
}

So you have encapsulated the constructor and seperated the creation of
ConcreteSolver from the creation of ConcreteProblem.
Perhabs you better use superclasses instead of concretes, e.g.

public ConcreteProblem(AbstractSolver _cs)

instead of

public ConcreteProblem(ConcreteSolver _cs) {

or

AbstractSolver _cs = new ConcreteSolver();

instead of

ConcreteSolver _cs = new ConcreteSolver();

I hope my sugesstions were helpful to you.

Greetz, Peter


Lash Rambo wrote:
> Say I have two class hierarchies--Problem and Solver--which sketch like
> this:
>
> public abstract class AbstractProblem {
> private AbstractSolver _solver;
>
> // ...
> }
>
> public class ConcreteProblem extends AbstractProblem {
> // ...
> }
>
> public abstract class AbstractSolver {
> public void solve(/* ... */) {
> // ...
> }
>
> // ...
> }
>
> public class ConcreteSolver extends AbstractSolver {
> // lots of parameters not in AbstractSolver
>
> // ...
> }
>
> ConcreteProblem needs to create a ConcreteSolver and hand it over to
> AbstractProblem. The catch is: ConcreteSolver has several parameters
> (variables controlling ConcreteProblem's behavior) ConcreteProblem may
> want to change from their default values. Changing parameters is
> accomplished through accessors.
>
> How can I do this? I've tried...
>
> public abstract class AbstractProblem {
> private AbstractSolver _solver;
>
> public AbstractProblem(AbstractSolver solver) {
> _solver = solver;
> }
>
> // ...
> }
>
> public class ConcreteProblem extends AbstractProblem {
> ConcreteSolver _cs = new ConcreteSolver();
>
> public ConcreteProblem() {
> super(_cs);
> _cs.setParam(/* ... */);
> }
>
> // ...
> }
>
> ...but Java won't let me access _cs before AbstractProblem's constructor
> has been called.
>
> I'd prefer to keep AbstractProblem's _solver private, since I can't give
> subclasses access to it without giving everything else in the package
> access to it, which I don't want to do. (Although I guess I could put
> the Problem and Solver hierarchies into separate packages with nothing
> else in them to approximate subtype-but-not-package access.)
>
> I can't make all of ConcreteSolver's parameters settable via its
> constructor, because I may want to change some defaults without changing
> others, which I can't always do since Java lacks named parameters (as far
> as I know).
>
> Any ideas?

.