分解オブジェクト間を移動する機能


📌 オブジェクト間の移動機能


クラス間で機能を安全に移動したり、新しいクラスを作成したり、外部アクセスから実装の詳細を非表示にしたりする方法

移動方法


メソッドが他のクラスで自分のクラスよりも多く使用されている場合は、メソッドを最も一般的なクラスに移動します.

✔¥メリット

  • クラス内部整合性
  • クラス間の依存関係は
  • 減少する.

    フィールドの移動


    フィールドを他のクラスよりも多くのクラスに移動

    ▼▼クラス抽出(Extract Class)


    クラスが複数の操作を実行する場合、新しいクラスを作成し、関連する機能を担当するフィールドとメソッドをクラスに配置します.

    ✔¥メリット

  • 単一責任原則
  • を遵守する
  • クラスコードの方がわかりやすい
  • 信頼性が高く、他のカテゴリの変更の影響を受けません.

    単一責任の原則


    各階級には一つの責任しかない.
  • 欠点

  • 過剰使用要求類内蔵
  • 品級内建


    ロールがクラスにほとんど機能しない場合は、すべての機能を他のクラスに移動します.

    ✔¥メリット


    不要なクラス
  • を排除し、コンピュータのメインメモリ
  • を解放する.

    プロキシオブジェクトを非表示


    クライアントがオブジェクトの委任クラスを直接呼び出している場合は、サーバにメソッドを作成してプロキシオブジェクトを非表示にします.

    📃 例


    <変更前>
    class Person {
      Department _department;
      public Department getDepartment() {
        return _department;
      }
      public void setDepartment(Department arg) {
        _department = arg;
      }
    }
    
    class Department {
      private String _chargeCode;
      private Person _manager;
      public Department (Person manager) {
        _manager = manager;
      }
      public Person getManager() {
        return _manager;
      }
    }
    お客様が誰かのマネージャーを知りたい場合は、まず彼の所属部門を理解する必要があります.
    manager = john.getDepartment().getManager();
    クライアントがDepartmentクラスを発見するには、マネージャに情報を伝える方法があります.
    Personクラスで委任メソッドを作成し、クライアントにDepartmentの存在を隠すことで、マージを減らすことができます.
    getDepartment()アクセス者を削除することもできます.
    (Personクラスが部門登録とマネージャ照会のみを担当している場合)
    <変更後>
    class Person {
      Department _department;
      public void setDepartment(Department arg) {
        _department = arg;
      }
      public Person getManager() {
      	return _department.getManager();
      }
    }
    
    class Department {
      private String _chargeCode;
      private Person _manager;
      public Department (Person manager) {
        _manager = manager;
      }
      public Person getManager() {
        return _manager;
      }
    }
    すべてのクライアントがこのPersonクラスの新しいメソッドを使用できるようにします.
    manager = john.getManager();

    ✔¥メリット

  • クライアントコードがオブジェクト間の関係の詳細をあまり知らない場合、プログラムの変更は
  • より容易になります.

    欠点

  • 過剰な委任メソッドを生成すると、不要なプロキシオブジェクト
  • が生成される.

    外部メソッドの導入


    サーバクラスに必要なメソッドが含まれておらず、クラスにメソッドを追加できない場合は、クライアントクラスにメソッドを追加し、サーバクラスのインスタンスを引数としてクライアントクラスに渡します.
    <変更前>
    class Report {
      // ...
      void sendReport() {
        Date nextDay = new Date(previousEnd.getYear(),
          previousEnd.getMonth(), previousEnd.getDate() + 1);
        // ...
      }
    }
    <変更後>
    class Report {
      // ...
      void sendReport() {
        Date newStart = nextDay(previousEnd);
        // ...
      }
      private static Date nextDay(Date arg) {
        return new Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1);
      }
    }

    ✔¥メリット

  • コード重複除外
  • ゾーン拡張の導入


    サーバクラスに必要なメソッドが含まれておらず、メソッドをクラスに追加できない場合は、メソッドを含む新しいクラスを作成し、元のクラスのサブクラスまたはパッケージクラスとして研磨します.

    📃 例


    <サブクラス>
    class MfDateSub extends Date {
     // 생성자 정의
      public MfDateSub (String dateString) {
        super(dateString);
      }
    // 변환 생성자 정의
      public MfDateSub (Date arg) {
        super(arg.getTime())
      }
    //필요한 외래 메소드 정의
      Date nextDay() {
        return new Date (getYear(), getMonth(), getDate() + 1);
      }
    }
    class MfDateWrap {
      private Date _original;
    //생성자 정의
      public MfDateWrap(String dateString) {
        _original = new Date(dateString);
      }
    //변환 생성자 정의
      public MfDateWrap(Date arg) {
        _original = arg;
      }
    //기존 기능 위임 메소드
      public int getYear() {
        return _original.getYear();
      }
    //기존 기능 위임 메소드
      public boolean equals (MfDateWrap arg) {
        return (toDate().equals(arg.toDate()));
      }
    //필요한 외래 메소드 정의
      Date nextDay() {
        return new Date (getYear(), getMonth(), getDate() + 1);
      }
    }

    ✔¥メリット

  • 他のメソッドを個別の拡張クラス(サブクラスまたはRapper)に移動して、不適切なコードをクライアントクラスにバンドルしないようにします.
  • プログラムコンポーネントはより一貫性があり、
  • を再利用可能である.

    ❓ Foreign Method & Local Extension


    ソースコードを変更できない場合は、
    1、2つの方法→Foreign方法
    サブクラスまたはRapperクラス→ローカル拡張

    📑 参考資料

  • https://refactoring.guru/refactoring
  • https://wikidocs.net/book/55
  • https://ko.wikipedia.org/wiki/%EB%8B%A8%EC%9D%BC_%EC%B1%85%EC%9E%84_%EC%9B%90%EC%B9%99