如何有效控制实现多接口的class对象?

How can I control the class object which implements multi interface effectively?

method:ClientProgram::deleteObject() 的目标是删除目标对象。并在删除对象之前显示对象的详细信息。

//#1. Client program which delete the target object.
public class ClientProgram {
    List<AbstractBase>list = new ArrayList<ConcreteA>();

    void deleteObject(String key) {
        for(AbstractBase obj : list){
            if(!obj.isTarget(key))continue;

            //show info and delete the object
            Msg( obj.getInfo().toString() );
            obj.delete();
            break;
        }
    }
}

当具体class从抽象基础class(如下面的#2、#3)或具有多种方法的接口扩展时是可行的。

//#2. A base abstract class for concrete classes
public abstract class AbstractBase {
    public abstract boolean isTarget(String key);
    public abstract void delete();
    public abstract void update(AbstractBase obj);
    public abstract AbstractBase getInfo();
}

//#3. A concrete class with an abstract class
public class ConcreteA extends AbstractBase {
     ....
}

但是一旦所有的方法都像#4一样被隔离到四个不同的接口中(因为应用了ISP),你只能用隔离接口中的任何一个来控制具体对象,而不能调用getInfo()和delete( ) 同时。


//#4. A concrete class with segregated interfaces
public class ConcreteA implements Delete, Update, GetInfo, Target {
    ....
}

使用像 #4 这样的 ISP class 创建像 deleteObject() 这样的方法的 best/common 实践是什么?

来自 Wikipedia page about interface segregation principle

In the field of software engineering, the interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.)

在您的情况下,您的客户确实依赖于 getInfo()delete();因此,您应该以两者都包含的粒度隔离您的界面。

另一种理解 ISP 的方式是为每个客户端构建一个接口。有时,同一个界面可供多个客户端使用,但通常一个界面会在其自身与一个客户端之间建立契约。

如果您需要使用ISP 你的版本 #4 看起来不错,但你不能用它来删除对象,

所以这是解决方案

class MyInfo {
    //some fields
}

interface Delete {
    void delete();
}

interface Info {
    MyInfo getInfo();
}

interface Update {
}

interface Target {
    boolean isTarget();
}

interface ClientProgramm extends Delete, Info, Target {

}

class ConcreteA implements ClientProgramm {

    @Override
    public void delete() {

    }

    @Override
    public MyInfo getInfo() {
        return null;
    }

    @Override
    public boolean isTarget() {
        return false;
    }
}

你所有的接口和类都是独立的,你可以将一些必要的逻辑收集到接口ClientProgramm中, 为了获得更大的灵活性,您可以将 ClientProgramm 拆分为 2 个不同的接口,例如 UpdateObjectDeleteObject