关于oop:最佳实践:在类定义中订购public / protected / private?

Best practice: ordering of public/protected/private within the class definition?

我正在从头开始一个新项目,希望它是干净的/有良好的编码标准。经验丰富的开发人员喜欢按什么顺序把事情安排在一个类中?

A:1)公共方法2)私有方法3)公共变量4)私有变量

B:1)公共变量2)私有变量3)公共方法4)私有方法

C:1)公共变量2)公共方法3)私有方法4)私有变量

我通常喜欢将公共静态变量放在顶部,但是公共静态方法会列在构造函数前面吗,还是应该总是首先列出构造函数?那种事…

我知道这是芬尼的,但我只是想知道:这方面的最佳实践是什么?

附言:不,我不使用CC。我知道。我是路德人。


在干净的代码中,Robert C.Martin建议编码人员总是将成员变量放在类的顶部(先是常量,然后是私有成员),并且方法的顺序应该是这样的,这样它们读起来就像一个故事,不会让读者过多地跳过代码。这是一种更明智的方式来组织代码,而不是通过访问修饰符。


最佳做法是保持一致。

就我个人而言,我更喜欢先使用public方法,然后使用protected方法,再使用private方法。一般来说,成员数据应该是私有的或受保护的,除非您有充分的理由不这样做。

我把public方法放在最上面的理由是它为类定义了接口,所以任何阅读您的头文件的人都应该能够立即看到这些信息。

一般来说,privateprotected成员对查看头文件的大多数人来说不太重要,除非他们考虑修改类的内部。将它们"挡在一边"可以确保只在需要知道的基础上维护这些信息,这是封装的一个更重要的方面。


我想我和大多数人在这方面有不同的哲学。我更喜欢将相关项目分组在一起。我不能忍受必须跳来跳去上课。代码应该基于可访问性(public、private、protected等)或实例与静态或成员与属性与函数之间的比较,以相当人为的顺序流动和使用,这无助于保持良好的流。因此,如果我有一个公共方法Method,它是由私有辅助方法HelperMethodAHelperMethodB等实现的,那么,我不会将这些方法彼此隔离在文件中,而是将它们彼此保持在一起。同样,如果我有一个由静态方法实现的实例方法,那么我也将这些方法组合在一起。

所以我的课经常是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MyClass {
    public string Method(int a) {
        return HelperMethodA(a) + HelperMethodB(this.SomeStringMember);
    }

    string HelperMethodA(int a) { // returns some string }

    string HelperMethodB(string s) { // returns some string }

    public bool Equals(MyClass other) { return MyClass.Equals(this, other); }

    public static bool Equals(MyClass left, MyClass right) { // return some bool }

    public double SomeCalculation(double x, double y) {
        if(x < 0) throw new ArgumentOutOfRangeException("x");
        return DoSomeCalculation(x, y);
    }

    const double aConstant;
    const double anotherConstant;
    double DoSomeCalculation(double x, double y) {
        return Math.Pow(aConstant, x) * Math.Sin(y)
            + this.SomeDoubleMember * anotherConstant;
    }      
}

就我个人而言,我喜欢先公开,后保护,再私有。原因是,当有人打开标题时,他/她首先看到他/她可以访问的内容,然后在他/她向下滚动时看到更多详细信息。


这是我点的菜

  • 静态变量
  • 静态方法
  • 公共变量
  • 受保护变量
  • 私有变量
  • 构造函数
  • 公共方法
  • 受保护的方法
  • 私有方法
  • 我使用以下规则:

    • 任何事之前都是静态的
    • 方法之前的构造函数之前的变量(我考虑属于以下类别的构造函数方法)
    • 公有公有私

    其思想是在行为(方法)之前定义对象(数据)。静态数据需要分离,因为它们既不是对象的一部分,也不是对象的行为。


    我以前很在乎。在过去的几年中,使用现代的IDES,几乎所有的操作都只需要1到2次按键,我已经让我的标准大大放松了。现在,我从静态变量、成员变量开始,然后是构造器,之后我不太担心它。

    在C中,我让Resharper自动组织事情。


    我一般同意公共、保护、私有秩序以及静态数据、成员数据、成员函数秩序。

    虽然我有时会像成员一样分组(getter&setter),但我通常喜欢按字母顺序列出组中的成员,以便更容易找到它们。

    我还喜欢垂直排列数据/函数。在右边加上制表符/空格,使所有名称在同一列中对齐。


    正如Elzo所说,现代的IDES使得在下拉菜单中使用彩色图标等更容易找到成员及其修改器。

    我的看法是,程序员更重要的是要知道这个类是为什么设计的,以及它应该如何工作。

    因此,如果它是单例的,我将语义(staticgetInstance()类)放在第一位。

    如果它是一个具体的工厂,我首先放置getnew()函数和register/initialize函数。

    …等等。当我说第一个的时候,我的意思是在c'tor和d'tor之后——因为它们是实例化任何类的默认方法。

    接下来的功能包括:

  • 逻辑调用顺序(例如initialize()、preprocess()、process()、postprocess())或
  • 相关功能在一起(如访问器、实用程序、操纵器等)。
  • 取决于类主要是一个带有一些函数的数据存储,还是一个带有一些数据成员的函数提供程序。


    public后跟protected和private的顺序对我来说更易读,最好在头文件顶部的注释中简单描述类逻辑,并使用函数调用命令来理解类剂量和内部使用的算法。

    我使用QT C++一段时间,看到一些新类型的关键字,比如EDCOX1,0,EDCX1,1。我更喜欢保持上面的顺序,和大家分享我的想法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #ifndef TEMPLATE_H
    #define TEMPLATE_H


    class ClassName
    {
        Q_OBJECT
        Q_PROPERTY(qreal startValue READ startValue WRITE setStartValue)
        Q_ENUMS(MyEnum)

    public:

        enum MyEnum {
            Hello = 0x0,
            World = 0x1
        };

        // constructors

        explicit ClassName(QObject *parent = Q_NULLPTR);
        ~ClassName();

        // getter and setters of member variables

        // public functions (normal & virtual) -> orderby logic

    public slots:

    signals:

    protected:

        // protected functions it's rule followed like public functions


    private slots:

    private:

        // methods

        // members

    };

    #endif // TEMPLATE_H

    有些编辑器,如Eclipse及其子代,允许您在大纲视图中按字母顺序或在页面中重新排序var和方法。