Slide 1

Slide 1 text

Why don’t you use enum ? Masayuki IZUMI - @izumin5210 potatotips #20

Slide 2

Slide 2 text

Ƅ Rekimoto Lab. at the University of Tokyo (2008-2015: Akashi-NCT) Ɠ Enginner at Wantedly, Inc. (2014.9-2015.2: Dmetlabel, Inc.) 2

Slide 3

Slide 3 text

2 Ruby JavaScript Android Design pry(main) > izumin.skill_ratio

Slide 4

Slide 4 text

Enum

Slide 5

Slide 5 text

Enum as constants public class Status { public static final int OK = 0; public static final int ERROR = -1; }

Slide 6

Slide 6 text

public enum Status { OK, ERROR; } public class Status { public static final int OK = 0; public static final int ERROR = -1; } Enum as constants

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

* 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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

* type safe !! * Implements comparable / serializable * They are immutable / singleton Constants / Methods

Slide 23

Slide 23 text

Event handling with enum

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Example - handling click event

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

* 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

Slide 37

Slide 37 text

Why don’t you use enum ?