如何在运行时更改对象引用(设计模式)

时间:2018-04-01 23:38:13

标签: java design-patterns

该应用程序是基于文本的星巴克模拟器。

Image

我面临的问题是如何根据(x, y)值更改对屏幕的引用。

我正在寻找一个解决方案,让屏幕负责根据x和y值更改为下一个屏幕。

以下是应用程序的第三层,其初始屏幕为MyCards

public class Frame implements IFrame {

     private IScreen current = new MyCards();

     /* Most code are taken out because not relevant */

     public void touch(int x, int y){ 
         if(current!= null){ current.touch(x, y)}

     }

}

如果我致电frame.touch(3,3),它应该将引用更改为我称之为MyCardsPay的新屏幕。

以下是interface我致电IScreen

public interface IScreen
{

    void touch(int x, int y) ;              // send touch events to screen
    String display() ;                      // displays screen components
    String name() ;                         // returns name of screen
    void next() ;                           // navigate to next screen
    void prev() ;                           // navigate to previous screen
    void setNext(IScreen s, String n ) ;    // set next screen with action name
    void setPrev(IScreen s, String n ) ;    // set previous screen with action name

}

这是我的基类,我称之为Screen

public class Screen implements IScreen {


    public Screen(){

    }

    @Override
    public void touch(int x, int y) {

    }

    @Override
    public void next() {
        // add code here

    }

    @Override
    public void prev() {
        // add code here
    }

    @Override
    public void setNext(IScreen s, String n ) {
        // add code here 
    }

    @Override
    public void setPrev(IScreen s, String n )  {
        // add code here
    }    


    @Override
    public String display() { 
        return ""; 
    }


    @Override
    public String name() {
        return (this.getClass().getName()).split("\\.")[1] ; 
    }

}

这是我的MyCard课程:

public class MyCards extends Screen {

    private Double price;

    public MyCards() {

    }

    public void setPrice(Double p){
        price = p;
    }

    @Override
    public String display(){
        return getPriceDescription() + super.display();
    }

    public String getPriceDescription(){
        NumberFormat formatter = NumberFormat.getCurrencyInstance();
        return formatter.format(price);
    }
}

这是我的MyCardsPay课程:

public class MyCardsPay extends Screen
{

    String cardID;

    public MyCardsPay()
    {

    }

    public void setCardID(String c){
        cardID = c;
    }

    @Override
    public String display(){
        if(cardID == null){
            return super.display();
        }
        return "[" + cardID + "]" + "\n\n\n" + "Scan Now";
    }


}

2 个答案:

答案 0 :(得分:1)

如果我没有出错,您是按current类的Frame字段存储当前屏幕,并且您想要通过Frame.touch()方法更改屏幕参考?< / p>

在这种情况下,我建议touch(在IScreen中,在MyCardsMyCardsPay中)返回非空,但touch()的{​​结果屏幕' 1}}。并按Frame.current存储结果。

也就是说,Frame喜欢:

public class Frame implements IFrame {

     private IScreen current = new MyCards();

     /* Most code are taken out because not relevant */

     public void touch(int x, int y){ 
         if(current!= null){ current = current.touch(x, y)}    
     }    
}

Screen就像:

public class MyCards extends Screen {

    @Override
    public IScreen touch(int x, int y) {
        if(isOnThePayButton(x, y)){
            return new MyCardsPay();
        }
    }
}

答案 1 :(得分:-1)

一种好方法是使用观察者模式。让Screen告诉Frametouch方法上更新哪个屏幕。

使用interface进行通信。

public interface IScreenFlowObserver {
    void switched(String screen, String n);
}

拥有框架implement

public class Frame implements IFrame, IScreenFlowObserver{

  /* More code*/

    public void switched(String screen, String n){ /* */

    }

}

然后将基类更改为:

  public class Screen implements IScreen{
         IScreenFlowObserver observer; 

         public void setObserver(IScreenFlowObserver o){
              observer = o;
        }

   }

最后,设置ScreenFactory来创建屏幕。

使用这种简单的设计模式,Screen类可以告诉Frame切换到谁。这允许让if statments