1

私は、外部サービスに接続することを知っている大きなコード(レガシー)を持っています。たとえば、Skypeに接続してその可用性を実現する方法です(これは、例のために機能する方法です)。は

SkypeAvailabilityManager.java

.init
.start
.stop
.connect
.disconnect
.keepAlive
.updateStatus

(例として、すべてのメソッドがパブリックである必要があり、誰かがそれらを呼び出すと仮定しましょう)。これで、巨大なコード(上記のすべてのメソッドを呼び出す巨大なレガシーコード)ができました。

今、私はスカイプまたは他のサービスと同期する必要がありますMessengerB

ただし、me​​ssengerBでは、init、start、connectなどは必要ありません。必要なのは、updateStatusメソッドだけです。

だから私はこのリファクタリングについて考えました(それはまだ私にはうまく聞こえませんが、理由を説明します

Interface: ExternalStatusFetcher

それの方法:

.updateStatus

これで、レガシーコードは上記の.init .start .stop .connectメソッドを多くの場所で呼び出しますが、追加する必要がある新しいMessengerStatusUpdaterImplは.updateStatusのみが必要であり、skype実装の.updateStatusを再利用したいのでコードを再利用します。

だから私の制限:

  1. SkypeAvailabilityManager.javaを再利用する
  2. レガシーコードは、コード内の多くの場所から.start.stop...を呼び出します。これが巨大なレガシーであることを変更する必要はありません。
  3. コードで共通のインターフェイスを意味する必要があります。両方のimplを同じように扱いたいのですが、クライアントはすべてのメソッドを呼び出すか、実際の実装でimpelemntationが実際に初期化されるまでその一部のみを呼び出します。

それの良いリファクタリングは何でしょうか?私のコンテナクラスがすべてのメソッドを保持するインターフェイスを保持している場合、これは素晴らしいことですが、2番目の実装ではすべてのメソッドが必要ではないため、何をすべきか少し混乱しています。

4

1 に答える 1

1

呼び出しコードを変更したくない場合は、次のようにします。

  1. すべてのメソッドでインターフェイスを作成します。これにより、コードに暗黙的に含まれているもの、つまりレガシーソフトウェアとメッセンジャー間の契約を明示的に述べています。
  2. MessengerBを除くすべてのメソッドupdateStatusがノーオペレーション (つまり、何もしない空のメソッド)であるインターフェイスを実装します。
  3. これらのメッセンジャーの実装を多数持つ場合は、インターフェイスを実装し、すべてのメソッドがノーオペレーションである抽象クラスを作成してから、適切なメソッドをオーバーライドする特定のメッセンジャーごとにサブクラスを作成できます。

IMHO これは良い最初のステップです。主に、現在のコード ステータスを適切にキャプチャし、新しいメッセンジャーを作成するために実装する必要があることを明確に示しており、後でレガシー コードをリファクタリングする場合の基礎として機能できるためです。

HTH

于 2013-03-04T15:40:33.523 に答える