Shapeインターフェイスを使用することは、非常に制限されているため、通常は不適切な設計です。さまざまな形を説明するには、さまざまな情報が必要です。サイズ変更はこの良い例です。円の場合は半径を変更する必要があり、長方形の場合は両側を変更する必要があります。つまり、1つではなく2つのパラメータを渡す必要があります。
これは、実際の形状が収まる必要のある長方形など、ある種の形状記述子を渡すことで解決できます。したがって、すべての形状がクラスで事前定義されており、すべてをスケーリングすることを前提として、適切にサイズ変更できます。カスタムシェイプが必要な場合は、シェイプ記述子を何らかの方法で拡張して、カスタムシェイプに必要なすべての情報を含める必要がありますが、既存のシェイプとの互換性は維持されます。これは必ずしも難しいことではありません。nullになる可能性のあるプロパティまたはパラメータを追加できます。ここでは、新しいパラメーターのみを追加します。
private interface ShapeFactory{
public Shape create(float x, float y, float width, float height);
}
private class CircleFactory implements ShapeFactory{
public Shape create(float x, float y, float width, float height){
float radius = Math.min(width, height);
return new Circle(radius, x, y);
}
}
あなたが通常このようにファクトリーを使用するという別の考え(多くの場合、あなたが望むものによってはアッパーも良いかもしれません):
private interface ShapeFactory{
public Shape create(float x, float y, float width, float height, bool isCircle);
}
private class MyShapeFactory implements ShapeFactory{
public Shape create(float x, float y, float width, float height, bool isCircle){
if (isCircle)
return new Circle(Math.min(width, height), x, y);
else
return new Rectangle(width, height, x, y);
}
}
したがって、ファクトリは必ずしもコンストラクタと同じパラメータを持っているとは限りません。多くの人がこの印象を持っています。なぜなら、彼らは工場を自動化し、それらをインスタンス化する方法についての情報なしでクラスリストのみを渡そうとしているからです。自動化されたDIコンテナによってコミットするのと同じ間違いです。
ここで本当に重要なのは、上位レベルのコードがどのようなShape実装を取り戻すかを知りたいかどうかです。ただし、場合によっては、ある種の一般的な記述子を持っているか、リファクタリングすることがあります。たとえば、必ずしもShape.scale(width, height)
メソッドがあるとは限りません。メソッドがある場合、コンストラクターと同様にスケーリングが異なるため、円や長方形のサイズを変更することはできません。しかし、もしあなたが望むのがのようなものを呼ぶことだけならShape.draw(canvas)
、私はあなたが行ってもいいと思います。
その間、私は同様の答えを持つ同様の質問を見つけました、多分あなたもそれから学ぶことができます:https ://softwareengineering.stackexchange.com/a/389507/65755