我有一个类似于下面的继承层次结构,我想编写我的DAL来保存这些对象,但我不确定构造它的最佳方法吗?
虽然所有类都继承自Pet,但每个方法都需要调用不同的存储过程并添加不同的sql参数。但是会有一些共同的参数。
一些想法:
(1)具有重载保存方法的PetDal,它接收每个派生类型。
(2)PetDal具有单独的SaveLabrador,SaveTabby方法。
(3)Base PetDal加上继承的LabradorDal,TabbyDal类,每个类型有一个共同的接口。例如void Save(宠物宠物)需要在每种方法中将宠物施放到派生类型(策略方法)。
(4)其他方式。
答案 0 :(得分:0)
您是否考虑过使用像strategy pattern这样的模式?它可能符合您的需求,因为您可以为不同的实现设置不同的策略,同时仍然使用抽象类中的属性/方法?
答案 1 :(得分:0)
(1)和(2)真的是一样的,只是语法上的不同。 (4)的一个问题是,如果你想处理不同的持久类型(平面文件,数据库等),那么你必须为每个排列设置一个类(AlsationToFileDAL,AlsationToSybaseDAL等)。
您可以使用(1)/(2)进行双重调度,例如:
// pets.h
#include <string>
#include <iostream>
class Alsation;
class Persian;
class PetDAL
{
public:
virtual ~PetDAL () {}
virtual void save (const Alsation* alsation) = 0;
virtual void save (const Persian* persian) = 0;
};
class Pet
{
std::string name_;
public:
Pet (const std::string& name) : name_ (name)
{}
virtual ~Pet () {}
std::string getName () const
{
return name_;
}
virtual void save (PetDAL* dal) const = 0;
};
class Dog : public Pet
{
bool sleepWalks_;
public:
Dog (const std::string& name, bool sleepWalks) : Pet (name), sleepWalks_ (sleepWalks)
{}
bool getSleepWalks () const {return sleepWalks_;}
};
class Alsation : public Dog
{
public:
Alsation (const std::string& name, bool sleepWalks) : Dog (name, sleepWalks)
{}
virtual void save (PetDAL* dal) const
{
dal->save (this);
}
};
class Cat : public Pet
{
int purrsPerMinute_;
public:
Cat (const std::string& name, int purrsPerMinute) : Pet (name), purrsPerMinute_ (purrsPerMinute)
{}
int getPurrsPerMinute () const {return purrsPerMinute_;}
};
class Persian : public Cat
{
public:
Persian (const std::string& name, int purrsPerMinute) : Cat (name, purrsPerMinute)
{}
virtual void save (PetDAL* dal) const
{
dal->save (this);
}
};
class PetDALCoutImpl : public PetDAL
{
public:
virtual void save (const Alsation* alsation)
{
std::cout << "Saving alsation " << std::endl
<< "\tname=" << alsation->getName () << std::endl
<< "\tsleepwalks=" << alsation->getSleepWalks () << std::endl;
}
virtual void save (const Persian* persian)
{
std::cout << "Saving persian " << std::endl
<< "\tname=" << persian->getName () << std::endl
<< "\tpurrsPerMinute=" << persian->getPurrsPerMinute () << std::endl;
}
};
int test (int argc, char* argv[])
{
Dog* dog = new Alsation ("fido", true);
Cat* cat = new Persian ("dave", 10);
PetDAL* petDAL = new PetDALCoutImpl ();
dog->save (petDAL);
cat->save (petDAL);
delete cat;
delete dog;
return 0;
};
即。 Pet基类知道它的子类可以保存到DAL,但它不依赖于DAL实现。