Daniel T. wrote:
In article
<936de0a9-1689-4d1b-a777-2262f6613...@p36g2000prp.googlegroups.com>,
"nvinh...@gmail.com" <nvinh...@gmail.com> wrote:
Hello everybody,
I have implemented a code like this, in one of my class who has a
private data member: std::String name_ ..., variables with _ mean
private data members:
void compute ( double x )
{
if ( name_ == "linearSoftening" )
{
fval_ = linearValue ( k1_, k2_, x );
fder_ = linearDerivative ( k1_, k2_, x );
}
else if ( name_ == "exponentialSoftening" )
{
fval_ = linearValue ( k1_, k2_, alpha_, x );
fder_ = linearDerivative ( k1_, k2_, alpha_, x );
I'm assuming the above is a typo and it should be:
fval_ = exponentialValue ( k1_, k2_, alpha_, x );
fder_ = exponentialDerivative ( k1_, k2_, alpha_, x );
}
...
}
So, everytime a new softening law, say powerSoftening, is to be added,
I have to do two things:
(1) Code the two functions powerValue (...) and powerDerivative(...)
(2) Add a else if in the above void compute (double x) method.
I think this design is not object-oriented. I am thinking of the
following design. A base class
class SofteningLaw{
double computeVal ( double x);
double computeDer ( double x);
};
class LinearSofteningLaw : public SofteningLaw
{
private:
double k1_;
double k2_;
public:
double computeVal ( double x){return k1_ + k2_ *x;}
double computeDer ( double x){return k2_;}
};
and other class for each softening law.
Then, in my class, I store a pointer to SofteningLaw as
class myClass{
private:
SofteningLaw* softening_;
double val_;
double der_;
public:
void compute ( double x ){
val_ = softening_-> computeVal (x);
der_ = softening_-> computeDer (x);
}
};
My question is there is better way to implement the same thing here?
Before jumping to the OO approach, lets talk about what you have above.
All other things equal, it is better (more idiomatic, and somewhat
better performance) to use an enum to represent the different softening
laws and then in the compute function use a switch statement to jump to
the right calculations.
Now on to the question you are really asking...
Whether or not the OO solution is better depends on a number of factors.
1) How would you plan to create the softening law object? If you end up
just moving the if... else chain (or switch statement) somewhere else to
new the correct softening law then you aren't gaining anything by using
the OO approach.
2) Can/should an object be able to change its softening law at runtime?
Both the system you have above and the OO approach allows this, but is
that ability really necessary?
3) Can/should objects outside the object in question be able to
determine which softening law a particular object is using? Maybe the
object is told which softening law to use at runtime by some outside
object, maybe not...
There are rarely simple answers to design problems, even experts (some
would say, especially experts) cannot enumerate all the factors that
have to be accounted for. As such, my questions above are only the
beginning, but their answers are necessary before a determination can be
made.
1. Make orthogonal classes representing softening policies
2. For dynamic case, make a bridge that unify them