2016-04-11 13 views
1

У меня был толстый интерфейс:Как избавиться от приведения типов?

public interface ISolver { 
    void solve(); 
    String printMsgs();  
    boolean hasSolution();  
    int getLeaderId();  
    void add(Agent agent);  
    void add(int item);  
    void add(String item);  
    void addAll(Agent[] data);  
    void addAll(int[] data);  
    void addAll(String[] data);  
    public void initiateStartState();  
    Agent next();  
    boolean hasNext();  
    public List<Integer> getLeftSenders();  
    public List<Integer> getRightSenders();  
    public List<Integer> getCurrentLeaders();  
    Agent get(int idx);  
} 

Два класса наследуют этот интерфейс:

public class OneDirectSolver extends Solver{ 
    // some code.. 
} 

public class BiDirectSolver extends Solver{ 
    // some code.. 
} 

класса BiDirectSolver использует все методы, объявленные в ISolver, но OneDirectSolver использует только несколько методов. Я хочу следовать Принципу разделения сегрегации. Итак, я оставил в ISolver только распространенные методы. Методы, которые специфичны для BiDirectSolver я двигаться в другом интерфейсе, который проходит ISolver

public interface ISolver { 
    void solve(); 
    String printMsgs(); 
    boolean hasSolution(); 
    int getLeaderId(); 
    void add(Agent agent); 
    void add(int item); 
    void add(String item); 
    void addAll(Agent[] data); 
    void addAll(int[] data); 
    void addAll(String[] data); 
    public void initiateStartState(); 
    Agent next(); 
    boolean hasNext(); 
} 

public interface BiDirectSolvable extends ISolver { 
    public List<Integer> getLeftSenders(); 
    public List<Integer> getRightSenders(); 
    public List<Integer> getCurrentLeaders(); 
    Agent get(int idx); 
} 

Но теперь у меня есть еще одна проблема. Я пытаюсь это описать. Таким образом, у меня есть 2 клиентов BiDirectSolver и OneDirectSolver:

public class OneDirectPanel extends MyAbstractPanel { 

    private OneDirectSolvable solver; 

    public void setSolver(OneDirectSolver solver) { 
     this.solver = solver; 
    } 
    //some code.. 
} 

public class BiDirectPanel extends MyAbstractPanel { 

    private BiDirectSolvable solver; 

    public void setSolver(BiDirectSolvable solver) { 
     this.solver = solver; 
    } 
    // some code 
} 

А теперь я хочу, чтобы показать фрагмент моего основного класса, в котором я создаю экземпляры OneDirectPanel, BiDirectPanel и ISolver:

public class GUI { 
    private ISolver solver; 
    private MyAbstractPanel panelWithPicture; 
    // a lot of code.. 
    if (comboBoxForMode.getSelectedItem().equals("one direct")) { 
     solver = new OneDirectSolver(); 
     panelWithPicture = new OneDirectPanel(); 
     panelWithPicture.setSolver((OneDirectSolver)solver); 
    } else { 
     solver = new BiDirectSolver(); 
     panelWithPicture = new BiDirectPanel(); 
     panelWithPicture.setSolver((BiDirectSolvable)solver); 
    } 
} 

I видят только одно решение:

if (comboBoxForMode.getSelectedItem().equals("one direct")) { 
    OneDirectSolver solver = new OneDirectSolver(); 
    panelWithPicture = new OneDirectPanel(); 
    panelWithPicture.setSolver(solver); 
} else { 
    BiDirectSolvable solver = new BiDirectSolver(); 
    panelWithPicture = new BiDirectPanel(); 
    panelWithPicture.setSolver(solver); 
} 

Но это невозможно для меня, потому что я должен сделать некоторые actioms с решателя после того, как была создана. Я должен это делать во всех случаях. Итак, я делаю это в основном классе. Итак, в основном классе я должен объявить ссылку с типом ISolver.

UPD: Больше всего, если я делать какие-то действия с решателя в главном классе это должно повлиять на решателей в OneDirectPanel и BiDirectPanel.

ответ

3

Поскольку вы временно нужен более конкретный тип выполнения, можно назначить this.solver впоследствии:

private ISolver solver; 
... 
if (comboBoxForMode.getSelectedItem() 
        .equals("one direct")) { 
       OneDirectSolver solver = new OneDirectSolver(); 
       panelWithPicture = new OneDirectPanel(); 
       panelWithPicture.setSolver(solver); 
       this.solver = solver; 
      } else { 
       BiDirectSolvable solver = new BiDirectSolver(); 
       panelWithPicture = new BiDirectPanel(); 
       panelWithPicture.setSolver(solver); 
       this.solver = solver; 
      } 
+0

@JornVemee, извините, я забыл про одну важную деталь. Я обновил свой вопрос. –

+0

@ АлександрЕлизаров Все должно быть в порядке, это тот же объект. Вы не копируете его, назначая позже, просто ссылаясь на него. –

+0

О да! Excusme, я не замечаю строку this.solver = solver. Это работает. Большое спасибо! –

1

первую очередь вы можете поместить свой экземпляр решатель как свойство MyAbstractPanel. Таким образом, у вас есть свойство базового решателя.

public abstract class MyAbstractPanel { 

     private ISolver solver; 

     public void setSolver(ISolver solver) { 
     this.solver = solver; 
     } 

     public void someWork(){ 
     this.solver.someWork(); 
     } 
    // implement this in child class 
     public abstract void doSomeSpecificWork(); 

    } 

    //assign solver object 
    ISolver solver = new OneDirectSolver(); 

    public class BiDirectPanel extends MyAbstractPanel { 
     public void doSomeSpecificWork(){ 
      ((OneDirectSolver)solver).doSomeSpecificWork(); 
    } 
// some code 

}

поскольку решателя является атрибутом панели я думаю, что это не очень хорошая практика, чтобы держать Referance типа ISolver в главном классе. надеюсь это поможет.