游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9342|回复: 36

请问我应该如何设计我的代码接口

[复制链接]

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2013-12-2 17:26:39 | 显示全部楼层 |阅读模式
本帖最后由 akima 于 2013-12-2 17:28 编辑

各位前辈,我希望写一个基于接口的个人代码库,但是我遇到一点问题,描述如下(伪代码) :

  1. // 图形接口, 用于图形文件-图形数据的渲染和维护
  2. class IImage
  3. {
  4. void render( ... );
  5. void createForRenderTarget( ... );
  6. };

  7. // 以 D3D9 实现的图形类
  8. class CD3D9Image : public IImage
  9. {
  10. // 没问题,D3D9 的确可以渲染一个 Image
  11. void render( ... );
  12. // 没问题,D3D9 支持渲染目标,Image 可以作为渲染目标
  13. void createForRenderTarget( ... );
  14. };

  15. // 以 OpenGL 实现的图形类
  16. class COpenGLImage : public IImage
  17. {
  18. // 没问题,OpenGL 的确可以渲染一个 Image
  19. void render( ... );
  20. // 没问题,OpenGL 支持渲染目标,Image 可以作为渲染目标
  21. void createForRenderTarget( ... );
  22. };


  23. // 以 GDI 实现的图形类
  24. class CGDIImage : public IImage
  25. {
  26. // 没问题,GDI 的确可以渲染一个 Image
  27. void render( ... );
  28. // 问题来了 ... GDI 不支持 Image 作为渲染目标,这个方法我无法实现 ...
  29. void createForRenderTarget( ... );
  30. };
复制代码

如上,是一个图形接口,用来维护图形数据,进行渲染和一些基本操作,我希望用户只是用 IImage 接口,而避免用户接触到内部细节,很明显,一个 Image 基本上都可以作为一个渲染目标而创建的,这对于 D3D 和 OpenGL 应该没问题,可是作为 GDI 的话,可能就会出现问题了,因为 GDI 不支持渲染目标,这样一来,接口不就出现问题了 ?

我应该怎样处理上面问题呢 ?

17

主题

44

帖子

271

积分

中级会员

Rank: 3Rank: 3

积分
271
发表于 2013-12-2 19:55:16 | 显示全部楼层
没太明白你的意思 GDI不支持createForRenderTarget 按道理讲不应该作为Image的派生类,或者就算以Image类为父类也可以不实现createForRenderTarget 方法啊 可能是我没理解你的意思

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2013-12-2 20:39:29 | 显示全部楼层
新撰组 发表于 2013-12-2 19:55
没太明白你的意思 GDI不支持createForRenderTarget 按道理讲不应该作为Image的派生类,或者就算以Image类为 ...

终于有人回答啦,我觉得你说的有道理,如果 GDI 不能实现 createForRenderTarget( ) 的话,就不要继承自 IImage 接口,但是 CGDIImage 也不能独立出来实现啊,因为用户只能使用 IImage 接口,不知道应该怎么办 。
我也想忽略那些不能实现的方法,不过这样子貌似不符合标准 ...

17

主题

44

帖子

271

积分

中级会员

Rank: 3Rank: 3

积分
271
发表于 2013-12-2 20:41:49 | 显示全部楼层
那就不实现createForRenderTarget方法好了  CGDIImage::createForRenderTarget(){} 就这样好了

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2013-12-2 20:43:08 | 显示全部楼层
新撰组 发表于 2013-12-2 20:41
那就不实现createForRenderTarget方法好了  CGDIImage::createForRenderTarget(){} 就这样好了 ...

我也打算这么做,可是别人一旦调用 createForRenderTarget( ) ,却发现什么事情都没发生,甚至摸不着头脑,怎么办 ?

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2013-12-2 20:43:41 | 显示全部楼层
新撰组 发表于 2013-12-2 20:41
那就不实现createForRenderTarget方法好了  CGDIImage::createForRenderTarget(){} 就这样好了 ...

或许我可以在文档里面写明 XXX 不支持 createForRenderTarget( ) 方法

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20468
发表于 2013-12-2 22:57:25 | 显示全部楼层
我觉得你抽象得还不够,在遇到底层工作机制完全不同的情况下,你这样的接口可能就会面临一些结构上问题,比如某些底层根本没那个机制。

我觉得你要抽象出来一个中间件接口,应该是按照你的机制来实现,然后不同的底层只是服务你机制的一种实现,而不是把底层的某种工作方式当作你的机制。

不知道我的意思能不能说清楚,不是很好表达。


ps:可以看看cocos2dx,他就是类似的封装,但可能代码量会大一些,不是很好阅读。

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2013-12-2 23:58:29 | 显示全部楼层
sea_bug 发表于 2013-12-2 22:57
我觉得你抽象得还不够,在遇到底层工作机制完全不同的情况下,你这样的接口可能就会面临一些结构上问题,比 ...

哇,sea_bug 大大光临啦,好生荣幸
可以写一小段演示代码我看看么 ?单纯这样子说,我有点不懂
coos2d-x 我听说过,代码量庞大啊
要是为了解决这个问题特意去翻一个引擎的源码,有点不实际了

5

主题

84

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2013-12-3 00:06:12 | 显示全部楼层
sea_bug 发表于 2013-12-2 22:57
我觉得你抽象得还不够,在遇到底层工作机制完全不同的情况下,你这样的接口可能就会面临一些结构上问题,比 ...

sea_bug 前辈,我再举一个例子吧,这样子的问题我发现自己遇到好多了:

// 文件接口
class IFile
{
// 打开文件
void open( ... );
// 进行数据写操作
void write( ... );
};

// Windows 标准磁盘文件
class CDiskFile : public IFile
{
// 没问题,可以打开一个磁盘文件
void open( ... );
// 没问题,可以将数据写入磁盘文件
void write( ... );
};

// Zip 压缩文件
class CZipFile : public IFile
{
// 没问题,可以打开一个 Zip 压缩文件
void open( ... );
// 问题来了,Zip 压缩文件不支持 write 操作
void write( ... );
};

应该怎么解决呢 ?

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20468
发表于 2013-12-3 00:07:06 | 显示全部楼层
我也没做过类似中间件的抽象设计,只是针对你遇到的问题所思考的解决方案。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 05:27

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表