Предотвращение instanceof при проверке типа сообщения

Если только необходимо сравнить схемы (не данные) и иметь доступ к Perl, mysqldiff мог бы работать. Я использовал его, потому что это позволяет Вам сравнить локальные базы данных с удаленными базами данных (через SSH), таким образом, Вы не должны потрудиться выводить любые данные.

http://adamspiers.org/computing/mysqldiff/

Это попытается генерировать SQL-запросы для синхронизации двух баз данных, но я не доверяю ему (или никакой инструмент, на самом деле). Насколько я знаю, существует номер, 100%-й надежный способ перепроектировать изменения должен был преобразовать одну схему базы данных в другого, особенно когда несколько изменений были внесены.

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

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

9
задан volker238 10 August 2009 в 03:51
поделиться

4 ответа

Простой способ избежать тестирования instanceof - это отправить полиморфно; например

public class Client {
    void messageReceived(IMessage message) {
        message.doOperations(this);
    }
}

, где каждый класс сообщений определяет соответствующий метод doOperations (Client client) .

EDIT: второе решение, которое лучше соответствует требованиям.

Альтернатива, которая заменяет последовательность 'instanceof' тесты с оператором switch:

public class Client {
    void messageReceived(IMessage message) {
        switch (message.getMessageType()) {
        case TYPE_A:
           // process type A
           break;
        case TYPE_B:
           ...
        }
    }
}

Каждый класс IMessage должен определить метод int getMessageType () для возврата соответствующего кода. Перечисления работают так же хорошо, как и int, и более элегантны, IMO.

7
ответ дан 4 December 2019 в 15:24
поделиться

Один из вариантов - цепочка обработчиков . У вас есть цепочка обработчиков, каждый из которых может обрабатывать сообщение (если применимо), а затем потреблять его, что означает, что оно не будет передано дальше по цепочке. Сначала вы определяете интерфейс Handler :

public interface Handler {
    void handle(IMessage msg);
}

И тогда логика цепочки обработчиков выглядит так:

List<Handler> handlers = //...
for (Handler h : handlers) {
    if (!e.isConsumed()) h.handle(e);
}

Затем каждый обработчик может решить обработать / обработать событие:

public class MessageAHandler implements Handler {
    public void handle(IMessage msg) {
        if (msg instanceof MessageA) {
            //process message
            //consume event 
            msg.consume();
        }
    }
}

Конечно, это не избавьтесь от instanceof s, но это означает, что у вас нет огромного блока if-elseif-else-if-instanceof , который может быть нечитаемым

5
ответ дан 4 December 2019 в 15:24
поделиться

Какой тип системы сообщений вы используете?

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

Я знаю вы можете сделать это в JMS или службе событий OSGi.

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

  String filterMsg1 = "JMSType='messageType1'";
  String filterMsg2 = "JMSType='messageType2'";

  // Create a receiver using this filter
  Receiver receiverType1 = session.createReceiver(queue, filterMsg1);
  Receiver receiverType2 = session.createReceiver(queue, filterMsg2);

  receiverType1.setMessageHandler(messageType1Handler);
  receiverType2.setMessageHandler(messageType2Handler);

Теперь каждый обработчик будет получать только определенный тип сообщения (без instanceof или if-then), конечно, при условии, что отправитель устанавливает тип посредством вызовов setJMSType () в исходящем сообщении.

Этот метод встроен в сообщение,

1
ответ дан 4 December 2019 в 15:24
поделиться
//Message.java

abstract class Message{
     public abstract void doOperations();
 }

//MessageA.java

 class MessageA extends Message{
    public void doOperations(){ 
         //do concreteMessageA operations ;
    }
 }

   //MessageB.java

class MessageB extends Message {
     public void doOperations(){ 
         //do concreteMessageB operations 
     }
}

//MessageExample.java

class MessageExample{
   public static void main(String[] args) {
        doSmth(new MessageA());
    }

    public static void doSmth(Message message) {
       message.doOperations() ;     

     }
}   
0
ответ дан 4 December 2019 в 15:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: