web-dev-qa-db-ja.com

巨大な接着剤による方法を回避するには?

現在の仕事では、古いコードを数回クリーンアップする必要があります。多くの場合、コードは迷路であり、その背後にあるデータはさらに複雑になっています。私は、ニースのきちんとしたモジュール式メソッドに物事を組み入れていることに気づきました。それぞれの方法は1つのことを行い、それをうまく行います。その時、物事は南下し始めます...

常に、私はクリーンなAPIになり、それをすべて結び付ける実際の方法はありません。解決策は、大きな醜い「接着剤」メソッド(一般的には条件文でいっぱい)を記述して、最終的にすべての「クリーン」メソッドを呼び出すことでした。

グルーメソッドは通常、クリーンアップしようとしていたコード/データのもつれの簡潔なバージョンになります。一般的には読みやすくなりますが、それでも迷惑です。

このような方法を回避するにはどうすればよいですか?これはもつれたデータの症状ですか、それとも私が間違っていることを反映していますか?

21
cmhobbs

LedgerSMBのリファクタリングの経験を紹介します。私たちは早い段階で別の方法で行うことを決定しましたが、あなたが説明したとおり正確に行っていますが、多くの接着剤メソッドはありません(いくつかの接着剤メソッドがありますが、多くはありません)。

2つのコードベースのある生活

LedgerSMBは2つのコードベースで約5年間存続しており、古いコードベースが削除されるまでにはさらに数年かかります。古いコードベースは、見るには本当に恐ろしいものです。悪いdb設計、PerlはIS->some_func(\%$some_object);のようなコードと一緒にスパゲッティメタファーが使用される理由を正確に示すコードを作成します(実行パスはモジュール間とバック間、および言語間で蛇行しており、韻や理由はありません)。新しいコードベースは、dbクエリをストアドプロシージャに移動し、リクエスト処理のためのよりクリーンなフレームワークを持つことで、これを回避します。

最初に行うことを決めたのは、モジュールごとにリファクタリングすることでした。つまり、特定の領域のすべての機能を新しいモジュールに移動し、古いコードを新しいモジュールにフックします。新しいAPIがクリーンな場合、これは大した問題ではありません。新しいAPIが面白くない場合、それは新しいAPIで少し一生懸命作業することへの招待です...

2つ目は、新しいコードが古いコードのロジックにアクセスしなければならない場合がたくさんあることです。これは、醜い接着方法につながるため、可能な限り回避する必要がありますが、常に回避できるわけではありません。この場合、接着方法は最小限に抑え、可能な限り回避する必要がありますが、必要に応じて使用します。

これを機能させるには、特定の領域のall機能の書き換えをコミットする必要があります。たとえば、すべての顧客情報追跡コードを一度に書き直すことができる場合、これは古いコードからこれを呼び出すコードは扱いにくくなく、新しいコードから古いコードへのディスパッチが最小限に抑えられることを意味します。

2番目のことは、適切な抽象化を使用している場合は、呼び出すAPIのレベルと、そのAPIをクリーンに保つ方法を選択できることです。ただし、APIを呼び出す部分を書き直すことも検討してください。これにより、APIもかなりクリーンになります。

ビジネスツールには、取り返しのつかないほど複雑な多くの領域があります。すべての複雑さを取り除くことはできません。しかし、特に必要なことを行うクリーンなAPIと、そのAPIを建設的に利用するモジュールに焦点を当てることで、それを管理できます。呼び出しコードの残りの部分を書き換える方が速いかもしれないことを考慮した後にのみ、グルーは最後の手段であるべきです。

12
Chris Travers

あなたがやったことはpreceduralコードベースの複雑な混乱を取り、素敵なモジュラーpreceduralコードベースを作成したようです。

常に、私はクリーンなAPIになり、それをすべて結び付ける実際の方法はありません。解決策は、大きな醜い「接着剤」メソッド(一般的には条件文でいっぱい)を記述して、最終的にすべての「クリーン」メソッドを呼び出すことでした。

手続き型コード(OOに偽装されている場合でも)を使用すると、常に、どこかで定義されたある種の順次ワークフローが発生し、多くの場合、説明したように複雑な条件付きブランチで満たされます。何かがおかしいと感じさせているのは、このコードの手続き型の性質だと思います。これは必ずしも悪いことではなく、レガシーコードを使用する場合は完全に避けられないかもしれません

8
MattDavey

元のコードベースをクリーンアップするのと同じ方法で、大きな醜い接着剤メソッドをクリーンアップする必要があります。きちんとしたモジュール方式で分割します。おそらくいくつかのタスクを実行するコード行のグループがあり、これらの行をメソッドに分割します。いくつかの変数を共有する場合、共有変数と新しいメソッドを1つのクラスに入れることを検討できます。

6
Paling

基本的に、抽象化レイヤーを追加し続けます。抽象レイヤーは、各レイヤーを自分自身で捉えるまでです。抽象化についての逆説的なことは、抽象化されたコードを読むとき、一度に1つのレイヤーにしか関心がないので、それを減らすために複雑さを追加することです。各レイヤーが簡単に理解できるほど小さい場合、その上にあるレイヤーの数は関係ありません。

それが、抽象化を書くのを難しくしている理由でもあります。 鉛筆 のような単純なものでさえ、抽象化のすべてのレイヤーを一度に頭の中に保持しようとすると、心が曲がります。重要なのは、1つのレイヤーを好きな方法で取得し、それを行った後、そのレイヤーの基礎となっている複雑さをすべて忘れ、次のレベルで同じことを行うことです。

1
Karl Bielefeldt

APIの実装について考えるだけでAPIをリファクタリングしているように見えますが、APIを使用するコード、つまり、あなたが話している「グルーコード」について十分に考えていません。

それが本当ならあなたは反対側から始めようとするかもしれません。最初に醜い接着剤コードになる恐れのあるものを書き直し、そのプロセスでAPIになるいくつかのまだ実装されていないインターフェースを作成します。このAPIの実際の実装については、あまり考えすぎないでください。できると思っているのであれば大丈夫です。そして、そのAPIに準拠するようにコードのラビリンスを書き直します。もちろん、このプロセスではAPIとグルーコードにいくつかの変更が加えられますが、より適切に一致するはずです。

0