Когда класс слишком большой? [закрыто]

См. проблему с расширением. В зависимости от расширения пружина может определить тип содержимого. Если ваш URL-адрес заканчивается на .com, он отправляет text / html в качестве заголовка содержимого. Если вы хотите изменить это поведение Spring, используйте приведенный ниже код:

@Configuration
@Import(HibernateConfig.class)
@EnableWebMvc
// @EnableAsync()
// @EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.azim.web.service.*",  basePackageClasses = { WebSecurityConfig.class }, excludeFilters = { @ComponentScan.Filter(Configuration.class) })
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true).useJaf(false)
                .defaultContentType(MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", MediaType.APPLICATION_JSON);
    }

    @Bean(name = "validator")
    public Validator validator() {
        return new LocalValidatorFactoryBean();
    }
}

Здесь мы устанавливаем для параметра favorPathExtension значение false и Default Content-type для Application / json. Примечание. Класс HibernateConfig содержит все компоненты.

29
задан mtgrares 2 December 2010 в 19:12
поделиться

13 ответов

Статические классы, такие как Math, могут иметь много методов. Было бы сложно разделить их.

6
ответ дан peter.murray.rust 2 December 2010 в 19:12
поделиться

Я укушу. Не делая ничего больше, чем вникать в очень мелкие края глубинных конструкций O-O, я рассмотрю несколько моих практических правил:

  1. Статические свойства весьма сомнительны. Сильно спросите себя, действительно ли они нужны.

  2. Большинство свойств / атрибутов класса должны быть частными (доступными только для экземпляра объекта) или защищенными, доступными только для экземпляра класса или производного класса (подкласса).

  3. Если свойство / атрибут класса является видимым для широкой публики, он, скорее всего, должен быть доступен только для чтения. По большей части состояние экземпляра объекта должно изменяться только при ответе на метод, который просит его сделать что-то полезное (например, вы запрашиваете, чтобы само окно перемещалось, а не явно устанавливало начало координат на координатной плоскости).

  4. Методы или свойства общедоступных методов получения / установки сомнительны, так как они в основном представляют состояние объекта (см. Пункт № 2 выше).

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

Вышесказанное должно значительно сократить общедоступный интерфейс к вашим объектам.

Наконец, если ваш объект имеет более нескольких сообщений, на которые он отвечает, у вас, вероятно, есть кандидат на рефакторинг: действительно ли это один монолитный объект или это сборка дискретных объектов? «Больше чем несколько», конечно, является очень субъективным (и контекстуальным) числом - я выброшу 10-12 в качестве разумного предела.

Надеюсь, это поможет.

Существует множество книг по проектированию, анализу и моделированию O-O.

23
ответ дан Nicholas Carey 2 December 2010 в 19:12
поделиться

Как уже говорили другие, класс слишком велик, когда он пытается сделать больше чем одно, и нарушает принцип единой ответственности .

Отличная книга на эту и другие темы (и я настоятельно рекомендую ее для любого разработчика) - Чистый код Боба Мартина.

8
ответ дан Bob Palmer 2 December 2010 в 19:12
поделиться

Общее руководство по дизайну: если первая реакция разумного человека на < набор вещей > Вероятно, это может быть "Это слишком много вещей!", тогда это слишком много вещей.

4
ответ дан Karl Knechtel 2 December 2010 в 19:12
поделиться

Первый шаг - придерживаться Принципа единой ответственности . Если вы не можете сказать в одном предложении, что делает ваш класс, то, вероятно, он делает слишком много.

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

45
ответ дан Community 2 December 2010 в 19:12
поделиться

Это все относительно, но ознакомьтесь с принципом единой ответственности:

В объектно-ориентированном программировании принцип единой ответственности гласит, что каждый объект должен иметь одну ответственность эта ответственность должна быть полностью заключена в класс

Эмпирическое правило, которое я придумал для SRP: подсчитайте количество использований / импорт / включений. Если в вашем классе более полудюжины, есть большая вероятность, что вы нарушаете SRP. Но это и относительная идея. Определенные образцы, такие как фасады, нарушают это правило по необходимости. Например. как в упрощении и сокрытии сложного подсистемы.

