Страницы

Поиск по вопросам

суббота, 23 марта 2019 г.

Как избежать определения двух методов/конструкторов с одинаковыми параметрами?

Например, пишу класс 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); } } }

Комментариев нет:

Отправить комментарий