Альтернативы суффиксу имени класса -Info

Я читал Чистый код Роберта С. Мартина и наткнулся на печально известное утверждение:

Избегайте таких слов, как Manager, Processor, Data или Info в названии класса.

Итак, естественно, я попытался выделить -Info из одного из имен моих классов. Теперь я видел всевозможные вопросы StackOverflow о том, что делать в случае -Manager или -Processor. Я видел комментарии, предполагающие, что они не могут придумать время, когда -Data было бы хорошим именем класса. Ну, на мой взгляд, -Data и -Info труднее выделить. Особенно, например, в классе ниже.

У меня есть класс Server, подобный следующему:

public class Server {
    //What I would call ServerInfo
    private int id;
    private String name;
    private String address;
    private int port;
    private int connections;
    private int maxConnections;
    private int status;

    //Bunch of members that aren't ServerInfo, for example:
    private ConcurrentHashMap<String, File> files = new ConcurrentHashMap<String, File>();
    private List<String> filePaths = new List<String>();
    /* ... */

    public void start() { /* ... */ }
    public void stop()  { /* ... */ }
}

На другом удаленном сервере хранится HashMap информации об этом сервере, как показано ниже:

public class ServerMap {
    ConcurrentHashMap<Integer, Server> serverMap = /* ... */;
}

Но этому HashMap нужно знать только то, что я сказал ServerInfo выше. Ему не нужно тратить память на хранение множества переменных, которые он никогда не будет использовать. Итак, для размещения этих переменных необходим класс Data.

public class ServerInfo {
    private int id;
    private String name;
    private String address;
    private int port;
    private int connections;
    private int maxConnections;
    private int status;
}

И ServerMap теперь становится ConcurrentHashMap<Integer, ServerInfo>.

Проблема в том, что это явно нарушает правило Clean Code. Я мог бы изменить -Info на какой-нибудь синоним, но разве это не решает проблему? Например, я мог бы назвать его ServerDetails, но не вижу, чем это отличается от ServerData или ServerInfo.

Я мог бы переопределить Server в другом пространстве имен и дать ему только эти члены, но это кажется еще более запутанным.

Каково лучшее решение решения этой проблемы?


person crush    schedule 30.07.2013    source источник
comment
Если группа членов, которые не являются ServerInfo, не обязательно используются, то почему вы помещаете их в Server? Можете ли вы привести больше примеров о них?   -  person Genzer    schedule 30.07.2013
comment
@Genzer Они используются Server. Они не используются картой, содержащей информацию о каждом Server. Только переменные в ServerInfo должны быть известны/сохранены ServerMap.   -  person crush    schedule 30.07.2013


Ответы (2)


Я думаю, смысл этого утверждения в том, чтобы избежать использования таких перегруженных терминов, как -Data и -Info, когда дело доходит до именования классов. Я не думаю, что неуместно использовать что-то вроде ServerDetails для объекта, который вы называете. В конце концов, это то, что они есть, не так ли?

Если ServerDetails слишком общий, спросите себя, что это за информация/подробности... В этом случае все они выглядят связанными с сетью или соединением. Как насчет ServerConnectionProperties или чего-то подобного?

Используйте рекомендации, изложенные автором именно так; методические рекомендации. Просто имейте в виду, что есть куча людей с кучей мнений, и очень немногие из них применяют 100% времени. Вы сойдете с ума, пытаясь применить каждую «лучшую практику» к письму.

person Nizzo    schedule 30.07.2013
comment
Мне это кажется очень разумным. Автор сформулировал это с такой категоричностью, что я почувствовал, что это какое-то правило, которому нужно следовать в 100% случаев — как будто в моем коде есть какой-то врожденный недостаток дизайна, поскольку я не мог найти способ ему следовать. - person crush; 30.07.2013
comment
Я не могу винить вас там. Каждый раз, когда я занимаюсь чем-то новым, я всегда копаюсь в рекомендациях «Лучшая практика», чтобы не сбиться с пути, и это приводит к большому количеству головокружений. Я пытаюсь провести какое-то исследование, выбрать путь и идти оттуда. Хотя, по общему признанию, я тоже иногда попадаю в кроличью нору. - person Nizzo; 30.07.2013
comment
Что вы думаете о ServerState или ServerSnapshot, так как это своего рода снимок/состояние Server в данный момент времени. - person crush; 30.07.2013
comment
Если это то, что он захватывает, они звучат нормально для меня. - person Nizzo; 30.07.2013

