Являются ли аргументы NULL плохой практикой? - PullRequest
18 голосов
/ 26 декабря 2010

Является ли плохой практикой передавать аргумент 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 одинаково для всех методов, и ни одно из выражений для соответствия имени метода не будет здесь полезным.

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

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

Ответы [ 5 ]

18 голосов
/ 26 декабря 2010

Это хорошо, если слишком много перегруженных методов. Таким образом, вместо того, чтобы иметь все комбинации параметров, вы позволяете некоторым из них быть 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();
16 голосов
/ 23 января 2013

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

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

Я использую Необязательно и Предварительные условия или AOP для обеспечения соблюдения этого правила.Это решение уже спасло меня от многих часов исправления ошибок после NPE или странного поведения.

6 голосов
/ 26 декабря 2010

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

3 голосов
/ 26 декабря 2010

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

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

getAllCompaniesList(null);

или

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

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

0 голосов
/ 24 января 2013

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

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