Например, пишу класс Vector. Вполне естественно создавать объект, принимая в конструктор или координаты x и y, или же принимая длину вектора и угол между направлением вектора и положительным направлением оси OX. Однако я не могу написать так:
public class Vector {
float x;
float y;
public Vector(float x, float y) {
this.x = x;
this.y = y;
}
public Vector(float length, float alpha) {
this.x = length*Math.cos(alpha);
this.y = length*Math.sin(alpha);
}
}
Компилятор, конечно, будет ругаться на неоднозначность в определении конструкторов. Я не могу её избежать переставив аргументы местами, так как они одинаковых типов. Что делать в таких ситуациях, когда метод/конструктор должен принимать два разных по смыслу набора параметров, но получается так, что они имеют одинаковые типы?
Ответ
В таких случаях не лишним будет использование статических фабричных методов. С использованием этого шаблона ваш код будет выглядить так:
public static class Vector {
public final float x;
public final float y;
private Vector(float x, float y) {
this.x = x;
this.y = y;
}
public static Vector coordinate(float x, float y) {
return new Vector(x, y);
}
public static Vector radian(float length, float alpha) {
return new Vector(length * Math.cos(alpha), length * Math.sin(alpha);)
}
}
Так же, можно воспользоваться шаблоном проектирования builder. Здесь он выглядит немного громоздко, но в принципе, тоже применим:
public static class Vector {
...
public static VectorBuilder builder() {
return new VectorBuilder();
}
public static class VectorBuilder {
private double length;
private double alpha;
private float x;
private float y;
public VectorBuilder setLength(float length) {
this.length = length;
compute();
return this;
}
public VectorBuilder setAlpha(float alpha) {
this.alpha = alpha;
compute();
return this;
}
private void compute() {
this.x = (float) (length * Math.cos(alpha));
this.y = (float) (length * Math.sin(alpha));
}
public VectorBuilder setX(float x) {
this.x = x;
return this;
}
public VectorBuilder setY(float y) {
this.y = y;
return this;
}
public Vector build() {
return new Vector(x, y);
}
}
}
Комментариев нет:
Отправить комментарий