私は、質問のために、たとえば「果物」と「野菜」を扱うレガシーJavaアプリケーションに取り組んでいます。それらは内部的に異なるものとして扱われます。なぜなら、それらはすべてのメソッド/プロパティを共通に持っているわけではないからですが、多くのことはそれらの両方に非常によく似ています。
したがって、適切なdoOtherStuffWithAFruit(Fruit f) / doOtherStuffWithAVeg(Veg v)を使用するdoSomethingWithAFruit(Fruit f )メソッドとdoSomethingWithAVegetable(Veg v)メソッドがたくさんあります。そして、それらは非常に似ていますが、果物を使って物事を行うメソッドは、果物を使って物事を行うメソッドのみを呼び出し、野菜についても同じことを呼び出します。
重複を減らすためにこれをリファクタリングしたいのですが、それを達成するための最良の方法がわかりません。いくつかのデザインパターンについて少し読んだことがありますが、それが私にとってより明確になったのかどうかはわかりません。(使用しているコードのいくつかのパターンを認識できますが、周りの状況を改善するためにパターンをいつ適用する必要があるのか本当にわかりません。おそらく、リファクタリング自体についてもっと読む必要があります...)
私はこれらの2つのオプションを考えていました:
1. FruitまたはVegetableのインスタンスを持つことができるクラスを作成し、それをメソッドに渡し、重複を最小限に抑えます。これは次のようになります。
public void doSomething(Plant p) {
// do the stuff that is common, and then...
if (p.hasFruit()) {
doThingWithFruit(p.getFruit());
} else {
doThingWithVegetable(p.getVegetable());
}
}
これで少し良くなるでしょうが、私にはわかりません...それでも気分が悪いです。
2.私が考えたもう1つの方法は、Fruit and Vegetableに共通のものを含むインターフェースを配置し、それを使用してそれを渡すことでした。これはよりクリーンなアプローチだと思いますが、instanceof
Fruit / Vegetableに固有のものが必要な場合は、Fruit/Vegetableを使用してキャストする必要があります。
それで、私はここでこれ以上何ができますか?そして、これらのアプローチの欠点は何ですか?
更新:質問は少し単純化されていることに注意してください。私は「植物」を使って物事を行う方法を探しています。つまり、植物に何かをする代わりに、ほとんど「植物」を「使用する」コードを探しています。そうは言っても、私が参照するこれらの同様のメソッドは「Plants」クラス内に含めることはできず、通常、次のような別の引数があります。
public void createSomethingUsingFruit(Something s, Fruit f);
public void createSomethingUsingVegetable(Something s, Vegetable v);
つまり、これらのメソッドには、果物/野菜以外の懸念事項があり、果物/野菜のクラスに含めるのには実際には適していません。
更新2:これらのメソッドのほとんどのコードは、Fruit / Vegetableオブジェクトから状態を読み取り、適切なタイプに従って他のクラスのインスタンスを作成し、データベースに保存するなど、私の回答からコメントの質問への回答までです。それが重要だと思います。