Я думаю, что вы смотрите на рефакторинг неправильно. Они правильное имя (на мой взгляд) для ServerInfo будет Server потому что это то, чем на самом деле является сервер. Когда мы имеем дело с ООП, «базовый» объект — это объект с данными. Например, мы не будем называть класс с именем пользователя, адресом электронной почты и паролем UserInfo или UserData, потому что данные подразумеваются тем фактом, что это класс с членами. Очевидно, что из этого правила есть некоторые исключения. Общепринятой практикой является наличие объекта ProfileData, содержащего некоторую менее важную информацию для Пользователей.

Есть два способа, которыми я могу думать о том, как я лично рефакторил бы эту проблему с сервером. Во-первых, я бы переименовал базу (serverInfo) в Server, а объект более высокого уровня во что-то еще, например ServerCommands (мне трудно найти подходящее имя, потому что я не знаю всего, что делает класс)

Мое следующее предложение основано на идее «обобщения». Основная причина, по которой мы не хотим называть классы, заключается в том, что это обобщает подразумеваемые аспекты программирования. Почти все классы, как правило, связаны с «информацией» и «данными». Что это за информация или данные? Я хотел бы процитировать тему SO, в которой обсуждаются рефакторинги «помощника» и «менеджера».

Причина: имя класса вроде "ThreadHelper" заставляет задуматься, зачем оно нужно и почему оно не может быть просто частью класса "Thread". Это на самом деле адаптер или декоратор? Если да, то назовите его так. Класс "Thread" уже берет на себя слишком много ответственности? Если это так, проведите рефакторинг и дайте новому классу осмысленное имя. «Помощник» ничего не говорит о том, что он делает или как помогает.

Все дело в том, какова фактическая цель классов. Если я увижу класс с именем serverInfo, я могу понять, а могу и не понять, что это за информация. Лично я бы назвал его ServerProperties. Может показаться, что это просто синоним информации, но на самом деле это более конкретно. Когда мы думаем о свойствах, мы думаем о деталях «одноразовой настройки», которые не меняются. (или если они меняются, это потому, что мы меняем настройки). Вы также можете назвать это ServerSettings, но лично мне больше нравятся свойства.

person Nick Humrich    schedule 30.07.2013
comment
Однако это не одноразовые детали настройки, которые не меняются. Например, connections будет меняться по мере поступления новых подключений. Одно свойство, которое я исключил (случайно), было status, которое говорило, находится ли сервер в сети, отключено, заблокировано, загружается и т. д. Это также изменится. Эта информация является лишь небольшой частью всего объекта Server, и именно эту информацию необходимо хранить в объекте ServerMap, а не хранить весь объект Server. Settings и Propeties оба передают контекст, отличный от намерения. Возможно, теперь вы можете предложить другие? - person crush; 30.07.2013
comment
Когда я смотрю на эти детали, то, что я бы сделал в этой ситуации (теперь, когда я вижу больше деталей), это сделать serverInfo что-то вроде BasicServer, а затем класс сервера что-то вроде ServerWithFiles или FileServer или что-то в этом роде. (или что-то, что отражает дополнительные данные, которые он содержит) Вы даже можете сделать FileServer extend BasicServer Чтобы позже вы могли создать другой класс сервера с другими расширенными членами - person Nick Humrich; 30.07.2013
comment
А затем сохранить экземпляры BasicServer в ServerMap? ServerMap находится в другом поле, поэтому экземпляры BasicServer, которые будут жить там, не будут ссылаться на экземпляр, который находится где-то еще. Вот почему важно, чтобы этот класс, содержащийся в ServerMap, содержал только необходимые данные. Сейчас я склоняюсь к тому, чтобы назвать его ServerState. Спасибо за ответ! - person crush; 30.07.2013