Дизайн OO и зеркально отразил/копировал методы

Куда подзапрос должен выполнить 1 запрос для каждой возвращенной строки. Внутреннее объединение просто должно выполнить 1 запрос.

5
задан Rudi 6 December 2009 в 18:17
поделиться

6 ответов

То, что вам нужно, называется мульти-диспетчеризацией .

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

Это может быть эмулировано в основных языках ООП, или вы можете использовать его напрямую, если вы используете Common Lisp.

Java Пример в статье Википедии касается даже вашей конкретной проблемы, обнаружения столкновений.

Вот подделка на наших «современных» языках:

abstract class CollisionObject {
    public abstract Collision CheckForCollisionWith(CollisionObject other);
}

class Box : CollisionObject {
    public override Collision CheckForCollisionWith(CollisionObject other) {
        if (other is Sphere) { 
            return Collision.BetweenBoxSphere(this, (Sphere)other);
        }
    }
}

class Sphere : CollisionObject {
    public override Collision CheckForCollisionWith(CollisionObject other) {
        if (other is Box) { 
            return Collision.BetweenBoxSphere((Box)other, this);
        }
    }
}

class Collision {
    public static Collision BetweenBoxSphere(Box b, Sphere s) { ... }
}

Вот она в Common Lisp:

(defmethod check-for-collision-with ((x box) (y sphere))
   (box-sphere-collision x y))

(defmethod check-for-collision-with ((x sphere) (y box))
   (box-sphere-collision y x))

(defun box-sphere-collision (box sphere)
    ...)
3
ответ дан 14 December 2019 в 04:39
поделиться

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

Это вопрос собственности. Действительно ли класс Box владеет логикой столкновения с кругом? Почему не наоборот? Результат - дублирование кода или передача кода столкновения из круга в Box. Оба не чистые. Двойная отправка этого не решает - та же проблема с правом собственности ...

Итак, вы правы - вам нужны сторонние функции / методы, которые решают определенные коллизии, и механизм, который выбирает правильную функцию для двух сталкивающихся объектов (здесь может использоваться двойная отправка, но если количество примитивов коллизий ограничено, тогда возможно, 2D-массив функторов - более быстрое решение с меньшим количеством кода).

3
ответ дан 14 December 2019 в 04:39
поделиться

Вы не говорите, какой язык вы используете, поэтому я предполагаю, что это что-то вроде Java или C #.

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

В качестве альтернативы создайте отдельный класс CollisionDetection, который проверяет столкновения между парами объектов, и если два объекта сталкиваются, он вызывает соответствующие методы для объектов, например, bomb.explode () и player.die (). Класс может иметь большую справочную таблицу с каждым типом объекта по строкам и столбцам, а также записи, дающие методы для вызова обоих объектов.

1
ответ дан 14 December 2019 в 04:39
поделиться

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

0
ответ дан 14 December 2019 в 04:39
поделиться

Вы должны использовать checkForCollisionWith: aCollisionObject, и поскольку все ваши объекты расширяют CollisionObject, вы можете поместить туда всю общую логику.

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

0
ответ дан 14 December 2019 в 04:39
поделиться

Первый вариант: Сделать столкновение направленным. Например, если ящик неподвижен, он не проверяет свои столкновения ни с чем другим; но движущийся круг проверяет столкновение с коробкой (и другими неподвижными объектами). Это нелогично, потому что всю жизнь нас учат «равным и противоположным реакциям». Ловушка: движущиеся объекты будут дублировать столкновения с другими движущимися объектами.


Второй вариант: Дайте каждому объекту уникальный идентификационный номер. В методе проверки коллизий проверяйте коллизию только в том случае, если первый параметр / объект имеет более низкий идентификатор, чем второй параметр.

Скажем, поле имеет идентификатор = 2, а круг имеет идентификатор = 5. Тогда будет выполняться «блок сталкивается с кругом», поскольку box.id

0
ответ дан 14 December 2019 в 04:39
поделиться