Подтвердить что ты не робот

Является ли аргумент NULL плохой практикой?

Неправильная практика передавать аргумент NULL методам или, другими словами, следует ли определять методы, которые допускают аргумент NULL как допустимый аргумент.

Предположим, что мне нужен два метода 1. получить список всех компаний 2. получить список компаний на основе фильтра.

Мы можем либо иметь два метода, как ниже

    List<Company> getAllCompaniesList();
    List<Company> getCompaniesList(Company companyFilter);

или у нас может быть один метод

    List<Company> getCompaniesList(Company companyFilter);

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

Помимо вопроса о хорошей практике, практически я вижу еще одну проблему с более поздним подходом, которая объясняется ниже.

Я реализую Spring AOP, в котором я хочу иметь некоторые проверки на аргументы вроде 1. Является ли аргумент NULL? 2. представляет собой размер коллекции 0?

Есть несколько сценариев, в которых мы не можем иметь нулевой аргумент вообще как метод

    void addBranches(int companyId, List<Branch>);

Эта проверка может быть выполнена очень хорошо, используя Spring AOP, определяя метод, например следующий

@Before(argNames="args", value="execution(* *)")
void beforeCall(JoinPoint joinPoint ,Object[] args )
{ 
           foreach(Object obj in args)
           {
                 if(obj == NULL)
                 {
                     throw new Exception("Argument NULL");
                 } 
           }   
}

Но проблема я сталкивается с тем, что я определил некоторые из методов, которые должны принимать аргумент NULL для множественной функциональности одного метода, как упомянуто выше для метода List getCompaniesList (Company companyFilter); Поэтому я не могу применять AOP равномерно для всех методов, и ни одно выражение для совпадения методов не будет полезно здесь.

Пожалуйста, дайте мне знать, требуется ли дополнительная информация или проблема не достаточно описательна.

Спасибо, что прочитал мою проблему и подумал над ней.

4b9b3361

Ответ 1

Хорошо, в случаях, когда слишком много перегруженных методов. Поэтому вместо того, чтобы иметь все комбинации параметров, вы позволяете некоторым из них быть null. Но если вы это сделаете, запишите это явно с помощью

@param foo foo description. Can be null

В вашем случае у меня будут два метода, где первый вызывает второй аргумент null. Это делает API более удобным.

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


Также обратите внимание, что предпочтительный способ справиться с несколькими параметрами конструктора - через Builder. Поэтому вместо:

public Foo(String bar, String baz, int fooo, double barr, String asd);

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

Foo foo = new FooBuilder().setBar(bar).setFooo(fooo).build();

Ответ 2

Я использую очень простое правило:

Никогда не допускайте null как аргумент или возвращаемое значение для общедоступного метода.

Я использую Дополнительно и Preconditions или АОП, чтобы обеспечить соблюдение этого правила. Это решение уже спасло мне много часов исправления ошибок после NPE или странного поведения.

Ответ 3

Это обычная практика, но есть способы сделать ваш код более понятным - иногда избегая нулевых проверок или перемещая их в другом месте. Посмотрите шаблон нулевого объекта - это может быть именно то, что вам нужно: http://en.m.wikipedia.org/wiki/Null_Object_pattern?wasRedirected=true

Ответ 4

Правило: простой интерфейс, сложная реализация.

Решения о дизайне вашего API должны быть сделаны путем рассмотрения того, как клиентский код может его использовать. Если вы ожидаете увидеть

getAllCompaniesList(null);

или

if (companyFilter == null) {
    getAllCompaniesList();
} else {
    getAllCompaniesList(companyFilter);
}

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

Ответ 5

Другим подходом, который может быть работоспособен, может быть наличие интерфейса CompanyFilter с методом companyIsIncluded(Company), который принимает Company и возвращает true или false, чтобы сказать, должна ли быть включена любая компания. Company может реализовать интерфейс таким образом, чтобы поведение метода companyIsIncluded отражалось equals(), но можно было легко иметь singleton CompanyFilter.AllCompanies, метод companyIsIncluded() всегда возвращал значение true. Используя этот подход, нет необходимости передавать нулевое значение - просто передайте ссылку на AllComapnies singleton.