2012-01-24 1 views
1

Я работаю над игрой, требующей действий разрешения в зависимости от объекта, с которым сталкивается шар.Object Specifc Behavior in a If

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

Псевдокод выглядит следующим образом:

resolve (Object a) { 

if (some test) { 
    if (Object a is rect) { 
    // do one thing 
    } else { 
    // do something else thing 
} else if (another test) { 
    if (Object a is rect) { 
    // do one thing 
    } else { 
    // do something else thing 
} else if (third test) { 
    if (Object a is rect) { 
    // do one thing 
    } else { 
    // do something else thing 
} 
} 

Однако для новичка, это чувствует рода суматоху (из-за испытаний для типа объекта в пределах каждого, если условие), но я не могу достаточно выяснить, как его улучшить? Я мог бы переопределить метод и иметь поведение, основанное на подклассе, который ему передается, но затем я получаю много одинакового кода в обоих методах.

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

Может ли кто-нибудь помочь?

+0

просто уточните, вы пишете ту же логику в случае, если и еще часть там три раза? – Jayy

ответ

3

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

Теперь это также означает, что вам не нужно проверять, является ли объект прямоугольником или нет, так как это осуществляется методом, известным как двойная отправка. Когда GameObject знает, какой экземпляр класса он есть, и поэтому вызывает соответствующий метод разрешения для Visitor.

Он также помогает ремонтопригодности, как если бы вам нужно было обрабатывать другой подкласс GameObject, то вы сначала меняете интерфейс ResolveVisitor, а затем начинаете изменять конкретные реализации посетителей. Если вы случайно забудете, тогда компилятор не позволит вам скомпилировать код и указать на проблему.

Вот подробный пример шаблона посетителя:

void resolve(GameObject obj) { 
    if (first test) { 
     obj.accept(new FirstTestVisitor()); 
    } else if (second test) { 
     obj.accept(new SecondTestVistor()); 
    } else { 
     obj.accept(new DefaultVisitor()); 
    } 
} 

interface GameObject { 
    public void accept(ResolveVisitor visitor); 
} 

interface ResolveVisitor { 
    public void resolve(Rectangle rect); 
    public void resolve(GameObject obj); // default case 
} 

class Rectangle implements GameObject { 
    public void accept(Visitor visitor) { 
     visitor.resolve(this); 
     // Rectangle and its subclasses will call resolve(Rectangle) 
     // whereas all other GameObjects will call resolve(GameObject) 
     // though other GameObjects will need their own accept method 
    } 
} 

class FirstTestVisitor implements ResolveVisitor { 
    public void accept(Rectangle rect) { 
     // logic for first test and if rect goes here 
    } 
    public void accept(GameObject obj) { 
     // logic for first test and not rect goes here 
    } 
} 
0

Вы можете попробовать использовать шаблон посетителя: visitor

Или вы можете сделать это: resolve(ISomeInterface a) { a.react(ball); } РЕАКТ-метод будет определяться в каждом классе вашей иерархии классов.