社区
模式及实现
帖子详情
请问,这种情况如何处理?
byteman_daydayup
2007-03-05 10:20:18
当从一个接口,继承出了多个子类,接口规范了子类的外部行为,然后某个子类却因为某种原因需要扩展其接口,这种情况该如何处理?? 是修改它们共有的父类接口,还是通过装饰模式来为需要扩展接口的子类增加接口(但是装饰模式,好象只能增强或修改某个接口,不能扩展出新的接口).如果装饰模式不行的话,通过修改父接口,必然为其他子类增加上不必要的接口.这种情况下我又想针对接口编程,该怎么办啦??
...全文
401
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
打赏
举报
回复
如果我有许多子类,各个子类需要不同的扩展,那么添加如此多的空方法到父类中,这样好吗??
我还是初学者,很多东西的理解都是靠凭空想象,不对的地方还请指正
Oracle数据库 大事务的数据更改对数据库内部的影响
本课程以Oracle 10g数据库为基础,来... 那么在
这种
情况
下,当用户执行commit提交操作,数据库是如何
处理
这些已经写到磁盘的脏数据块的? 本课程就以实验的方式得出数据,来验证以上所提出的问题。
什么是异常?为什么要使用异常
处理
?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”
这种
情况
,那么应该如何进行
处理
呢,下面小编...
抖音小店无货源,出现退货的
情况
怎么
处理
?千万别大意
抖音小店无货源,出现退货的
情况
怎么
处理
?新手商家千万别大意 首先,我们先来了解一下抖店后台都有哪些退款方式:有发货前仅退款、发货后仅退款、退货退款还有换货。 那像发货前仅退款
处理
的话就比较容易
处理
的,...
项目上线后出现Bug,该如何
处理
?
项目在上线之后又出现了Bug,这让很多测试人员和开发人员头痛。但很多时候线上Bug普遍地存在,不可避免。 任何项目都存在未发现 ...那么遇到
这种
情况
,测试人员该如何
处理
呢? 首先测试人员可以做的是重现这个问题...
模式及实现
5,530
社区成员
4,169
社区内容
发帖
与我相关
我的任务
模式及实现
C/C++ 模式及实现
复制链接
扫一扫
分享
社区描述
C/C++ 模式及实现
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章