javaooppolymorphisminterface-segregation-principle

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


The goal of the method:ClientProgram::deleteObject() is to delete the target object. And it shows the detail info of the object before deleting it.

//#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;
        }
    }
}

It is feasible when the concrete class extends from the abstract base class (like below #2,#3) or an interface with multi methods.

//#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 {
     ....
}

But once all the methods are segregated into four different interface like #4 (as the ISP is applied), you can only control the concrete object with either one of the segregated interface and cannot call getInfo() and delete() at the same time.


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

What is the best/common practice for creating a method like deleteObject() using the ISPed class like #4?


Solution

  • if you need to use ISP your version #4 looks good , but you cannot use it to deleteObject ,

    so here is solution

    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;
        }
    }
    

    all your interfaces and classes are independent , and you can collect some necessary logic into interface ClientProgramm , for more flexibility you can split ClientProgramm to 2 different interfaces like UpdateObject and DeleteObject