class DistanceBase
{
public:
virtual ~DistanceBase() {}
virtual double distance(const RD_Vector&) = 0;
};
class L1Distance : public DistanceBase
{
virtual double distance(const RD_Vector& v)
{
double sum=0.0;
for (int i=1;i<=v.nelems();++i) sum+=fabs(v);
return sum;
}
};
class L2Distance : public DistanceBase
{
virtual double distance(const RD_Vector& v)
{ return sqrt(dot(v,v)); }
};
Client:
class NearestNeighbour
{
private:
DistanceBase* _d;
public:
NearestNeighbour(DistanceBase& d) : _d(&d) {}
int nearest(const RD_Array<RD_Vector>& data,
const RD_Vector& v);
// Uses _d->distance(dv)
};
We can change the functionality without changing the implementation:
L1Distance distance1; L2Distance distance2; NearestNeighbour nearest1(distance1); // Uses L1 metric NearestNeighbour nearest2(distance2); // Uses L2 metric