LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 628|回复: 1

一个接口命名的问题(选择题)

[复制链接]
发表于 2009-5-4 12:04:32 | 显示全部楼层 |阅读模式
我是给公司内部做C++类库的, 我们的代码规范是: 函数用pascal命名

先看这3个代码, 它们有类似的功能, 只是接口有点区别.

class Temperature;
========================================
代码A: 函数名前面带Get和Set, 接口对称, 不易出错, 但有时很不自然.
class Bird
{
        void SetFlying(bool);
        bool GetFlying() const;
        void SetRunning(bool);
        bool GetRunning() const;
        bool GetHasFeather() const; // get has ???
        Temperature GetTemperature() const;
};

Bird myBird;
myBird.SetFlying(true);
if(myBird.GetFlying())
{
        myBird.SetFlying(false);
}
======================================
代码B: 类似自然语言的写法, 但有陷阱, 容易出错
class Bird
{
        void Fly();
        bool IsFlying() const;
        void Land(); // 和Fly相对应
        void Run();
        bool IsRunning() const;
        void Stop(); // 和Run相对应
        bool HasFeather() const;
        Temperature GetTemperature() const;
};

Bird myBird;
myBird.Fly();
if(myBird.IsFlying())
{
        myBird.Stop(); // 错误, 应是Land()
}
=============================================
代码C: 代码A的修改, 去掉Get/Set, 引出了新的问题:
class Bird
{
        void Flying(bool);
        bool Flying() const;
        void Running(bool);
        bool Running() const;
        bool HasFeather() const;
        void Temperature(::Temperature); //函数和类同名, 或多或少会造成一些困扰
        ::Temperature Temperature() const;
};

========================================
代码D: 代码A的修改版, 用更自然的词代替Get
class Bird
{
        void SetFlying(bool);
        bool IsFlying() const;
        void SetRunning(bool);
        bool IsRunning() const;
        bool HasFeather() const;
        Temperature GetTemperature() const;
};

这几种风格中, 我认为C最好, B最差.

B是不可取的, 因为太容易出错, 代码首先要正确, 才能讲究"风格".
A和C对比, C少了Set/Get, 但从参数形式就可以明显看出, 所以并不需要特意加上.
而重名并不是问题, 因为这两个名字实际在两个不同的空间, 不是真的重名.
D的写法是我最常用的, 但它破坏了对称性, "set"本应对应"get", 而不是"is".


所以我打算在以后开发中采用C的写法, 不用D了.
不知你是否认同我的选择, 或者是否有更好的写法?
单选投票, 共有 3 人参与投票

投票已经结束

33.33% (1)
0.00% (0)
33.33% (1)
33.33% (1)
您所在的用户组没有投票权限
发表于 2009-5-4 13:24:20 | 显示全部楼层
get/set成对出现是习惯用法,LZ如果去掉,以后其他人接手会很麻烦。如
Obj* getSingleton();
一看方法名就知道是取得一个实例的指针。如果改成
Obj* Singleton();
是创建了一个实例呢?还是取得了一个实例呢?就得去查文档。
而且用get/set方法,在方法列表里会按字母排序,都给放在一起,用起来也方便。

我个从比较喜欢的两种风格,LZ可以参考一下
A: 比较类似JAVA。方法第一个单词如果是动词,首字母小写。
class obj
{
public:
  obj() {}
  virtual ~obj() {}

public:
  int getValue() { return 0; }
  void setValue(int value) { mValue = value; }

protected:
  int mValue;
};

B:BOOST风格,全部小写,方法的动词与后面的单词用"_"分割。
class obj
{
public:
  obj() {}
  virtual ~obj() {}

public:
  int get_value() { return 0; }
  void set_value(int value) { _value = value; }

protected:
  int _value;
};
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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