接口设计问题

frland 2007-02-01 02:10:05
接口发布后就不能改变,那如何设计能满足将来参数扩展的需要?
...全文
2225 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
ouyh12345 2007-09-26
  • 打赏
  • 举报
回复
添加一个设置参数的接口,这样,在参数发生变化时,不需要修改接口
zyx040404 2007-09-26
  • 打赏
  • 举报
回复
经验
musezh2 2007-09-26
  • 打赏
  • 举报
回复
收藏
weiqurang 2007-09-25
  • 打赏
  • 举报
回复
.不修改现有接口,重新设计具有新参数的接口
libbyliugang 2007-06-23
  • 打赏
  • 举报
回复
有一种插件接口的形式或许比较适合你说的情况:
比如接口:
class IObject
{
public:
virtual void fun1() = 0;
virtual void fun2() = 0;
virtual void fun3() = 0;
};

1、对于这种接口有可能以后需要进行大范围接口修改,此时可以提供下面的创建这个接口对象的exportable函数:
void* createObject(const char* pname, void* pargs);
用户如果想创建IObject的实例,那么可以这样编写代码:
IObject* pObj = (IObject*)createObject("IObject", NULL); // 如果不需要参数那么就填NULL;
这样就实现了根据名字创建对象的策略(就是创建插件的方法),通过这一个接口可以导出很多其他的对象,接口并不一定相同。而且createObject能导出什么接口,是由开发包发布的时候,由发布者对外公布的。呵呵,这种函数几乎是万能接口了。

2.支持接口的扩展,同时保持与老接口兼容的方法:
还是以上面的接口为例。方法是类似的:
class IObject
{
public:
virtual void fun1() = 0;
virtual void fun2() = 0;
virtual void fun3() = 0;

virtual void* getExtent(const char* pname, void* pextarg) = 0;
};

这个接口比上面的接口多了一个函数:
virtual void* getExtent(const char* pname, void* pextarg) = 0;
或许you很快会意识到,这个接口也将是可扩展的了:
通过pname参数传入不同的名字可以从现有的IObject接口中导出新的接口。
这样就的业务可以仍然使用旧的接口(fun1/fun2/fun3这三个接口函数并不需要删除);
但是新业务我们可以要求新业务使用扩展接口:通过getExtent导出的接口。
比如由于业务的发展,需要修改这个接口,那么我们在发布新版本的时候,可以提供新的扩展接口:
class IObjExt
{
public:
virtual void newfun() = 0;
};

用户可以这样使用新接口:
IObjExt* pExt = pObj->getExtent("IObjExt", NULL);
...
pExt->newfun();
当然并不限制为通过名字获取接口也可以通过其他的数据类型。
This is 插件式接口....:)
lyg_zy 2007-06-05
  • 打赏
  • 举报
回复
1:采用com方式,QueryInterface 发展一新接口来扩展参数和功能
2:采用命令模式:
比如设计一接口函数为ExecuteCommand(CommandI *pCommand);其实现主要为
pCommand->Execute();

CommandI为一命令执行类:
class CommandI
{
virtual void _stdcall Execute() = 0;
};

第一版本的实现比如只有一参数 int a
Class CommandImplOld:class CommandI
{
Private:
int a;
};
第二版本的实现比如只有二参数 int a,int b;
Class CommandImplNew:class CommandI
{
Private:
int a;
int b;
};
这样的化,以后的变化接是CommandI的派生类的变化.

3:采用Com里的IDispach的Invoke实现的原理实现,函数原型如下:
HRESULT Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR *pDispParams,
VARIANT FAR *pVarResult,
EXCEPINFO FAR *pExcepInfo,
unsigned int FAR *puArgErr);






dai_weitao 2007-06-05
  • 打赏
  • 举报
回复
设计时保留一到两个参数为NULL, 留着以后扩展用.
hlqyq 2007-05-20
  • 打赏
  • 举报
回复
诶,接口,诗歌一样的概念.能被调用的,都是接口?
如果你写了一个基类,派生类仅需定义构造、析构函数,以及保护和私有的虚拟函数,嗯,你定义了一个很好的接口.
庄鱼 2007-05-15
  • 打赏
  • 举报
回复
接口是一种很复杂的技术,其复杂性在于数据逆推,根据任一成员或成员函数可以推知整个结构的相互关系,因此,作为通用型接口考虑,有必要将结构本身作为一个类参数加以传递。
wishfly 2007-04-28
  • 打赏
  • 举报
回复
mark
xxyifan 2007-04-28
  • 打赏
  • 举报
回复
修改接口不是好办法,让用户知道他不使用的接口也不是好事情,重载同理,如果架构已经定下来,可以考虑Vistor模式
houdy 2007-04-22
  • 打赏
  • 举报
回复
这个问题应该比我们想像的要复杂,所以我们需要比较系统的分析和思考。我觉得我们首先可以从对接口的定义开始入手。接口可以以很多的形式存在:
1. 函数。例如Win32 API都是以函数的形式的存在。
2. 类。类的公用成员函数/共有静态函数/友元函数/特殊的全局函数,构成了类的接口。
3. COM。COM思想很好的体现了面向接口编程思想。
在有了接口清晰的定义后,我们就可以根据不同的类型讨论不同的接口扩展方式。
yutaooo 2007-04-18
  • 打赏
  • 举报
回复
我对接口有这样的看法:

1.我们C++说的接口通常指类的所有 公有成员 + 非成员方法(这个好象常被忽略), 如:
class A {
public:
void foo(); // 这个也算接口的方法吧。
int value_; // 这个也应该认为是接口的一部分吧。
}

std::ostream & operator<<(std::ostream &, A const &); // 我觉得operator<<也要算

2.以前做COM之类的程序,也有接口的概念。那个接口通常指,纯抽象类(有这种叫法吗?),如:
struct IA : public IUnknown { // 所有方法都要virtual / = 0
virtual void foo() = 0;
virtual void func() = 0;
};

3.接口就是他奶奶的要稳定。没啥多想的,不稳定的话就是麻烦。虽然一些设计模式可以做些有限的扩展,但是累、复杂、难以理解是免不了了。

4.所以接口设计体现一个设计师,架构师的价值。要求他穿透N个月,N年看问题,其核心在于他能够比绝大多数人快的多的找到事物的自然本质。也因此,精心设计接口,一丝不苟是件异常重要的事情。
gudyn 2007-04-18
  • 打赏
  • 举报
回复
不要试图去这样作。
wanglovec 2007-03-10
  • 打赏
  • 举报
回复
这个问题我也苦恼
h3w4 2007-02-16
  • 打赏
  • 举报
回复
同意楼上,想要复用以前的实现
1.包含实现/接口
2.继承接口
kuanghong 2007-02-15
  • 打赏
  • 举报
回复
升级接口,兼容老的接口。
OpenHero 2007-02-12
  • 打赏
  • 举报
回复
仿照COM吧。。。
heguodong 2007-02-10
  • 打赏
  • 举报
回复
微软的做法是扩展接口,原有的接口不变,在此基础上增加
你以前的程序不用修改,你新的需求就调用新接口,OK?
飞驰的青蛙 2007-02-10
  • 打赏
  • 举报
回复
up
加载更多回复(15)

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