社区
模式及实现
帖子详情
请问,这种情况如何处理?
byteman_daydayup
2007-03-05 10:20:18
当从一个接口,继承出了多个子类,接口规范了子类的外部行为,然后某个子类却因为某种原因需要扩展其接口,这种情况该如何处理?? 是修改它们共有的父类接口,还是通过装饰模式来为需要扩展接口的子类增加接口(但是装饰模式,好象只能增强或修改某个接口,不能扩展出新的接口).如果装饰模式不行的话,通过修改父接口,必然为其他子类增加上不必要的接口.这种情况下我又想针对接口编程,该怎么办啦??
...全文
400
19
打赏
收藏
请问,这种情况如何处理?
当从一个接口,继承出了多个子类,接口规范了子类的外部行为,然后某个子类却因为某种原因需要扩展其接口,这种情况该如何处理?? 是修改它们共有的父类接口,还是通过装饰模式来为需要扩展接口的子类增加接口(但是装饰模式,好象只能增强或修改某个接口,不能扩展出新的接口).如果装饰模式不行的话,通过修改父接口,必然为其他子类增加上不必要的接口.这种情况下我又想针对接口编程,该怎么办啦??
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
19 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
UltraBejing
2008-05-01
打赏
举报
回复
以后需再关注,现在先帮你顶一下
knowledge_Is_Life
2008-05-01
打赏
举报
回复
支持搂主,收藏
wanglovec
2007-03-24
打赏
举报
回复
这是个问题
lyg_zy
2007-03-24
打赏
举报
回复
sorry,上边写的东西有些错误,现在再写一遍:
enum eType
{
eBase,
eDeriv1,
eDeriv2,
}
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual void* QueryInterface(eType nType) = 0;
};
class BaseImpl:public IBase
{
public:
void func1();
void func2();
void* QueryInterface(eType nType)
{
if (nType==eBase)
{
return (IBase *) this;
}
return NULL;
};
};
如果第一个子类接口如下:
class IDerive1:
{
public:
virtual void func3() = 0;
}
class DeriveImp1 :public BaseImpl,public IDerive1
{
public:
//void func1(); 这个可以不实现了,BaseImpl已实现
//void func2();这个可以不实现了,BaseImpl已实现
void func3(); //IDerive1接口
void* QueryInterface(eType nType)//重载此虚函数
{
if (nType==eDevive1)
{
return (IDerive1 *) this;
}
return NULL;
}
};
然后使用的时候这样使用
IBase *pBase= new DeriveImp1();
pBase->func1();
IDerive1* pDerive1=(IDerive1*)pBase->QueryInterface(eDerive1);
if(pDerive1)
{
pDerive1->func3();
}
以上代码用一enum来标识不同的派生接口。我们在得到任一基类接口对象后,都可以用enum类型来探查他实际支持的派生类接口从而确定我们实际的调用。可以通过不停的扩充enum和派生类接口来完成扩展。
lyg_zy
2007-03-24
打赏
举报
回复
enum eType
{
eBase,
eB,
eC,
}
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual void* QueryInterface(eType nType) = 0;
};
class BaseImpl:public IBase
{
public:
void func1();
void func2();
virtual void* QueryInterface(eType nType)
{
if (nType==eBase)
{
return (IBase *) this;
}
return NULL;
};
};
如果子类B正是我要扩展的
class IB:
{
public:
virtual void func3() = 0;
}
class B:public BaseImpl,public IB
{
public:
void func1();
void func2();
void func3(); //扩展了的接口
virtual void* QueryInterface(eType nType)
{
if (nType==eB)
{
return (IB *) this;
}
return NULL;
}
};
然后使用的时候这样使用
IBase *p= new B();
p->func1();
IB* pB=p->QueryInterface( 1);
if(pB)
{
pB->func3();
}
lyg_zy
2007-03-24
打赏
举报
回复
这个问题一种优雅的方式可以采用COM里的方式.所以的创建都可以返回一基类接口(比如Com里的IUnknow)接口。这样可以调用基类的所有方法,然后每个接口都一QueryInterface(int nType)
(在Com里int nType是一GUID)查询返回它的子类接口不就行了吗?看看Com里的实现手法吧。
iambic
2007-03-06
打赏
举报
回复
Adaptor
heguodong
2007-03-06
打赏
举报
回复
但是装饰模式,好象只能增强或修改某个接口,不能扩展出新的接口
概念上错误
装饰模式的意图是为了不该边原有接口的前提下扩展接口
注意前提只是不改变原有接口
class ICar
{
public:
virtual void Run() = 0;
};
class ColorCar:public ICar
{
ICar car;
public :
ColorCar(ICar _car)
{
car=_car;
}
virtual color GetColor(){return null;}
virtual void Run(){}
}
ytfhwfnh
2007-03-05
打赏
举报
回复
最好的办法是在IBase中添加一个退化了的方法:
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual void func3() { };
};
这样,以后子类中需要func3()的时候也方便扩展。如果没有func3()的子类,通过基类指针使用了func3(),你希望怎么处理?可以添加到IBase中。
byteman_daydayup
2007-03-05
打赏
举报
回复
请问你是说这样吗?
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class A:public IBase
{
public:
void func1();
void func2();
};
如果子类B正是我要扩展的
class IB:
{
public:
virtual void func3() = 0;
}
class B:public IBase,public IB
{
public:
void func1();
void func2();
void func3(); //扩展了的接口
};
然后使用的时候这样使用
IB *p = new B();
p->func3(); //这样使用的也是IB这个接口,也算是针对接口编程了吧??
我理解的对吗??
byteman_daydayup
2007-03-05
打赏
举报
回复
如果我直接扩展了子类的接口,那么如果我使用的是它们父类的接口的话,就不能使用到扩展后的子类的接口啊
比如
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class A:public IBase
{
public:
void func1();
void func2();
};
如果子类B正是我要扩展的
class B:public IBase
{
public:
void func1();
void func2();
void func3(); //扩展了的接口
};
这样我在使用子类B的时候
IBase* p =new B();
p->func3(); //这样就访问不了func3.
但是如果这样
B* b = new B();
b->func3() //这样就依赖于了具体的类B了,不是针对接口编程了.
这种情况有什么好的方法吗??
ytfhwfnh
2007-03-05
打赏
举报
回复
直接扩展子类的接口不行吗?不知道子类的具体要求是什么?最好能举具体的例子。
byteman_daydayup
2007-03-05
打赏
举报
回复
我是这样采用观察者模式的,首先网络通讯类继承通讯类和被观察者类这2个接口,然后界面类继承观察者类,当网络通讯类检测到新的客户加入或者断开的时候,会更新在先客户断链表中的类容,然后调用观察者的notify方法来通知他,让界面类根据我更新后的在线客户链表中的内容来更新界面,然后用户可能会选择某几个在线的客户,然后给他们发送相同的命令,当选中某几个时候,会调用被观察者提供的更新待发送客户端链表内容的方法,来修改待发送链表中的客户,当使用writerbuffer时候,会根据实际待发送客户断链表中的客户来发送数据给它们!
byteman_daydayup
2007-03-05
打赏
举报
回复
我现在的做法是这样的,因为是才用模式,很多东西觉得生搬硬套的感觉
因为网络通讯类在接收到新的客户端加入的时候,需要通知界面显示新到的客户,以便选择,所以我采用了观察者模式.
在网络通讯类中聚合1个管理在线客户SOCKET和1个管理选中待发送客户端SOCKET的链表,一个用来接收上线的客户,以便显示到界面上,一个管理那些将要被发送命令的SOCKET,待我调用接口中的writebuffer命令的时候,就查询第2个连表中的socket,一个一个的通过他们发送数据.
byteman_daydayup
2007-03-05
打赏
举报
回复
我这里遇到这样一个实际问题:
需要设计一个程序,能够通过网络方式或者串行口方式发送命令去控制下位机,下位机大概有100多台,分布在各地.其中网络方式只需要实现一个C/S模式的S端,因为下位机的各个控制器会主动连接到一个固定的IP上来,等到下位机连接上我的服务器以后,我可以选择一个或多个指定的客户端下位机.向他们一起发送我的控制命令.串口方式是本地配置下位机,只能一台一台的发命令给下位机,网络方式要求是远程并且可以多台一起设置.
我抽象出了这么一个公共的接口
class TCommunication
{
public:
virtual UINT32 WriteBuffer(UINT8* buffer, UINT32 len) = 0;
virtual UINT32 ReadBuffer (UINT8* buffer, UINT32 len) = 0;
virtual ~TCommunication(){};
virtual int Setting(UINT32 speed, UINT16 port) = 0;
virtual int Start() = 0;
virtual int Stop() = 0;
};
然后分别实现串口类和网络类(继承通讯接口).但是他们两个子类之间又有一些不同之处
串口方式很简单,就只需要同时给一台机器发命令就好了
网络方式需要给多台一起发命令,因此它内部需要一个容器来保存各个客户端的SOCKET.然后循环发送命令,并且还需要设计一个界面来显示当前上线的客户端,然后根据你的选择一个或多个,给指定的客户发数据.
所以感觉两个子类应该可以从通讯借口中继承下来.
foochow
2007-03-05
打赏
举报
回复
class IBase
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class b :public IBase
{
public:
virtual void func3()=0;
};
class B:public b
{
public:
void func1(){}
void func2(){}
void func3(){}
};
b*_bp=new B;
b->func1();
b->func2();
b->func3();
ytfhwfnh
2007-03-05
打赏
举报
回复
你这么些子类通过什么抽象概念将它们连接在一起呢?如果出现你所说的情况的话,就应该考虑重新设计了,模式不能死搬硬套,视情况而定。
believefym
2007-03-05
打赏
举报
回复
子类如果扩展了,就不能再用通过接口进行多态的调用了
byteman_daydayup
2007-03-05
打赏
举报
回复
如果我有许多子类,各个子类需要不同的扩展,那么添加如此多的空方法到父类中,这样好吗??
我还是初学者,很多东西的理解都是靠凭空想象,不对的地方还请指正
什么是异常?为什么要使用异常
处理
?java是如何实现异常
处理
的?
这种
情况
称为异常
情况
,通常会导致程序异常从而停止执行。 作为程序员,我们应该
处理
这些特殊
情况
,以便与用户进行友好的交互,并让程序继续正常执行,而不是使程序崩溃或死亡。 因此,术语“异常
处理
”。 假如程序...
ctrl导致开机弹出计算机,开机提示“Press Ctrl+Alt+Del to restart”
这种
情况
如何
处理
?...
开机提示“Press Ctrl+Alt+Del to restart”
这种
情况
如何
处理
?2018-06-22 16:26:29近经常听到用户反应说自己电脑开机的时候经常出现“Press Ctrl+Alt+Del to restart”
这种
情况
,那么应该如何进行
处理
呢,下面小编...
exe闪退 怎样解决python_python文件打开闪退要怎么
处理
?
小编就曾遇到过,很疑惑,自己的软件是严格按照顺序步骤安装好的,为什么会出现
这种
情况
呢?有疑问首先就先去了解了问题所在,经过勘查一系列的相关内容,于是不仅解决了问题,还发现一些可以注意的内容,一起来看...
抖音小店无货源,出现退货的
情况
怎么
处理
?千万别大意
抖音小店无货源,出现退货的
情况
怎么
处理
?新手商家千万别大意 首先,我们先来了解一下抖店后台都有哪些退款方式:有发货前仅退款、发货后仅退款、退货退款还有换货。 那像发货前仅退款
处理
的话就比较容易
处理
的,...
项目上线后出现Bug,该如何
处理
?
项目在上线之后又出现了Bug,这让很多测试人员和开发人员头痛。但很多时候线上Bug普遍地存在,不可避免。 任何项目都存在未发现 ...那么遇到
这种
情况
,测试人员该如何
处理
呢? 首先测试人员可以做的是重现这个问题...
模式及实现
5,530
社区成员
4,169
社区内容
发帖
与我相关
我的任务
模式及实现
C/C++ 模式及实现
复制链接
扫一扫
分享
社区描述
C/C++ 模式及实现
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章