Сколько переменных слишком много для класса? - PullRequest
4 голосов
/ 14 января 2009

Я хочу посмотреть, есть ли у кого лучший дизайн для класса (класс, как в ООП ), который я пишу. У нас есть скрипт, который помещает статистику общих папок в файл CSV . Я читаю это и помещаю в класс Share.

Мой босс хочет знать такую ​​информацию, как:

  • Общее количество файлов
  • Общий размер файлов
  • Количество файлов Office
  • Размер офисных файлов
  • Количество исполняемых файлов
  • Размер Exe файлов
  • и т.д ....

У меня есть класс с переменными, такими как $ numOfficeFiles, $ sizeOfficeFiles и т. Д., С множеством методов get / set. Разве нет лучшего способа сделать это? Каково общее правило, если у вас есть класс с большим количеством переменных / свойств?

Я считаю это вопросом, не зависящим от языка, но если это имеет значение, я использую PHP.

Ответы [ 11 ]

8 голосов
/ 14 января 2009

Иногда данные могут быть просто данными:

files = {
   'total':  { count: 200, size: 3492834 },
   'office': { count: 25, size: 2344 },
   'exe':    { count: 30, size: 342344 },
   ...
}
8 голосов
/ 14 января 2009

Всякий раз, когда я вижу более 5 или 6 не финальных переменных в классе, я начинаю беспокоиться.

Скорее всего, их следует поместить в меньший класс, как это было предложено Outlaw Programmer. Также есть хороший шанс, что он может быть просто помещен в хеш-таблицу.

Вот хорошее эмпирическое правило: если у вас есть переменная, в которой нет ничего, кроме установщика и получателя, у вас есть ДАННЫЕ, а не код - вытащите их из своего класса и поместите в коллекцию или что-то в этом роде.

Наличие переменной с установщиком и получателем просто означает, что либо вы ничего не делаете с ней (это данные), либо код, управляющий ею, находится в другом классе (ужасный дизайн ОО, переместите переменную в другой класс).

Помните - каждый фрагмент данных, который является членом класса, - это то, что вам нужно будет написать определенный код для доступа; например, когда вы переносите его из объекта в элемент управления в графическом интерфейсе.

Я часто помечаю элементы управления графическим интерфейсом именем, чтобы можно было перебирать коллекцию и автоматически переносить данные из коллекции на экран и обратно, что значительно сокращает стандартный код; хранение данных в качестве переменных-членов значительно усложняет этот процесс (требует отражения).

3 голосов
/ 14 января 2009

«Класс должен делать одно и делать хорошо»

Если вы не нарушаете это правило, то я бы сказал, что их не так уж много.

Однако это зависит.

Если вы слишком много имеете в виду 100, то вы можете разбить его на класс данных и коллекцию, как показано в редактировании ниже.

Тогда у вас есть только одна операция получения / установки, однако есть плюсы и минусы этой "ленивости".

EDIT:

На второй взгляд, у вас есть пары переменных, Count и Size. Должен быть другой класс, например FileInfo с подсчетом и классом, теперь у вашего первого класса только классы FileInfo.

Вы также можете указать тип файла, например, «Все», «Отлично». , , в классе File Info. Теперь родительский класс становится коллекцией объектов FileInfo.

Лично я думаю, что пошел бы на это.

1 голос
/ 14 января 2009

Похоже, у вас может быть тонна повторяющегося кода. Вам нужно количество файлов и размер файлов для разных типов. Вы можете начать с класса, который выглядит следующим образом:

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));
    }
}

Вы можете очистить свой API, передав параметр методу получения:

public int getNumFiles(String type)
{
    return stats.get(type).getNumFiles();
}
1 голос
/ 14 января 2009

Число «максимальных переменных» каждого класса действительно зависит от того, какие данные имеют смысл для рассматриваемого класса. Если для класса действительно X различных значений и все данные связаны, это должна быть ваша структура. Это может быть немного утомительно в зависимости от используемого языка, но я бы не сказал, что есть какой-то «предел», который вы не должны превышать. Это продиктовано целью.

1 голос
/ 14 января 2009

Я думаю, что ответ «нет такой вещи, как слишком много переменных».

Но затем, если эти данные будут храниться некоторое время, вы можете просто поместить их в базу данных и выполнить вызовы своих функций в базе данных.

Полагаю, вы не хотите пересчитывать все эти значения каждый раз, когда вас просят об этом.

0 голосов
/ 14 января 2009

Я всегда пытаюсь представить класс как «имя моего контейнера» или «имя задачи», которое я собираюсь вычислить. Методы в классе являются «действиями» частью задачи.

В этом случае кажется, что вы можете начать группировать вещи, например, вы много раз повторяете действия number и size Почему бы не создать суперкласс, от которого наследуются другие классы, например:

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, но вы меня поняли. Вещи начнут выглядеть намного чище и лучше управляться.

0 голосов
/ 14 января 2009

Это скорее проблема читабельности.

Я бы обернул все данные в массив. И используйте только одну пару методов get / set.

Что-то вроде:

class Test()
{
    private $DATA = array();

    function set($what,$data) {
       $DATA[$what] = $data;
    }

    function get($what) {
        return $this->DATA[$what];
    }
}
0 голосов
/ 14 января 2009

Может быть, я не понял цели, но почему вы загружаете все значения в память, используя переменные, просто чтобы выгрузить их в файл csv (когда?). Я бы предпочел прослушиватель без сохранения состояния в каталог и немедленную запись значений в CSV.

0 голосов
/ 14 января 2009

Как раз из того, на что я взглянул:

Если вы сохраняете массив со всеми именами файлов, все эти переменные могут быть вычислены на лету.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...