2020年4月3日 星期五

for java,值為string type的 enum 類別

一般如果是用string做值的enum,比較直接是寫在interface
---------------------
 interface PlayserStatus {
    public final static String PLAY="play";
    public final static String STOP="stop";
}

class Player {
   String  _status;
   Player(String status){
       _status=status;
   }
....
....
}
然後再用
  var player=new Player(PlayserStatus.PLAY);

---------------------
問題是這樣就無法限制Player的建構元一定是要在PLAY/STOP這樣的範圍,太危險了
所以還是enum寫法比較安全
--------------.
enum  PlayerStatus {
     AXN_INIT("init"),
     AXN_PLAY("Play"),
     AXN_PAUSE("Pause"),
     AXN_FINISH("Finshed");

    private final String value;
    private PlayerStatus(String s) {
        value = s;
    }
    public String toString(){
        return value;
    }

}
class Player {
    private  PlayerStatus xntStatus;
    public Player(PlayerStatus status) {
        xntStatus=status;
    }
    @Override    public void setStatus(PlayerStatus s) {
        xntStatus=s;
    }
    @Override    public String getStatus() {
        return xntStatus.toString();
    }
}
....
...
 public void main(String[] args){
  ...  
   ...
   ...
   var player=new Player(PlayerStatus.AXN_INIT);
   System.out.println("status is "+player.getStatus());
   player.setStatus(PlayerStatus.AXN_PLAY);
   System.out.println("status is "+player.getStatus());
   ....
 }
----------------------------------------------------
這樣就可以更具體限制了
有關java enum 類型的更完整的介紹,請參考以下更精闢的好文
https://tpu.thinkpower.com.tw/tpu/articleDetails/1432

同場加映!!
如果是要切換狀態時的行為,不是在player裡大改, 而是由playerStatus決定呢?
------------原班人馬,加個狀態表------------------------------
//先定義行為
interface PlayerIsDoing{
  void doing();
}
class InitPlayer implements PlayerIsDoing{
    public void doing(){
        System.out.println("Doing Init Now");
    }
}
class PlayingPlayer implements PlayerIsDoing{
    public void doing(){
        System.out.println("Playing Now");
    }
}
//再定義行為對映表,順便了解一下直接給值的HashMap的寫法
class HtLolder{
  static PlayerIsDoing p1=new InitPlayer();
  static PlayerIsDoing p2=new  PlayingPlayer();
  static Map<String,PlayerIsDoing> ht=new HashMap<String,PlayerIsDoing>(){
      {
          put("init",p1);
          put("Play",p2);
      }
    };
 }
//改一下enum類別
enum  PlayerStatus {
      
      AXN_INIT("init"),
      AXN_PLAY("Play");
      Map<String,PlayerIsDoing>  ht=HtLolder.ht;
     private final String value;
     private PlayerStatus(String s) {
         value = s;
     }
     public String toString(){
         return value;
     }
     //重點來了!!
     public  void doPlaying(){
         ht.get(value).doing(); <-----------
     }

 }
class Player implements PlayerAction{
    private  PlayerStatus xntStatus;
    public Player(PlayerStatus status) {
        xntStatus=status;
    }
    @Override    public void setStatus(PlayerStatus s) {
        xntStatus=s;
    }
    @Override    public String getStatus() {
        xntStatus.doPlaying();<-----------
        return xntStatus.toString();
    }
}

//it's show time!!
public static void main(String[] args) throws IOException {
    var player=new Player(PlayerStatus.AXN_INIT);
    System.out.println("status is "+player.getStatus());
    player.setStatus(PlayerStatus.AXN_PLAY);
    System.out.println("status is "+player.getStatus());
    ...
    ....
}
--------------------------------------------------------------
這樣,有新行為,player不用改(小改啦),把新行為放在PlayerStatus跟行為對映表所在的套件中
會比較靈活些吧
大家加油吧!!



沒有留言:

張貼留言