关于接口的设计

 

在 关于UI回调Invoker的实现(二)这一篇中,我说到了接口设计问题。

 

一个对象,只能访问属于自己应该访问的方法,而对于不能访问不该访问的方法。

其实,这是一句废话。

 

怎么评判“什么方法应该访问,什么方法不应该访问”呢?

 

如果一个类,public访问属性的方法全部是继承自接口的方法。那么,我认为这个接口没有任何意义。

接口的意义在于,接口的客户,不知道接口是如何实现的。但是它仍然能通过接口的实例,访问(对应的)方法。

如果代码有这样的例子,这跟把类的方法直接全部暴露给客户,没有区别。

 

例如上篇文章给的例子。

SetPressFunc这个方法,是button等有响应的窗口控件才有的,对于窗口本身没有任何意义(除非你让点击窗口的时候,也响应一个回调)。

因此,对于SetPressFunc来说,它只应该属于IUIButton接口,而不应该属于IUIWnd接口。

尽管IUIButton继承自IUIWnd。

 

例如,我有一个类方法,这个类方法会改变类对象的某项(危险的)属性。这是一个危险的类方法,我并不希望暴露给我的客户,因为客户完全不必了解这个属性会造成什么危害。

但是我希望我的客户能可以方便地使用其他类方法,而且,我不希望客户知道类的实现。

这种情况下,我需要提出接口。

 

假设有有一个接口:

class ISensitive
{
public:
	virtual ~ISensitive();

	virtual void SetOperationName(const _tchar* oper_name) = 0;
};

 这个接口只有一个方法,它能改变一个玩家的名字。

然后我有一个类,这个类继承了这个接口:

class CSensitive : public ISensitive
{
public:
	CSensitive();
	~CSensitive();

	virtual void SetOperationName(const _tchar* oper_name);

public:
	void SetOperationID(int64 oper_id);
};

  这个类除了继承自 ISensitive 的方法外,还有一个SetOperationID方法。

很显然,当客户使用 ISensitive 的实例的时候,只知道 SetOperationName 这一个方法,而且并不知道 实现这个接口的类,有 SetOperationID 这个方法。

一定会有人问,既然 SetOperationID 客户不知道,那要着它干什么?

 

先解释一个词:客户,很显然,客户是使用产品的人。

但是,使用的人,在不同的场合下,有不同的意义。

我的产品是一个类(以及它的接口)。使用产品的人有2种:

第一种:对类一无所知,也不需要知道的人。这类人通常是库的使用者。

第二种:不仅需要知道接口(有那些方法),还需要知道类(有那些方法)。这类人通常是库的作者(因为他知道内部怎么设计的,可以怎么转换而不会有危险)。

 

 

在这个前提下,再进行简要说明。

A是程序员,A是使用我提供的二进制库文件,和某些接口(类、和/或 方法)。A直接使用这些资源,来完成某件事情。

那么A是第一种客户。

我也是程序员,库是我所写的,但是我为了要让库正确稳定地工作,我可能需要定义其他模块,除了访问接口方法外,还需要访问接口对象无法访问,但是类对象能访问的方法。

我就是第二种客户。

 

紧接着上述代码的例子。

A为了要改变某个玩家的名字,用ISensitive接口提供的方法 SetOperationName 就可以了。但是,作为库的作者,我绝对不能让A访问 SetOperationID 这个方法。因为PlayerID是一个环境范围内,唯一存在的一个值。例如,游戏玩家的帐号ID。这个值在第一次初始化时候就固定下来,而且不支持更改。

既然不支持更改,那么 SetOperationID 这个方法有什么用?

考虑这种情况:玩家第一次登录,数据库查询,发现没有对应的角色给玩家初始化,需要玩家自己创建角色。接下来玩家创建了一个角色,系统随机生成一个唯一值,把这个值当作ID赋给PlayerID,这个ID关联创建的角色。这样,玩家下次登录的时候,选取已经创建的角色,只需要从数据库中找到对应ID,就可以初始化角色了。

 

有点类似于 Linux的用户。root有超级权限,想执行什么就执行什么,而其他用户的权限要少,某些能执行,某些不能执行。

对于类似的情况,就应该把都能做的事情提取成接口。把只有管理员能做的事情,保护起来。

 

我是一个初学者,在我设计我自己的UI库的时候,遇到这些接口定义的问题。仔细想过才有上述体会。

可能有些错误,欢迎指正。

 

=====>THE END<=====

posted @ 2013-11-01 20:32  ·若狂  阅读(545)  评论(0编辑  收藏  举报