Why don't you use enum ?

Why don't you use enum ?

【第20回】potatotips(iOS/Android開発Tips共有会) 発表資料 http://connpass.com/event/17624/

9eed44f137609e6ce3b6f1e14f80b9e1?s=128

Masayuki Izumi

August 11, 2015
Tweet

Transcript

  1. Why don’t you use enum ? Masayuki IZUMI - @izumin5210

    potatotips #20
  2. Ƅ Rekimoto Lab. at the University of Tokyo (2008-2015: Akashi-NCT)

    Ɠ Enginner at Wantedly, Inc. (2014.9-2015.2: Dmetlabel, Inc.) 2
  3. 2 Ruby JavaScript Android Design pry(main) > izumin.skill_ratio

  4. Enum

  5. Enum as constants public class Status { public static final

    int OK = 0; public static final int ERROR = -1; }
  6. public enum Status { OK, ERROR; } public class Status

    { public static final int OK = 0; public static final int ERROR = -1; } Enum as constants
  7. Example - Enum as constants public void onSomethingAction(int status) {

    switch (status) { case Status.OK: Log.d(TAG, "status: OK"); break; case Status.ERROR: Log.d(TAG, "status: ERROR"); break; } }
  8. Example - Enum as constants public void onSomethingAction(int status) {

    switch (status) { case Status.OK: // => int Log.d(TAG, "status: OK"); break; case Status.ERROR: // => int Log.d(TAG, "status: ERROR"); break; } }
  9. Example - Enum as constants public void onSomethingAction(Status status) {

    Log.d(TAG: "status: " + status.name()); }
  10. Example - Enum as constants public void onSomethingAction(Status status) {

    Log.d(TAG: "status: " + status.name()); } \ enum /
  11. * type safe ! - "int enum pattern" is fragile

    - Add/Remove a new item easliy * Prefixes of names are unnecessary - Because each enum types has its own namespace Enum as constants
  12. Enum that has member constants/methods public enum Status { OK("Succeed

    the process!"), ERROR("Error has occurred..."); private final String message; Status(String message) { this.message = message; } private String getMessage() { return message; } }
  13. Enum that has member constants/methods public enum Status { OK("Succeed

    the process!"), ERROR("Error has occurred..."); private final String message; Status(String message) { this.message = message; } private String getMessage() { return message; } }
  14. Enum that has member constants/methods public enum Status { OK("Succeed

    the process!"), ERROR("Error has occurred..."); private final String message; Status(String message) { this.message = message; } private String getMessage() { return message; } }
  15. Example - Enum that has member constants/methods public void onSomethingAction(int

    status) { switch (status) { case Status.OK: Log.d(TAG, "Succeed the process!"); break; case Status.ERROR: Log.d(TAG, "Error has occurred..."); break; } }
  16. Example - Enum that has member constants/methods public void onSomethingAction(Status

    status) { Log.d(TAG, status.getMessage()); }
  17. Example - Enum that has member constants/methods public void onSomethingAction(Status

    status) { Log.d(TAG, status.getMessage()); } \ enum /
  18. Constant-specific method implementations public enum Status { OK("Succeed the process!")

    { @Override void log(String tag) { Log.d(tag, message); } }, ERROR("Error has occurred...") { @Override void log(String tag) { Log.e(tag, message); } }; // ... abstract void log(String tag); }
  19. Constant-specific method implementations public enum Status { OK("Succeed the process!")

    { @Override void log(String tag) { Log.d(tag, message); } }, ERROR("Error has occurred...") { @Override void log(String tag) { Log.e(tag, message); } }; // ... abstract void log(String tag); }
  20. Constant-specific method implementations public enum Status { OK("Succeed the process!")

    { @Override void log(String tag) { Log.d(tag, message); } }, ERROR("Error has occurred...") { @Override void log(String tag) { Log.e(tag, message); } }; // ... abstract void log(String tag); }
  21. Constant-specific method implementations public enum Status { OK("Succeed the process!")

    { @Override void log(String tag) { Log.d(tag, message); } }, ERROR("Error has occurred...") { @Override void log(String tag) { Log.e(tag, message); } }; // ... abstract void log(String tag); }
  22. * type safe !! * Implements comparable / serializable *

    They are immutable / singleton Constants / Methods
  23. Event handling with enum

  24. Example - handling click event public void onClick(View v) {

    swtich(v.getId()) { case R.id.button1: // do something... break; case R.id.button2: // do something... break; // ... } }
  25. Example - handling click event

  26. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { @Override public void handle(Context context) { /* ...*/ } }, BUTTON2(R.id.button2) { @Override public void handle(Context context) { /* ...*/ } }; // ... abstract public void handle(Context context); }
  27. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { @Override public void handle(Context context) { /* ...*/ } }, BUTTON2(R.id.button2) { @Override public void handle(Context context) { /* ...*/ } }; // ... abstract public void handle(Context context); }
  28. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { @Override public void handle(Context context) { /* ...*/ } }, BUTTON2(R.id.button2) { @Override public void handle(Context context) { /* ...*/ } }; // ... abstract public void handle(Context context); }
  29. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { /* ... */ }, BUTTON2(R.id.button2) { /* ... */ }; // ... public static ClickEventHandler valueOf(int resId) { for (ClickEventHandler handler : values()) { if (handler.getResId() == resId) { return handler; } } throw new IllegalArgumentException(); } }
  30. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { /* ... */ }, BUTTON2(R.id.button2) { /* ... */ }; // ... public static ClickEventHandler valueOf(int resId) { for (ClickEventHandler handler : values()) { if (handler.getResId() == resId) { return handler; } } throw new IllegalArgumentException(); } }
  31. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { /* ... */ }, BUTTON2(R.id.button2) { /* ... */ }; // ... public static ClickEventHandler valueOf(int resId) { for (ClickEventHandler handler : values()) { if (handler.getResId() == resId) { return handler; } } throw new IllegalArgumentException(); } }
  32. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { /* ... */ }, BUTTON2(R.id.button2) { /* ... */ }, UNKNOWN(-1) { @Override public void handle(Context context) {} }; // ... public static ClickEventHandler valueOf(int resId) { for (ClickEventHandler handler : values()) { if (handler.getResId() == resId) { return handler; } } return UNKNOWN; } }
  33. Example - handling click event public enum ClickEventHandler { BUTTON1(R.id.button1)

    { /* ... */ }, BUTTON2(R.id.button2) { /* ... */ }, UNKNOWN(-1) { @Override public void handle(Context context) {} }; // NULL Object pattern // ... public static ClickEventHandler valueOf(int resId) { for (ClickEventHandler handler : values()) { if (handler.getResId() == resId) { return handler; } } return UNKNOWN; } }
  34. Example - handling click event public void onClick(View v) {

    ClickEventHandler.valueOf(v.getId()).handle(this); }
  35. Example - handling click event public void onClick(View v) {

    ClickEventHandler.valueOf(v.getId()).handle(this); }
  36. * Delegates event handling from controller - We can avoid

    fat controller !!!! * Improves testability - Because they are referentially transparent (?) * Other usecases - BLE (BluetoothGattCharacteristic), HTTP response, etc. Event handling with enum
  37. Why don’t you use enum ?