Unikanie wystąpienia podczas sprawdzania typu wiadomości

Mam następującą sytuację, w której klasa klienta wykonuje inne zachowanie w zależności od typu otrzymywanej wiadomości. Zastanawiam się, czy jest lepszy sposób na zrobienie tego, ponieważ nie podoba mi się wyrażenie instanceof i if.

Jedną z rzeczy, o których pomyślałem, było wyciągnięcie metod z klasy klienta i umieszczenie ich w wiadomościach. Umieściłbym metodę taką jak process () w interfejsie IMessage, a następnie umieścił specyficzne zachowanie komunikatu w każdym z konkretnych typów wiadomości. To sprawiłoby, że klient byłby prosty, ponieważ wywołałby po prostu message.process () zamiast sprawdzania typów. Jednak jedynym problemem jest to, że zachowanie zawarte w warunkach ma związek z operacjami na danych zawartych w klasie Client. Tak więc, jeśli zaimplementowałem metodę procesu w konkretnych klasach komunikatów, musiałbym przekazać ją klientowi i nie wiem, czy to naprawdę ma sens.

public class Client {
    messageReceived(IMessage message) {
        if(message instanceof concreteMessageA) {
            concreteMessageA msg = (concreteMessageA)message;
            //do concreteMessageA operations
        }
    }
        if (message instanceof concreteMessageB) {
            concreteMessageb msg = (concreteMessageB)message;
            //do concreteMessageB operations
        }
}