将两个非常相似的类重构为一个
本文关键字:重构 一个 非常 两个 相似 | 更新日期: 2023-09-27 18:06:17
这是第一个类:
public class TextBoxInt : TextBox
{
public int min;
public int max;
public Value<int> value;
public virtual void Update(object sender, EventArgs e)
{
int newValue;
if (int.TryParse(Text, out newValue))
{
if (newValue < min || newValue > max)
{
//do thing A
}
value.Set(newValue);
Text = value.Get().ToString();
}
else
{
Text = value.Get().ToString();
Focus();
}
}
public TextBoxInt(Value<int> value, int min, int max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
}
这是第二类:
public class TextBoxFloat : TextBox
{
public float min;
public float max;
public Value<float> value;
public virtual void Update(object sender, EventArgs e)
{
float newValue;
if (float.TryParse(Text, out newValue))
{
if (newValue < min || newValue > max)
{
//do thing A
}
value.Set(newValue);
Text = value.Get().ToString();
}
else
{
Text = value.Get().ToString();
Focus();
}
}
public TextBoxFloat(Value<float> value, float min, float max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
}
此外,这是Value类:
public class Value<T>
{
private T value;
private List<IValueListener<T>> listeners = new List<IValueListener<T>>();
public Value(T value)
{
this.value = value;
}
public T Get()
{
return value;
}
public void Set(T value)
{
this.value = value;
foreach (IValueListener<T> listener in listeners)
{
listener.ValueUpdated(this);
}
}
public void AddListener(IValueListener<T> listener)
{
listeners.Add(listener);
}
public void RemoveListener(IValueListener<T> listener)
{
listeners.Remove(listener);
}
}
正如你所看到的,前两个类基本上是同一个类。唯一的区别是类型。第一个是int
,另一个是float
。如果我能把这两个类组合成一个类,我似乎会制作出更好的代码。
如果是int类,我可以将min
和max
设置为float,并在需要时将它们强制转换为int
。当类型是int.时,我只会确保我通过"完整"浮动
有没有什么方法可以在不复制Update()
方法(If int do codeForInt, else if float do sameCodeButForFloat
(的情况下做到这一点?
此外,即使我复制了代码,我也会遇到value.Set(newValue);
的问题——在一种情况下,newValue
将是int
,在另一种情况中,它将是float
,并且我不能将任何一个转换为T
。
还有,有没有办法限制泛型类型?要指定它只能是int还是float?
我应该把它们作为两个阶级,还是有办法把它们统一起来?
您可以创建一个泛型类,而不是创建单独的类。
public class BoundedTextBox<T> : TextBox where T : IComparable<T> ...
声明T
实现IComparable<T>
将允许您在设置操作期间检查T
是否在边界内。
if (newValue.CompareTo(min) <= 0 || newValue.CompareTo(max) >= 0)
{
// do thing A
}
让一个抽象的TextBox<T>
类继承自TextBox
类,其中TextBox<T>
有一个新的abstract string GetValue()
方法怎么样?您将有实现GetValue()
的TextBoxFloat
类,它将执行float
特定的逻辑,类似地,TextBoxInt
类也将执行。你的TextBox<T>
会有点像
public abstract class TextBox<T> : TextBox
{
public T min;
public T max;
public Value<T> value;
public virtual void Update(object sender, EventArgs e)
{
Text = GetValue();
Focus();
}
public TextBoxFloat(Value<T> value, T min, T max)
{
this.value = value;
this.min = min;
this.max = max;
Text = value.Get().ToString();
LostFocus += new EventHandler(update);
}
public abstract string GetValue();
}
正如@flkes所说,泛型类是实现这一点的方法。你可以尝试以下方法:(你可以在这里找到一个很好的例子(
public abstract class TextBoxBase
{
public abstract object GetMin();
public abstract object GetMax();
public abstract object GetValue();
}
public abstract class TextBox<T> : TextBoxBase
{
public T min { get; set; }
public T max { get; set; }
public T value { get; set; }
public virtual void SetTextBox(T mn, T mx, T val)
{
min = mn;
max = mx;
value = val;
}
public override object GetMin() { return min; }
public override object GetMax() { return max; }
public override object GetValue() { return value; }
}
public class TextBoxInt : TextBox<int>
{
public override void SetTextBox(int mn, int mx, int val)
{
min = mn;
max = mx;
value = val;
}
}
public class TextBoxFloat : TextBox<float>
{
public override void SetTextBox(float mn, float mx, float val)
{
min = mn;
max = mx;
value = val;
}
}