【问题标题】:How many variables are too much for a class?一个类有多少变量太多了?
【发布时间】:2009-01-14 16:03:44
【问题描述】:

我想看看是否有人对我正在写的课程(OOP 中的课程)有更好的设计。我们有一个将共享文件夹统计信息放入CSV 文件的脚本。我正在阅读它并将其放入 Share 课程中。

我的老板想知道如下信息:

  • 文件总数
  • 文件总大小
  • Office 文件数
  • Office 文件的大小
  • Exe 文件数
  • Exe 文件的大小
  • 等等....

我有一个类,其中包含 $numOfficeFiles、$sizeOfficeFiles 等变量以及大量的 get/set 方法。难道没有更好的方法来做到这一点吗?如果你的类有很多变量/属性,一般规则是什么?

我认为这是一个与语言无关的问题,但如果重要的话,我正在使用 PHP。

【问题讨论】:

    标签: language-agnostic oop


    【解决方案1】:

    每当我在一个类中看到超过 5 或 6 个非最终变量时,我都会感到不安。

    按照 Outlaw Programmer 的建议,他们很可能应该被安排在一个较小的班级中。它也很有可能只是放在哈希表中。

    这里有一个很好的经验法则:如果你有一个只有 setter 和 getter 的变量,那么你有 DATA,而不是代码 - 将它从你的类中取出并放入一个集合或其他东西中。

    拥有一个带有 setter 和 getter 的变量只是意味着您永远不会对它做任何事情(它是数据),或者操作它的代码在另一个类中(糟糕的 OO 设计,将变量移动到另一个类)。

    请记住——作为类成员的每条数据都是您必须编写特定代码才能访问的东西;例如,当您将其从对象传输到 GUI 上的控件时。

    我经常用名称标记 GUI 控件,这样我就可以遍历集合并自动将数据从集合传输到屏幕并返回,从而显着减少样板代码;将数据存储为成员变量会使这个过程更加复杂(需要反射)。

    【讨论】:

      【解决方案2】:

      有时,数据可能只是数据:

      files = {
         'total':  { count: 200, size: 3492834 },
         'office': { count: 25, size: 2344 },
         'exe':    { count: 30, size: 342344 },
         ...
      }
      

      【讨论】:

      • 吉米,那是什么语言?
      • 虽然我也不认识你的语言示例,但我完全同意让数据成为数据。将其放入哈希中。永远不要创建没有业务逻辑方法的类。然后你可能有一个类来操作你的数据......
      • 好吧,你抓住了我,我喜欢无缘无故地输入随机符号。删除无关的 '>' 以产生 Javascript。
      【解决方案3】:

      “一个班级应该做一件事,并且把它做好”

      如果你没有违反这条规则,那么我会说没有太多。

      视情况而定。

      如果太多是指 100 个,那么您可能希望将其分解为数据类和集合,如下面的编辑所示。

      那么你只有一个 get/set 操作,但是这种“懒惰”有利有弊。

      编辑:

      乍一看,您有成对的变量,计数和大小。 应该有另一个类,例如带有计数和类的 FileInfo,现在您的第一个类只有 FileInfo 类。

      您还可以输入文件类型,例如“全部”,“Exe”。 . .在文件信息类上。 现在父类变成了 FileInfo 对象的集合。

      就个人而言,我想我会去的。

      【讨论】:

      • 我认为变量与字典应该与对象的稀疏性相关联。如果您在一个永远不会有空白字段的类上使用字典,那么您只是在浪费空间并引入潜在的错误。在这种情况下,我会说数据不够稀疏。
      • CMartin:我自己对字典不满意,改变了答案以有一个更整洁的选择
      【解决方案4】:

      我认为答案是“没有太多变数”。

      但是,如果这些数据要保留一段时间,您可能只想将其放入数据库中,然后对数据库进行函数调用。

      我假设您不想在每次被要求时都重新计算所有这些值。

      【讨论】:

      • 肯定有太多变数之类的东西 - 参见。上帝班,cf。 stackOverflowException
      【解决方案5】:

      每个类的“最大变量”计数实际上是对相关类有意义的数据的函数。如果一个类确实有 X 个不同的值并且所有数据都是相关的,那应该是你的结构。根据所使用的语言创建可能有点乏味,但我不会说你不应该超过任何“限制”。这是由目的决定的。

      【讨论】:

        【解决方案6】:

        听起来您可能有大量重复的代码。您想要一堆不同类型的文件数和文件大小。您可以从如下所示的类开始:

        public class FileStats
        {
            public FileStats(String extension)
            {
                // logic to discover files goes here
            }
        
            public int getSize() { }
            public int getNumFiles() { }
        }
        

        然后,在你的主类中,你可以拥有一个包含所有你想要的文件类型的数组,以及这些帮助对象的集合:

        public class Statistics
        {
            private static final String[] TYPES = { "exe", "doc", "png" };
            private Collection<FileStats> stats = new HashSet<FileStats>();
        
            public static void collectStats()
            {            
                stats.clear();
                for(String type : TYPES)
                    stats.add(new FileStats(type));
            }
        }
        

        您可以通过将参数传递给 getter 方法来清理您的 API:

        public int getNumFiles(String type)
        {
            return stats.get(type).getNumFiles();
        }
        

        【讨论】:

          【解决方案7】:

          没有“硬”限制。然而,OO 设计确实有couplingcohesion 的概念。只要您的课程松散耦合且高度内聚,我相信您可以根据需要使用尽可能多的成员/方法。

          【讨论】:

            【解决方案8】:

            也许我没有理解目标,但是为什么您要使用变量将所有值加载到内存中,只是为了将它们转储到 csv 文件(何时?)。我更喜欢目录的无状态监听器并立即将值写入 csv。

            【讨论】:

            • 我的猜测是,未来老板很有可能会提出更多的需求,需要对一些业务逻辑进行编码。
            【解决方案9】:

            我总是尝试将 Class 视为我将要计算的“我的容器的名称”或“任务的名称”。类中的方法是任务的“动作”部分。

            在这种情况下,您似乎可以开始将事物组合在一起,例如您多次重复 numbersize 动作。为什么不创建一个其他类继承自的超类,例如:

            class NameOfSuperClass {
                public $type;
                function __construct($type) {
                    $this->type = $type;
                    $this->getNumber();
                    $this->getSize();
                }
                public function getNumber() {
                    // do something with the type and the number
                }
                public function getSize() {
                    // do something with the type and the size
                }
            }
            
            Class OfficeFiles extends NameOfSuperClass {
                function __construct() {
                    $this->_super("office");
                }
            }
            

            我不确定这在 PHP 中是否正确,但你明白我的意思。事情将开始变得更干净,更易于管理。

            【讨论】:

              【解决方案10】:

              就我所见:

              如果您保留一个包含所有文件名的数组,则所有这些变量都可以即时计算。

              【讨论】:

                【解决方案11】:

                这更像是一个可读性问题。

                我会将所有数据包装到一个数组中。并且只使用一对 get/set 方法。

                类似:

                class Test()
                {
                    private $DATA = array();
                
                    function set($what,$data) {
                       $DATA[$what] = $data;
                    }
                
                    function get($what) {
                        return $this->DATA[$what];
                    }
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2015-05-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多