Когда класс слишком долго?

Когда функция слишком долго? подмножество этого вопроса, я думаю.

Каковы несколько хороших метрик для определения, что класс является слишком длинным?

Я повторно пересматриваю ряд приемных инструкций по коду для проекта с внешними подрядчиками и понял, что не покрыл это в прошлом, но должен покрыть это в будущем.

22
задан Community 23 May 2017 в 12:34
поделиться

6 ответов

Когда на нем больше одной ответственности.

Позвольте мне процитировать здесь Чистый код Роберта К. Мартина :

Первое правило классов - они должны быть небольшими. Второе правило классов - они должны быть меньше этого. ... С помощью функций мы измеряли размер путем подсчета физических линий. С классами мы используем другую меру. Считаем обязанности. [Глава 10, страница 136]

63
ответ дан 29 November 2019 в 03:21
поделиться

Это способ получения списка контактов из перечислять контактов в обмен с помощью EWS. Я еще не уверен, как получить контакты из глобального списка, только посмотрел на API час назад.

private static void ListContacts(ExchangeService svc) {
    foreach (var v in svc.FindItems(WellKnownFolderName.Contacts,
                                    new ItemView(20))) {
        Contact contact = v as Contact;
        ContactGroup contactGroup = v as ContactGroup;

        //v.Load(); // Turns out you don't need to load for basic props.
        if (contact != null) {
            Console.WriteLine("Contact: {0} <{1}>",
                contact.DisplayName,
                contact.EmailAddresses[EmailAddressKey.EmailAddress1]);
        } else if (contactGroup != null) {
            Console.WriteLine("Contact Group: {0}", contactGroup.DisplayName);
            switch (svc.RequestedServerVersion) {
                case ExchangeVersion.Exchange2007_SP1:
                    ExpandGroupResults groupResults
                        = svc.ExpandGroup((contactGroup.Id));
                    foreach (var member in groupResults) {
                        Console.WriteLine("+ {0} <{1}>",
                            member.Name, member.Address);
                    }
                    break;
                case ExchangeVersion.Exchange2010:
                    foreach (GroupMember member in contactGroup.Members) {
                        Console.WriteLine("+ {0} <{1}>",
                        member.AddressInformation.Name,
                        member.AddressInformation.Address);
                    }
                    break;
                default:
                    Console.WriteLine(
                        "** Unknown Server Version: {0}",
                        svc.RequestedServerVersion);
                    break;
            }
        } else {
            Console.WriteLine("Unknown contact type: {0} - {1}",
                contact.GetType(), v.Subject);
        }
    }
}

Я решил создать службу для многословия, ознакомьтесь с API веб-служб Exchange для получения дополнительной информации.

-121--1858916-

Сложность разветвления класса : Число других классов, на которые опирается данный класс. Также было показано, что квадрат этого указывает на объем обслуживания, требуемый в функциональных программах (на основе файла), по меньшей мере.

Цикломатическая сложность : проверка цикломатической сложности по указанному пределу. Сложность измеряется количеством операторов if, while, do, for,?:, catch, switch, case и операторов & & и | (плюс один) в теле конструктора, метода, статического инициализатора или инициализатора экземпляра. Это мера минимального количества возможных путей через источник и, следовательно, количества необходимых тестов. Как правило, 1-4 считается хорошим, 5-7 ок, 8-10 рассмотреть рефакторинг, и 11 + повторный фактор сейчас!

17
ответ дан 29 November 2019 в 03:21
поделиться

У одного класса должна быть только одна ответственность. Это лучшая мера, чем длина. Итак, при разработке кода каждая единица вашего дизайна (тип или класс) должна нести ответственность только за одну вещь (какая бы «одна вещь» ни была в вашем случае). Если вы сохраните все так просто, как возможно, вы не попадете в беспорядок.

4
ответ дан 29 November 2019 в 03:21
поделиться

Не более 17 строк. Ни больше ни меньше. Так что, если меньше 17 строк, возврат каретки сделает свое дело. Если его больше 17, вам нужно будет начать вызывать другие функции из самой функции.

Например:

public function myFunction() {
...
line 17: myFunctionPart2();
}

public function myFunctionPart2() {
...
line 17: myFunctionPart3();
}

И так далее.

Это довольно стандартная практика программирования.

9
ответ дан 29 November 2019 в 03:21
поделиться

Когда вы думаете, что теперь вам стало труднее управлять этим, и вы застреваете.

1
ответ дан 29 November 2019 в 03:21
поделиться

Да, это раздражает. Вы можете использовать strdup для его сокращения:

char *p = strdup("hello");
printf("p is %s \n",p);
-121--4557578-

См. также вопрос: Остановить выполнение JavaScript без блокировки браузера

Делать именно то, что вы хотите, не работает. Нельзя создавать синхронность из асинхронности (только наоборот!) в однопоточной среде, управляемой событиями. Вы должны принять асинхронный характер языка и разработать свой собственный согласованный стиль обработки обратных вызовов, чтобы ваш код был читаемым/поддерживаемым. Можно, например, выбрать, чтобы никогда не выполнять реальную работу внутри закрытия обратного вызова, а просто вызвать другую функцию/метод верхнего уровня для ясности.

-121--3842593-

Игнорируя используемую схему проектирования, я бы рассмотрел объем ответственности, который выполняет класс. Если объем слишком велик, его следует разбить на конкретные сферы ответственности, абстрагировать или сделать более общим.

Я бы не стал брать количество строк как значимую метрику.

2
ответ дан 29 November 2019 в 03:21
поделиться