Как обрабатывать один и тот же путь кода с разными параметрами?
Я столкнулся с ситуацией, когда, пытаясь не изменять базовый исходный код (это не совсем "мой" код на этом уровне; в противном случае я хотел бы изменить его), у меня есть два почти идентичных пути кода, но с отдельные типы данных, которые я использую.
Не обращая внимания на то, что вы, вероятно, можете довольно легко преобразовать одно в другое, похожим примером будет объект "Круг".
С одной стороны, у меня есть Point
объект и радиус. С другой стороны, у меня есть Circle
объект. Оба они могут описывать один и тот же фактический круг, но я просто не могу преобразовать один в другой.
Тогда в моем коде у меня есть:
void Run(Circle circle)
{
if(AllNegative(circle))
{
// ...
// Do unrelated stuff
// ...
ColorCircle(circle);
// ...
}
}
void Run(Point pt, uint radius)
{
if(AllNegative(pt, radius))
{
// ...
// Do unrelated stuff
// ...
ColorCircle(pt, radius);
// ...
}
}
bool AllNegative(Circle circle) { return (circle.AllNegative); }
bool AllNegative(Point pt, uint radius) { return ((pt.X + radius) < 0) && ((pt.Y + radius) < 0); }
void ColorCircle(Circle circle) { /* ... */ }
void ColorCircle(Point pt, uint radius) { /* ... */ }
Конечно, у меня есть больше кода в Run
чем в этом примере.
Как мне слить Run
в одну функцию, чтобы минимизировать дублирование кода?
4 ответа
В этом случае вы можете выбрать два пути:
- Вы можете оставить все как сейчас - перегруженные методы.
- Переместить дублированный код в новый метод. Если в вашем
unrelated
В разделе вы рассчитываете диаметр круга (реалистичный или нет), создаете методcalcDiameter(radius)
,
В такой ситуации нет ничего плохого с дублированным кодом, если только пара строк действительно не делает новый метод практичным.
Пример с дженериками:
public interface ICircle
{
Point Point{get;}
uint Radius{get;}
... add whatever you need
}
public class MyCircle: ICircle
{
private Circle _circle;
... implement interface
}
public class MyCircle2: ICircle
{
private Point _point;
private uint _radius;
... implement interface
}
void Run<T>(T circle) where T: ICircle
{
if(AllNegative(circle))
{
ColorCircle(circle);
}
}
Вы можете создать общий интерфейс для них обоих, который будет выглядеть примерно так:
public interface IMyShape
{
public bool IsNegative();
public void Color();
}
Тогда вам понадобится только один метод, который принимает ссылку IMyShape:
void Run(IMyShape shape)
{
if(shape.AllNegative())
{
// ...
// Do unrelated stuff
// ...
shape.Color();
// ...
}
}
Как минимум, вы могли бы сделать unrelated stuff
в отдельном методе и вызывать его из каждого Run
,