Xem xét một tình huống trong đó một lớp thực hiện cùng một hành vi cơ bản, các phương thức, et cetera, nhưng nhiều phiên bản khác nhau của lớp đó có thể tồn tại cho các mục đích sử dụng khác nhau. Trong trường hợp cụ thể của tôi, tôi có một vectơ (vectơ hình học, không phải danh sách) và vectơ đó có thể áp dụng cho bất kỳ không gian Euclide N chiều nào (1 chiều, 2 chiều, ...). Làm thế nào có thể định nghĩa lớp / loại này?
Điều này sẽ dễ dàng trong C ++ khi các mẫu lớp có thể có các giá trị thực tế làm tham số, nhưng chúng ta không có sự sang trọng đó trong Java.
Hai cách tiếp cận tôi có thể nghĩ ra có thể được thực hiện để giải quyết vấn đề này là:
Có một thực hiện của từng trường hợp có thể tại thời gian biên dịch.
public interface Vector { public double magnitude(); } public class Vector1 implements Vector { public final double x; public Vector1(double x) { this.x = x; } @Override public double magnitude() { return x; } public double getX() { return x; } } public class Vector2 implements Vector { public final double x, y; public Vector2(double x, double y) { this.x = x; this.y = y; } @Override public double magnitude() { return Math.sqrt(x * x + y * y); } public double getX() { return x; } public double getY() { return y; } }
Giải pháp này rõ ràng là rất tốn thời gian và cực kỳ tẻ nhạt để viết mã. Trong ví dụ này có vẻ không tệ lắm, nhưng trong mã thực tế của tôi, tôi đang xử lý các vectơ có nhiều triển khai mỗi cái, với tối đa bốn chiều (x, y, z và w). Tôi hiện có hơn 2.000 dòng mã, mặc dù mỗi vector chỉ thực sự cần 500.
Chỉ định tham số khi chạy.
public class Vector { private final double[] components; public Vector(double[] components) { this.components = components; } public int dimensions() { return components.length; } public double magnitude() { double sum = 0; for (double component : components) { sum += component * component; } return Math.sqrt(sum); } public double getComponent(int index) { return components[index]; } }
Thật không may, giải pháp này làm tổn hại đến hiệu suất mã, dẫn đến mã lộn xộn hơn so với giải pháp trước đây và không an toàn ở thời gian biên dịch (không thể đảm bảo tại thời điểm biên dịch rằng vectơ bạn xử lý thực sự là 2 chiều, ví dụ).
Tôi hiện đang thực sự phát triển trong Xtend, vì vậy nếu có bất kỳ giải pháp Xtend nào có sẵn, chúng cũng sẽ được chấp nhận.