求范型模式的类设计方案

chenyu2202863 2009-10-13 11:16:54
加精
背景:
目前有一批控件类(Button,CheckBox,ListCtrl等),都是继承自Control类。
Control类提供一些通用Virtual方法,继承类按需求改写某些方法。
然后还有各个控件的管理类,比如管理Button的管理类ButtonCollection,负责更换皮肤、删除资源之类的需要集中处理的事务。

现在客户端的调用就比较尴尬,需要定义控件类和管理控件类,比如CMyButton和CMyButtonCollection。

需求:
我希望能有范型的设计把这些郁闷给消灭,然后客户端尽可能充分享受编程的乐趣!我用的WTL库做的开发,所以想尽可能的应用范型模式来设计开发

PS:看着STL和LOKI把范型应用的那么优雅高效,羡慕啊~
...全文
455 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
gwemail2003 2009-10-17
  • 打赏
  • 举报
回复
1 用模式可以解决问题
2 感觉换皮肤等对控件是公共的处理,应该是横向处理的问题。
chenyu2202863 2009-10-16
  • 打赏
  • 举报
回复
再顶一天
hankanling123 2009-10-16
  • 打赏
  • 举报
回复
不是这样的。你可以到百度里面去查询一下......
chenyu2202863 2009-10-16
  • 打赏
  • 举报
回复
再顶一下,希望更多的朋友学习和牛人来支招!
chenyu2202863 2009-10-15
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 jameshooo 的回复:]
用到泛型再用公共基类的话,就失去了泛型开销小的优点了。

泛型的设计要点:把设计中的各方面特性都抽取出来,每个特性就是一个模板类型,特性的粒度可大可小。
以你的需求作为例子,你现在需要一个集合管理类,第一步就是构造最粗的粒度:

template <class TControl /*=CMyButton*/ >
class ControlManagerT
{ ... };

接下来你会发现不同控件的使用有些差别(这里假设控件不是从同一个公共基类派生的,否则没必要搞泛型),导致上面的管理模板很难写代码,这时就需要把粒度细化,方法就是把差别的地方再次封装成一个模板类型,假设消息处理机制不同,就为每种控件设计一个消息接受者类(或函数等):

template <class TControl, class TMessageReceiver>
class ControlManagerT
{ ... };

第三步,这里还能继续优化,例如某些控件的消息接受者可以合并,那么可以把 TMessageReceiver 也做成一个模板类,封装一些通用的处理,针对少量控件定义特化模板类,例如:

template <class TControl>
class MessageReceiverT { ... };

template <>
class MessageReceiverT <CMyButton> { ... }; // CMyButton 特化类
... // 可能还有其它特化类

// 管理类就可以这样定义:
template <class TControl, class TMessageReceiver=MessageReceiverT <TControl> >
class ControlManagerT { ... }

上述细化过程可以一直持续下去,直到满足需求为止!等你做下去之后,你就会发现STL/ATL之流都是这样设计的。只不过它们是通用的,所以粒度非常精细,但你自己的实际应用中是不需要这么精细的。

最后的用法:
ControlManagerT <CMyButton> m_btnCollection;
[/Quote]

赞,厉害!
给了许多启发,看来得在思想上转变,GP的思想真好!
cphj 2009-10-15
  • 打赏
  • 举报
回复
嗯,最近看Generic Programming and the STL以及STL的一些历史,说到GP其实有一定程度的面向对象,STL之父之前在多种支持OOP的语言上尝试过(scheme, ada, java)实现和使用泛型算法,包括在C++完整引入模板之前他试图用单根继承来实现也非常困难,最后他的结论是完全的面向对象和GP不相容,或者说是正交的

所以比较怀疑范型能承担GUI框架的设计作用,应该只能在容器和算法上面用一用
chenyu2202863 2009-10-15
  • 打赏
  • 举报
回复
C++社区很少讨论模式的,大部分都是在讨论实现~
xwsn007 2009-10-15
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 jameshooo 的回复:]
用到泛型再用公共基类的话,就失去了泛型开销小的优点了。

泛型的设计要点:把设计中的各方面特性都抽取出来,每个特性就是一个模板类型,特性的粒度可大可小。
以你的需求作为例子,你现在需要一个集合管理类,第一步就是构造最粗的粒度:

template <class TControl /*=CMyButton*/ >
class ControlManagerT
{ ... };

接下来你会发现不同控件的使用有些差别(这里假设控件不是从同一个公共基类派生的,否则没必要搞泛型),导致上面的管理模板很难写代码,这时就需要把粒度细化,方法就是把差别的地方再次封装成一个模板类型,假设消息处理机制不同,就为每种控件设计一个消息接受者类(或函数等):

template <class TControl, class TMessageReceiver>
class ControlManagerT
{ ... };

第三步,这里还能继续优化,例如某些控件的消息接受者可以合并,那么可以把 TMessageReceiver 也做成一个模板类,封装一些通用的处理,针对少量控件定义特化模板类,例如:

template <class TControl>
class MessageReceiverT { ... };

template <>
class MessageReceiverT <CMyButton> { ... }; // CMyButton 特化类
... // 可能还有其它特化类

// 管理类就可以这样定义:
template <class TControl, class TMessageReceiver=MessageReceiverT <TControl> >
class ControlManagerT { ... }

上述细化过程可以一直持续下去,直到满足需求为止!等你做下去之后,你就会发现STL/ATL之流都是这样设计的。只不过它们是通用的,所以粒度非常精细,但你自己的实际应用中是不需要这么精细的。

最后的用法:
ControlManagerT <CMyButton> m_btnCollection;
[/Quote]

