2010-06-03 3 views
6

Если у меня есть функция, вызванная из нескольких мест, и для ее выполнения требуется какое-то условие для выполнения, где это условие должно быть проверено? В моем случае это для рисования - если кнопка мыши удерживается нажатой, а затем выполнить логику рисования (это выполняется в обработчике перемещения мыши при перетаскивании.)Лучшая практика - Когда оценивать условные выражения для выполнения функции

Опция 1 говорит, что она помещается в функцию, поэтому что он будет проверен. Сказано, если хотите.

public function Foo() { 
    DoThing(); 
} 

private function DoThing() { 
    if (!condition) return; 
    // do stuff 
} 

У меня есть проблема с этим состоит в том, что при чтении кода Foo, который может быть далеко от DoThing, это выглядит как ошибка. Первая мысль состоит в том, что условие не проверяется.

Второй вариант, то есть проверить перед вызовом.

public function Foo() { 
    if (condition) DoThing(); 
} 

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

Вариант 3 состоит в том, чтобы переименовать функцию как более описательную.

public function Foo() { 
    DoThingOnlyIfCondition(); 
} 

private function DoThingOnlyIfCondition() { 
    if (!condition) return; 
    // do stuff 
} 

Действительно ли это «правильное» решение? Или это слишком далеко? Я чувствую, что если бы все было похоже на это, имена функций начали бы дублировать их код.

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

ответ

5

Согласно DRY, я бы пошел первым.

public function Foo() { 
    DoThing(); 
} 

private function DoThing() { 
    if (!condition) return; 
    // do stuff 
} 

После того, как вы привыкнете к шаблону, это не так нервирует видеть в вашем коде одинокого DoThing(). Вы начнете читать его как EnsureThingDone().

+2

Это отвечает на вопрос о структуре. Что касается названия, то немного больше мысли должно дать альтернативу, которая является подходящим описательным и не повторяющимся. Возможно, что-то в духе 'DrawOnDrag()' для 'DoThing()'. – Novelocrat

0

Я хотел бы проверить предварительные условия внутри функции,

public function DoThing() 
{ 
    ValidatePreconditions(); 
    DoWork(); 
} 

private function DoWork() 
{ 
    //Do the actual work; 
} 

Таким образом, я уверен, что все надлежащие предпосылки выполнены перед выполнением моей функции, и нет никакой необходимости для потребителя, чтобы добавить unnecesary код каждый вызывается моя функция.

0

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

Оптимальным способом сделать это было бы сделать DoThing методом экземпляра для этого объекта.

2

Вариант четыре, заверните предикат и фактический вызов в третьей функции.

function DoThing() { 
    // do stuff 
} 

function DoThingOnlyIfCondition() { 
    if (!condition) return; 
    DoThing(); 
} 

function Foo() { 
    DoThingOnlyIfCondition(); 
} 

// Foo version 2 
function FooBar() { 
    DoThing(); 
} 

Теперь Foo или любая другая функция может использовать наиболее подходящую версию DoXXX().

Смежные вопросы