輸入多組參數陣列,分別代表矩形(長寬)、圓形(半徑)等形狀,計算總面積佔外接矩形比例。需支援未來擴充三角形、梯形、多邊形等。
package com.test;
public interface Shape {
double getArea(); // 移除介面常量 area,改由實作類管理狀態
}
// 矩形 (含正方形)
public class Rectangle implements Shape {
private final double length;
private final double width;
public Rectangle(double length, double width) {
this.length = length; this.width = width;
}
@Override public double getArea() { return length * width; }
}
// 圓形
public class Round implements Shape {
private static final double PI = Math.PI; // 使用 Math.PI 更精確
private final double radius;
public Round(double radius) { this.radius = radius; }
@Override public double getArea() { return PI * radius * radius; }
}
// 三角形 (海龍公式)
public class Triangle implements Shape {
private final double a, b, c;
public Triangle(double a, double b, double c) { this.a=a; this.b=b; this.c=c; }
@Override public double getArea() {
double s = (a+b+c)/2;
return Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
}
public class ShapeFactory {
public static Shape create(double[] params) {
if (params == null || params.length == 0) return null;
switch (params.length) {
case 1: return new Round(params[0]); // 圓形
case 2: return new Rectangle(params[0], params[1]); // 矩形
case 3: return new Triangle(params[0], params[1], params[2]); // 三角形
default: throw new IllegalArgumentException("不支援的參數個數: " + params.length);
}
}
}
public class Domain {
public static void main(String[] args) {
double[][] shapesData = {
{400.0, 50.0}, // 外接矩形
{10.0}, // 圓形
{10.0, 20.0}, // 矩形
{5.0, 15.0}, // 矩形
{23.5} // 圓形
};
Shape outer = ShapeFactory.create(shapesData[0]);
double maxArea = outer != null ? outer.getArea() : 0;
double userArea = 0;
for (int i = 1; i < shapesData.length; i++) {
Shape s = ShapeFactory.create(shapesData[i]);
if (s != null) userArea += s.getArea();
}
double usageRate = maxArea > 0 ? userArea / maxArea : 0;
System.out.printf("使用率: %.4f%%%n", usageRate * 100);
}
}
| 原始碼 | 改進版 |
|---|---|
介面含常量 area | 介面純行為,狀態封裝在實作類 |
if(len==1)...if(len==2) 硬編碼 | 工廠方法集中建立邏輯,易擴充 |
| 新增形狀需改主程式 | 新增類別實作 Shape + 工廠加一行 case |
| PI 硬編碼 3.14 | 使用 Math.PI |
若形狀類別很多,可用 @ShapeType(paramCount=3) 註解 + 反射掃描自動註冊到 Map,工廠查 Map 建立實例,完全符合開閉原則。
採用「介面定義行為、具體類別封裝演算法、工廠封裝建立邏輯」的經典組合,實現**高內聚、低耦合、易擴充**。新增形狀只需新增類別、註冊工廠,業務邏輯完全不變。