C++ 读写器和派生类的解耦持久性
我正在重构一堆旧代码。我的主要目标是将行为与数据库分离。当前的实现直接访问数据库,这使得测试和执行诸如实现缓存层等操作变得困难。。。到目前为止,我一直在使用依赖项倒置和读写器的组合,并取得了巨大成功,也就是说,直到我找到了一些更复杂的类型 我有一个抽象的基本用户类,它封装了所有用户类型所共有的信息。从基类继承是基类用户类型的许多专门化,每个专门化封装了特定于该类型的信息 如果我有一个指向基类的指针或引用,并且我需要将该用户持久化到数据库,那么我如何知道要使用哪个编写器?如果将writer用于基类,则特定于派生类的信息将丢失。在基类上放置一个抽象的getUserType()方法,然后每个派生类都必须实现该方法,这看起来有点像黑客。这可能是双重分派的情况,但实现细节对我来说有点模糊C++ 读写器和派生类的解耦持久性,c++,design-patterns,C++,Design Patterns,我正在重构一堆旧代码。我的主要目标是将行为与数据库分离。当前的实现直接访问数据库,这使得测试和执行诸如实现缓存层等操作变得困难。。。到目前为止,我一直在使用依赖项倒置和读写器的组合,并取得了巨大成功,也就是说,直到我找到了一些更复杂的类型 我有一个抽象的基本用户类,它封装了所有用户类型所共有的信息。从基类继承是基类用户类型的许多专门化,每个专门化封装了特定于该类型的信息 如果我有一个指向基类的指针或引用,并且我需要将该用户持久化到数据库,那么我如何知道要使用哪个编写器?如果将writer用于基类
class User
{
public:
std::string
name() const
{
return m_name;
}
void
name(const std::string& name)
{
m_name = name;
}
private:
std::string m_name;
}
class EmailUser : User
{
public:
std::list<std::string>
emails() const
{
return m_emails;
}
void
emails(const std::string<std::string>& emails)
{
m_emails = emails;
}
private:
std::set<std::string> m_emails;
}
class UserWriter
{
public:
virtual void
write(User& user) = 0;
}
class DBUserWriter : UserWriter
{
public:
void
write(User& user)
{
SQLExecute("SOME SQL UPDATE STMT %s", user.name());
}
}
class DBEmailUserWriter : UserWriter
{
public:
void
write(User& user)
{
m_baseUserWriter.write(user);
SQLExecute("SOME SQL UPDATE STMT %s", user.email.front());
}
private:
DBUserWriter m_baseUserWriter;
}
类用户
{
公众:
字符串
name()常量
{
返回m_名称;
}
无效的
名称(常量标准::字符串和名称)
{
m_name=名称;
}
私人:
std::字符串m_名称;
}
类EmailUser:用户
{
公众:
标准::列表
电子邮件()常量
{
返回m_电子邮件;
}
无效的
电子邮件(const std::string和电子邮件)
{
m_电子邮件=电子邮件;
}
私人:
std::设置m_电子邮件;
}
类用户编写器
{
公众:
虚空
写入(用户和用户)=0;
}
类DBUserWriter:UserWriter
{
公众:
无效的
写入(用户和用户)
{
SQLExecute(“某些SQL更新STMT%s”,user.name());
}
}
类DBEmailUserWriter:UserWriter
{
公众:
无效的
写入(用户和用户)
{
m_baseUserWriter.write(用户);
SQLExecute(“某些SQL更新STMT%s”,user.email.front());
}
私人:
DBUserWriter m_baseUserWriter;
}
以下是使用wikipedia页面中指定的双重分派实现的示例:
#include <iostream>
using namespace std;
class Writer;
class User
{
public:
std::string name() const { return m_name; }
void name(const std::string& name) { m_name = name; }
virtual void accept(Writer & writer) const;
private:
std::string m_name;
};
class EmailUser : public User
{
public:
std::string email() const { return m_email; }
void email(const std::string& email) { m_email = email; }
virtual void accept(Writer & writer) const;
private:
std::string m_email;
};
class Writer
{
public:
void process(const User& user) { user.accept(*this); }
virtual void write(const User& user) { cout << user.name() << endl; }
virtual void write(const EmailUser& user) { cout << user.email() << endl; }
};
class SubWriter : public Writer
{
public:
void process(const User& user) { user.accept(*this); }
void write(const User& user) { cout << "[" << user.name() << endl; }
void write(const EmailUser& user) { cout << "[" << user.email() << endl; }
};
void User::accept(Writer & writer) const { writer.write(*this); }
void EmailUser::accept(Writer & writer) const { writer.write(*this); }
int main()
{
User u;
EmailUser eu;
Writer w;
SubWriter s;
u.name("Hugo Peixoto");
eu.email("hugo.peixoto@gmail.com");
w.process(u);
w.process(eu);
s.process(u);
s.process(eu);
return 0;
}
#包括
使用名称空间std;
班主任;
类用户
{
公众:
std::string name()常量{return m_name;}
void name(const std::string&name){m_name=name;}
虚拟无效接受(写入方和写入方)常量;
私人:
std::字符串m_名称;
};
类EmailUser:公共用户
{
公众:
std::string email()常量{return m_email;}
无效电子邮件(const std::string&email){m_email=email;}
虚拟无效接受(写入方和写入方)常量;
私人:
std::字符串m_电子邮件;
};
班主任
{
公众:
无效进程(constuser&User){User.accept(*this);}
virtualvoidwrite(constuser&User){cout下面是一个使用wikipedia页面中指定的双分派实现的示例:
#include <iostream>
using namespace std;
class Writer;
class User
{
public:
std::string name() const { return m_name; }
void name(const std::string& name) { m_name = name; }
virtual void accept(Writer & writer) const;
private:
std::string m_name;
};
class EmailUser : public User
{
public:
std::string email() const { return m_email; }
void email(const std::string& email) { m_email = email; }
virtual void accept(Writer & writer) const;
private:
std::string m_email;
};
class Writer
{
public:
void process(const User& user) { user.accept(*this); }
virtual void write(const User& user) { cout << user.name() << endl; }
virtual void write(const EmailUser& user) { cout << user.email() << endl; }
};
class SubWriter : public Writer
{
public:
void process(const User& user) { user.accept(*this); }
void write(const User& user) { cout << "[" << user.name() << endl; }
void write(const EmailUser& user) { cout << "[" << user.email() << endl; }
};
void User::accept(Writer & writer) const { writer.write(*this); }
void EmailUser::accept(Writer & writer) const { writer.write(*this); }
int main()
{
User u;
EmailUser eu;
Writer w;
SubWriter s;
u.name("Hugo Peixoto");
eu.email("hugo.peixoto@gmail.com");
w.process(u);
w.process(eu);
s.process(u);
s.process(eu);
return 0;
}
#包括
使用名称空间std;
班主任;
类用户
{
公众:
std::string name()常量{return m_name;}
void name(const std::string&name){m_name=name;}
虚拟无效接受(写入方和写入方)常量;
私人:
std::字符串m_名称;
};
类EmailUser:公共用户
{
公众:
std::string email()常量{return m_email;}
无效电子邮件(const std::string&email){m_email=email;}
虚拟无效接受(写入方和写入方)常量;
私人:
std::字符串m_电子邮件;
};
班主任
{
公众:
无效进程(constuser&User){User.accept(*this);}
虚拟无效写入(常量用户和用户){因此,我可以看到您的解决方案的唯一缺点是,它要求我对每个用户类型使用相同的编写器,这使得很难混合和匹配缓存机制或数据存储。您可以有多个编写器。我更新了代码,检查这是否是您要找的。因此,我可以看到您的解决方案的唯一缺点是请允许我对每种用户类型使用相同的编写器,这样很难混合和匹配缓存机制或数据存储。您可以有多个编写器。我已更新了代码,请检查您是否需要这些编写器。