2

我有一些类的实现Base,所有对象都收集在一个List<Base>.

如何action根据instanceof这些对象调用特定对象,而不必使用详细instanceof检查?如何根据这些对象的实例选择要执行的服务方法,而不必关心在哪个对象上执行操作。应该以某种方式自动选择正确的服务方法,而无需进行类型转换或实例检查。

class Base;
class Foo extends Base;
class Bar extends Base;

class Service {
    List<Base> bases;

    public void someMethod() {
        for (Base base : bases) {
            //perform some instanceof dependend action.
            //these actions cannot be inside of any Base class as it makes use of other objects too.
            if (base instanceof Foo) {
                fooService.action((Foo) base);
            }
            if (base instanceof Bar) {
                barService.action((Bar) base);
            }
        }
    }
}


//custom service methods
class FooService {
    void action(Foo foo) {
    }
}

class BarService {
    void action(Bar bar) {
    }
}
4

3 回答 3

4

多态性是一种可能性。如果 Base 类包含一个抽象 action() 方法,您可以直接调用它,无需任何 if 语句。

另一个是注册表。对于 Base 的每个子类,您可以注册到服务类的映射。在 someMethod() 中,查找注册表中的类,获取对应的服务类,并调用它。

顺便说一句,冗长并不是 instanceof 语句的唯一问题。一旦创建了 Base 的新子类,您使用这些编写的代码就会中断。满足Open/Closed 原则可以减少代码的脆弱性。

于 2013-04-01T00:32:34.677 回答
2

一种可能的解决方案是使用该Visitor模式。您需要将两个重载方法合并FooServiceBarService一个类中。action()然后你需要为accept()每个FooBar类添加一个方法,然后可以调用适当的action()方法。有关详细信息,请参阅http://en.wikipedia.org/wiki/Visitor_pattern

可能还有其他更合适的设计模式可以解决这个问题。我建议你研究它们。

于 2013-04-01T00:32:24.770 回答
0

我最接近解决这个问题的是:

class Base{};
class Foo extends Base{};
class Boo extends Base{};

额外的 BaseService 接口,因此每个服务类都使用相同的方法:

public interface BaseService<T extends Base> {

void action(T base);

}

嘘服务:

public class BooService implements BaseService<Boo> {

public void action(Boo boo){
    System.out.println("Action performed by BooService");
    }
}

食品服务:

public class FooService implements BaseService<Foo> {

public void action(Foo foo){
    System.out.println("Action performed by FooService");
    }
}

附加的 ServiceSupplier 类,它将根据传递的对象调用适当的服务:

public class ServiceSupplier {

private Map<Class<? extends Base>, BaseService> services;

public ServiceSupplier(){
    initializeServiceMap();
}

public BaseService getServiceOfType(Class<? extends Base> clazz){
    return services.get(clazz);
}

private void initializeServiceMap() {
    services = new HashMap<>();
    services.put(Foo.class, new FooService());
    services.put(Boo.class, new BooService());
    }
}

还有你的服务类:

public class Service {
List<Base> bases;
ServiceSupplier serviceSupplier;

public Service(){
    serviceSupplier = new ServiceSupplier();

    bases = new ArrayList<>(Arrays.asList(new Foo(), new Boo()));
}

public void someMethod() {
    bases.forEach(base -> serviceSupplier.getServiceOfType(base.getClass()).action(base));
    }
}

似乎只是为了删除一些“if”语句,但拥有更多服务,您需要做的就是将它们添加到 initializeServiceMap()方法中。

于 2017-02-25T23:34:17.590 回答