jeudi 12 septembre 2019

Cleanest pattern for filtering objects of unknown type?

I have an application that takes json objects from a queue, deserializes them to a model, applies a list of filters, and sends the objects that pass all filters through to another queue.

The two complicating criteria are:

  1. The set of filters is determined and injected via Spring profile.
  2. The type of object that the json is being deserialized to is also determined the by the Spring profile.

The following solution is ugly because it involved casting:

public class MessageTypeOne {

    public int someField;
}

public class MessageTypeTwo {

    public int otherField;
}

public interface MessageFilter {

    boolean doesFilterPass(Object object);
}

@Component
@Profile("ProfileOne")
public class OneOfMyMessageFilters implements MessageFilter {

    public boolean doesFilterPass(Object object) {
        MessageTypeOne message = (MessageTypeOne)object;

        if (message.someField == something) {
            return false;
        } else return true;
    }
}

@Component
@Profile("ProfileTwo")
public class AnotherOneOfMyMessageFilters implements MessageFilter {

    public boolean doesFilterPass(Object object) {
        MessageTypeTwo message = (MessageTypeTwo)object;

        if (message.otherField == something) {
            return false;
        } else return true;
    }
}

@Service
public class MessageFilterService {

    // injected at runtime via Spring profile
    private Set<MessageFilter> messageFilters

    @AutoWired
    public MessageFilterService(Set<MessageFilter> messageFilters) {
        this.messageFilters = messageFilters;
    }

    public boolean passesAllFilters(Object object) throws IOException {
        for (MessageFilter filter : messageFilters) {
            if (!filter.doesFilterPass(object)) {
                return false;
            }
        }

        return true;
    }
}

What's the cleanest pattern for cases like these? I've read about the visitor pattern but I'm not sure that's any better than casting like this.

Aucun commentaire:

Enregistrer un commentaire