不同的数据处理类,如何定义统一的调用接口?有好的设计模式吗?

数据有数据库和文件两种存储方式。用数据库类和文件类分别负责去读取。
但数据库需要传入数据的ID,而文件需要传入文件的路径。它们调用的参数不同。
应该如何设计一个统一的调用接口?有什么好的设计模式吗?

目前我能想到的方法是,传入参数的地址指针,或者传入参数的基类,类内部去将这个指针转换为自己需要的参数类型。

继承和多态不仅规定了函数的名称、参数、返回类型,还规定了类的继承关系。耦合性太强,
在没有反射的c++中使用这些就是在找罪受,我认为在现代c++中(有了std::bind和std::function之后)很多设计模式没有存在的必要。
用class封装是根本的,我建议在有了std::bind和std::function之后,只要基于对象的设计就足以,在大多数情况下绝对不要使用继承, 顶多在单纯为了功能的继承时使用继承就可以了。

说回你的问题,
我们首先一拳到肉,直接解决问题本身:

//定义数据读取完毕后的回调
typedef std::function<void(const void*, unsigned int)> DataCallback;
//定义读取函数,只需传入回调地址获取数据
typedef std::function<int(DataCallback)> DataReader;
//从数据库读
class ReadFromDatabase
{
public:
	int read(int id ,DataCallback cb)
	{
		const void* data;
		unsigned int dataLengh;
		//... 
		//...
		//根据id 读取数据至data和dataLengh后回调出去
		if (cb)
		{
			cb(data , dataLengh);
		}
		return 0;
	}
};
//从文件读
class ReadFromFile
{
public:
	int read(const std::string& path,DataCallback cb)
	{
		const void* data;
		unsigned int dataLengh;
		//... 
		//...
		//根据path 读取数据至data和dataLengh后回调出去
		if (cb)
		{
			cb(data, dataLengh);
		}
		return 0;
	}
};

好了,现在已经有了问题的解决者,关键就在怎么调用了。
你的问题中,有一点不可避免,那就是你总有一个时刻需要知道从哪里读取数据并决定使用id还是路径作为参数。
如果这个时刻在你抽象的业务逻辑中,那么统一的接口是毫无意义的。因为你的逻辑本身就已经if else了,何必再去统一呢?
换句话说,“判断从哪读”的这个逻辑不应该被抽象。你抽象出来的业务逻辑应该只管“读”即可。
也就是你的业务开始前就应该需要知道“从哪读,哪个id或哪个路径”。这种业务才需要被抽象,才需要一个统一接口。

上面的例子就定义了一个统一的接口DataReader,那么只要在业务开始前决定一个DataReader使用就可以了。

class Reader
{
public:
	static DataReader fromDatabase(int id)
	{
		return std::bind(&ReadFromDatabase::read, 
			std::make_shared<ReadFromDatabase>(), 
			id,
			std::placeholders::_1);
	}
	static DataReader fromFile(const std::string& path)
	{
		return std::bind(&ReadFromFile::read,
			std::make_shared<ReadFromFile>(),
			path,
			std::placeholders::_1);
	}
};
class Business
{
public:
	Business(const DataReader& fromWhere)
		: reader_(fromWhere)
	{}
	void run()
	{
		//...
		//...
		if (reader_)
		{
			reader_(std::bind(&Business::dataReadDone, this, std::placeholders::_1, std::placeholders::_2));
		}
		//...
		//...
	}
private:
	void dataReadDone(const void* data, unsigned int size)
	{
		//...
	}
private:
	DataReader reader_;
	//...
	//...
};

业务:

Business b(Reader::fromDatabase(data_id));
// Business b(Reader::fromFile(path));
b.run();

是不是比一拳拳总打在棉花上的大多数设计模式看着舒服

其实你可以试下函数式的编程,传递的参数不变,但是根据参数类型的不同,将不同的数据处理函数传递过去,这样的话,可以实现不同的参数调用同样的接口,然后去执行不同的业务方法。

你可以参照下下面这个博文:

https://blog.csdn.net/richenyunqi/article/details/89530589

设置不是必须就可以啊

工厂模式、适配器模式了解一下,应该可以解决你的问题

定义一个枚举类型enum和一个共用体union,枚举用来说明共用体的参数是读写数据库的参数还是读写文件的参数,共用体中写数据库和文件读写所需的参数,不考虑空间占用的话,用结构体代替共用体也行,希望对你有帮助

文件那个可以调度传到数据库吗。这样也统一点