Skip to content

Instantly share code, notes, and snippets.

@mike-neck
Last active December 25, 2017 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mike-neck/c2cfa86f925b774072b7ed7084ffc6fd to your computer and use it in GitHub Desktop.
Save mike-neck/c2cfa86f925b774072b7ed7084ffc6fd to your computer and use it in GitHub Desktop.
リファクタリングカタログ1 (没)

スプラウトメソッド

  • 概要
    • 新しい機能を実現するコードを新しいメソッドとして作成して、既存コードの中で呼び出す
  • 条件
    • 新しい機能を実現するコードを追加する必要があるが、既存部分が複雑なため安易にロジックの追加ができない状態

サンプル

例: 新しい Message が作成され後にオンラインユーザー宛にデスクトップ通知を送信するコード

void notifyNewMessage(final Message message, final List<User> roomMembers) {
  final List<WebNotificationMessage> webNotificationMessages = roomMembers.stream()
      .filter(User::isOnline)
      .map(user -> new NewMessageNotification(message.title, message.text, user.session))
      .collect(toList());
  webNotifier.sendNotifications(webNotificationMessages);
}

このコードに現在オンラインではないユーザー宛にプッシュ通知を送るコードを追加する

  • プッシュ通知は pushNotifier#sendPayload(Collection<Payload>) で送信できる
  • Payload オブジェクトは User.pushArnMessage.titleMessage.text で作られる

この処理を単純に追加した場合は notifyNewMessage メソッドは次のようになる

void notifyNewMessage(final Message message, final List<User> roomMembers) {
  final List<Payload> payloads = roomMembers.stream()
      .filter(user -> !user.isOnline())
      .map(user -> new Payload(user.pushArn, message.title, message.text))
      .collect(toList());
  final List<WebNotificationMessage> webNotificationMessages = roomMembers.stream()
      .filter(User::isOnline)
      .map(user -> new NewMessageNotification(message.title, message.text, user.session))
      .collect(toList());
  pushNotifier.sendPayload(payloads);
  webNotifier.sendNotifications(webNotificationMessages);
}

このように追加すると、メソッドの内部が複雑になってくるし、テストが困難になってくるので、新たに追加する処理のみを別のメソッドに実装して、既存のコードは新規メソッドの呼び出しだけを追加する。

// 新しい機能に関する処理を新しいメソッドに実装する
void pushNotifyNewMessage(final Message message, final List<User> roomMembers) {
  final List<Payload> payloads = roomMembers.stream()
      .filter(user -> !user.isOnline())
      .map(user -> new Payload(user.pushArn, message.title, message.text))
      .collect(toList());
  pushNotifier.sendPayload(payloads);
}

void notifyNewMessage(final Message message, final List<User> roomMembers) {
  // 新しい機能のメソッド呼び出しを既存メソッドに追加する
  pushNotifyNewMessage(message, roomMembers);
  final List<WebNotificationMessage> webNotificationMessages = roomMembers.stream()
      .filter(User::isOnline)
      .map(user -> new NewMessageNotification(message.title, message.text, user.session))
      .collect(toList());
  webNotifier.sendNotifications(webNotificationMessages);
}

この方法によって、既存のメソッドにテストがなかったとしても、テストで保護できる新規機能を追加できる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment