关于一个格式转换软件的设计解决思路
关于一个格式转换软件的设计
问题:
我现在要做一个多种格式之间转换的软件。譬如我现在有两种格式A,B用户可以读入A转成B,或者读入B转成A.我设计了一个方式,大体上是读入一个格式,然后把数据放到一个中间量,然后用中间量存成另一种格式,但总觉得耦合度太大,希望谁能看看有没有更好的方法。
设这个中间数据类为Data;
对于格式:我有一个虚类Format,和两个子类AFormat, BFormat
然后我有个作为外界接口的Transform类
外界调用为
现在的问题是我每次增加一个格式,那么我不但需要继承一个Format类,还需要增加Transform的两个函数,请问有什么好的去耦合的方法吗?
------解决方案--------------------
应用模板类啊
将格式抽象化
写成抽象类……………………
------解决方案--------------------
这个不是模板能实现的,人家要转换数据格式,数据可能是一种文件,各种抽象都有可能。
建议你这么设计,能不能抽象出各种数据格式的共同之处,设计一种中间的数据格式,然后在各个Format的子类中提供中间格式到自己的转换。比如:
问题:
我现在要做一个多种格式之间转换的软件。譬如我现在有两种格式A,B用户可以读入A转成B,或者读入B转成A.我设计了一个方式,大体上是读入一个格式,然后把数据放到一个中间量,然后用中间量存成另一种格式,但总觉得耦合度太大,希望谁能看看有没有更好的方法。
设这个中间数据类为Data;
对于格式:我有一个虚类Format,和两个子类AFormat, BFormat
- C/C++ code
class Format { public: virtual Read(const string FileName, Data* aData) = 0; virtual Write(const string FileName, const Data* aData) = 0; } class AFormat : public Format { public: virtual Read(const string FileName, Data* aData); //负责A格式的读 virtual Write(const string FileName, const Data* aData);//负责A格式的写 } class BFormat ...
然后我有个作为外界接口的Transform类
- C/C++ code
class Transform { public: ReadA(const string FileName) { Format* aFormat = new AFormat(); aFormat->Read(FileName, m_Data); } ReadB(const string FileName)... WriteA(...); WriteB(...); private: Data* m_Data; }
外界调用为
- C/C++ code
Transform* aTransform = new Transform(); aTransform->ReadA(...); aTransform->WriteB(...);
现在的问题是我每次增加一个格式,那么我不但需要继承一个Format类,还需要增加Transform的两个函数,请问有什么好的去耦合的方法吗?
------解决方案--------------------
应用模板类啊
将格式抽象化
写成抽象类……………………
------解决方案--------------------
这个不是模板能实现的,人家要转换数据格式,数据可能是一种文件,各种抽象都有可能。
建议你这么设计,能不能抽象出各种数据格式的共同之处,设计一种中间的数据格式,然后在各个Format的子类中提供中间格式到自己的转换。比如:
- C/C++ code
class Format { public: virtual Read(const string FileName, Data* aData) = 0; virtual Write(const string FileName, const Data* aData) = 0; virtual transformToSelf(const string Filename)=0;//转成子类自己的格式 vitual transfromToMediate(const string Filename)=0;//转子类格式成中间格式 } class AFormat : public Format { public: virtual Read(const string FileName, Data* aData); //负责A格式的读 virtual Write(const string FileName, const Data* aData);//负责A格式的写 virtual transformToSelf(const string Filename)// 将中间格式的文件转换成A vitual transfromToMediate(const string Filename);//将A转成中间格式数据 } class BFormat ... //调用,把A转成B aTransform->transfromToMediate(filename); bTransform->transformToSelf(filename);
------解决方案--------------------
// 工厂模式
// 一般的实现
class Transform
{
public:
Format * GetFormat(string s)
{
if(s=="H264")
return new FormatH264();
else if(s=="MPEG4")
return new FormatMPEG4();
else if....
}
Transform * Read(string filename, string fmt)
{
format_src = GetFormat(fmt);
format_src ->Read(filename, m_data);
delete format_src;
return this;
}
void Write(string format, string fmt)
{
format_dst = GetFormat(fmt);
format_dst ->Write(filename, m_data);
delete format_dst;
}
};
//
//
Transform * t = new Transform();
t->Read("1.avi", "MPEG4")->Write("1.mp4", "H264");
// 如果无论如何都不想动 Transform 这个类
// 可以事先在这个类中添加一个 static map<string, GetFormatFunc> factory_functions;
// 用来保存格式字符串与格式创建函数之间的对应关系
// 相应的 每个 Format 要加入一个 static 函数如 GetInstance(){return new FormatXXX();}
// 并且在每个 Format 定义好之后,用函数也好,宏也好。将自身注册到 Transform 的 factory_functions 中去