双手赞成!!!
yshuise 2009-10-14
  • 打赏
  • 举报
回复
FACTORY METHOD(工厂方法)—对象创建型模式
cattycat 2009-10-14
  • 打赏
  • 举报
回复
觉得还是选择一种设计模式比较好。
可以设计管理类的基类,对每个Control的子类设计一个管理类的子类。
在管理类的基类有一个到Control类的指针,每个管理类的子类负责实例化自己的对象,保证每个控件管理器的子类生成对应的控件。
可以参考Factrory 模式。
jameshooo 2009-10-14
  • 打赏
  • 举报
回复
用到泛型再用公共基类的话,就失去了泛型开销小的优点了。

泛型的设计要点:把设计中的各方面特性都抽取出来,每个特性就是一个模板类型,特性的粒度可大可小。
以你的需求作为例子,你现在需要一个集合管理类,第一步就是构造最粗的粒度:

template<class TControl /*=CMyButton*/ >
class ControlManagerT
{ ... };

接下来你会发现不同控件的使用有些差别(这里假设控件不是从同一个公共基类派生的,否则没必要搞泛型),导致上面的管理模板很难写代码,这时就需要把粒度细化,方法就是把差别的地方再次封装成一个模板类型,假设消息处理机制不同,就为每种控件设计一个消息接受者类(或函数等):

template<class TControl, class TMessageReceiver>
class ControlManagerT
{ ... };

第三步,这里还能继续优化,例如某些控件的消息接受者可以合并,那么可以把 TMessageReceiver 也做成一个模板类,封装一些通用的处理,针对少量控件定义特化模板类,例如:

template<class TControl>
class MessageReceiverT { ... };

template<>
class MessageReceiverT<CMyButton> { ... }; // CMyButton 特化类
... // 可能还有其它特化类

// 管理类就可以这样定义:
template<class TControl, class TMessageReceiver=MessageReceiverT<TControl> >
class ControlManagerT { ... }

上述细化过程可以一直持续下去,直到满足需求为止!等你做下去之后,你就会发现STL/ATL之流都是这样设计的。只不过它们是通用的,所以粒度非常精细,但你自己的实际应用中是不需要这么精细的。

最后的用法:
ControlManagerT<CMyButton> m_btnCollection;
fishgo1 2009-10-14
  • 打赏
  • 举报
回复
chenyu2202863 2009-10-14
  • 打赏
  • 举报
回复
来高人~
chenyu2202863 2009-10-14
  • 打赏
  • 举报
回复
对,我也想到了抽象接口
把控件的通用行为抽象出来,按不同行为分类。
比如,鼠标的移近移出,Down、Up为一类接口,而绘制为一类接口

这样后,思路很清晰了,也方便以后扩展,但是感觉怪怪的。
chenyu2202863 2009-10-14
  • 打赏
  • 举报
回复
to Jcily

确实如你所说,Control类抽象了共有的接口
但是我想在重新设计Collection和相关控件类(其实是贴图而已)的关系,以免在客户端调用的时候需要控件类和控件管理类,如CMyButton和CMyButtonCollection
asimay 2009-10-14
  • 打赏
  • 举报
回复
抽象接口
Hiiishe 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 chenyu2202863 的回复:]
目前没有用Factory模式,只是在特定类中固定生成控件类,然后Add进Collection进行管理
比如
CMyDialog
{
private:
    CMyButton[2] m_wndBtn;
    CMyButtonCollection m_btnCollection;
};

使用的时候
btnCollection.Add(&m_wndBtn);


现在,我想把Collection做成模板类,基于策略选择不同的控件类。虽然我都把所有控件类通用的行为都抽象了,但是某些控件还是有不同的行为。难点啊

[/Quote]

看你贴出的代码,你各个具体控件,在创建和销毁都由客户端代码在做,对应Collection做了一些其他事情,
我觉得可以把各个控件的创建与销毁的实现细节代码也由Collection来做,而客户端代码只需要关心自己想要创建什么,而至于怎么创建由对应Collection来提供,返回给客户代码对应控件指针。
另外,客户端还是需要知道(包含)各个具体控件类的,比如在操作特定控件时候。
你想达到的目的似乎是在操作各个控件也做到泛型,这给设计本身增加一定的复杂性,你需要抽象操作层次,为客户代码构建一层操作上的统一的编程流程,而你再在这一层的实现中做具体的操作细节实现。从而让客户代码不亲自操作各个控件,只是发出请求或者命令。
有没有必要再抽这么一层出来,完全根据实际情况来,若本身直接操作各个具体控件也很好理解,且各个具体控件的接口设计也达到了单一职责就没有太大必要。否则你抽象出来的一层概念在使用上流程更难理解,丢失了客户代码在使用上的灵活性,而只是编程代码少了几句,就不好了。
设计时会有很多需要权衡的地方,这需要有丰富的经验。
xwsn007 2009-10-14
  • 打赏
  • 举报
回复
想法不错,参考一下stl的源码,将Control类设计为模板类啊,反正其负责更换皮肤、删除资源之类的通用的
与控件类型无关的操作。像CMyButtonCollection这样的一种控件类型,一个collection类的方式不好。
lsd123 2009-10-14
  • 打赏
  • 举报
回复
.
zhp21 2009-10-14
  • 打赏
  • 举报
回复


class InterfaceBase
{
public:
virtual IDispatch* GetSelfObj() = 0;
};
template< class t>
class cwnd : publc InterfaceBase
{
};
class somewnd :publc cwnd
{
};//
cwnd<somewnd > m_wnd;

就这么个思路
加载更多回复(6)

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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