2
ответ дан Paul Sasik 2 December 2010 в 19:12
поделиться

Количество методов само по себе не является надежным показателем. Что, если 20 из них являются просто добытчиками имущества?

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

2
ответ дан Steve Townsend 2 December 2010 в 19:12
поделиться

Это зависит.
Если вы находитесь в Java с парами get / set для каждого поля, я не удивлюсь. Но если бы каждый из этих методов состоял из 100+ линейных зверей, это был бы запах.

0
ответ дан µBio 2 December 2010 в 19:12
поделиться

Это зависит от того, можете ли вы разделить класс на подклассы.

Редактировать: я имею в виду, что вы должны спросить себя: «Этот метод применим к этому классу или он принадлежит подклассу?»

Например,

Class Animal
  - dog_bark()
dog_bark () может быть перемещен в класс с именем Dog, а метод переименован в bark ()
0
ответ дан simshaun 2 December 2010 в 19:12
поделиться

В общем, класс должен быть разработан, чтобы делать что-то одно и делать это хорошо. Теперь, с вашим примером класса Math, он может действовать как фасад для отдельных реализаций. Или это может быть разделено на иерархию:

public abstract class Math 
{

       abstract Solve(IMathPayload);
       abstract CanSolve(IMathPayload);
}

public class LinearMath : Math {}

public class DifferentialEquasionMath: Math {}
0
ответ дан dexter 2 December 2010 в 19:12
поделиться


Об этом говорится в третьем издании «Effective C ++»:
«Предпочитать функции, не являющиеся членами, и не являющиеся друзьями». Что это означает, что вы должны держать свой класс достаточно маленьким, потому что большие классы, как правило, трудно расширять (они плохо масштабируются)

Вы также можете проверить свой класс на наличие веток. Если ваш класс содержит «if» или «switch'es», существует высокая вероятность того, что ваша классовая ответственность исчезла. Если это так, то рефакторинг и разделение обязанностей на более мелкие части могут привести к меньшим классам.

С наилучшими пожеланиями,
Марчин

0
ответ дан Marcin 2 December 2010 в 19:12
поделиться

Одной из стратегий, которой я хотел бы следовать, является создание класса Handle для каждого объекта модели данных. Поскольку дескриптор отвечает только за изменение этого объекта данных, он следует SRP. Если мне нужно создать классы вне модификации объекта данных, по крайней мере, я знаю, что большая часть кода уже соответствует SRP.

0
ответ дан Bjt1776 2 December 2010 в 19:12
поделиться

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

НО:

Когда дело доходит до программирования, вам никогда не нужно больше 40+ методов в одном классе, и их нужно разделить на эти энтиты.

Например,

class HTTP
{
    /*
        * Base functions for HTTP Fetching / transferring / Sending
        * so when it comes to single responsibility this would be the the fetch / set in HTTP
    */
}

, тогда вы будете более конкретны со своими подклассами, такими как

class YoutubeUploader extends HTTP
{
    /*
        * This class is responsible for uploading to youtube only
     */
}

class YoutubeDownload extends HTTP
{
    /*
        * This class is responsible for downloading to youtube only
     */
}

class CronRunner extends HTTP
{
    /*
        * This class is responsible for Running your HTTP Cron Tasks
     */
}

нет, если у вас нет этого базового HTTP-класса, вам придется определять методы в все три подкласса для передачи данных по протоколу HTTP.

Разделение ваших классов на отдельные обязанности дает более структурированную структуру, приводящую к меньшему количеству кода и большему результату.

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

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

class User
{
    public function getUsername()
    {
        return $data['username']; 
    }

    public function getPermissions()
    {
        return $data['permissions'];
    }

    public function getFirstname()
    {
        return $data['firstname']; 
    }
}

, в действительности это не нужно, когда вы можете сделать:

class User
{
    public function __call($method,$params = array())
    {
        if(substr(0,3,$method) == "get")
        {
            $var_name = substr(3,strlen($method),$method);
            return $data[$var_name];
        }
    }
}

Это займет автомобиль любого метода. Вызванный, который начинается с 'get', он берет последнюю часть строки и ищет массив.

0
ответ дан RobertPitt 2 December 2010 в 19:12
поделиться