如何避免代码重复
本文关键字:代码 何避免 | 更新日期: 2023-09-27 18:02:58
我在Hour
和Day
两个类的Output()
方法中有相同的代码。有没有办法避免在一个地方而不是两个地方修改代码?
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715 080000");
Day day = new Day(hour);
Console.WriteLine(String.Format("Hour: {0}", hour.Output()));
Console.WriteLine(String.Format("Day: {0}", day.Output()));
}
}
public interface IMoment
{
string OutputMoment();
}
class Hour : IMoment
{
public string Date;
public string Time;
public Hour (string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
public string Output()
{
return Date + " " + Time;
}
}
class Day : IMoment
{
public string Date;
public string Time;
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
public string Output()
{
return Date + " " + Time;
}
}
不要犯创建基类来共享该方法的错误。这是对继承的一种常见的误用。这种技术通常会失效,并且将无意义的类引入到类的公共接口中。继承不能用于代码共享。用于"Liskov替换"。
相反,创建一个静态助手方法,它将这两个值作为参数并计算结果。这允许您实现一次格式化。这很容易实现,几乎总是有效,而且不会影响类的公共API。不要担心稍微大一点的语法占用空间。这不是什么大问题(大多数时候)。
作为usr回答的另一种选择,您可以重构代码,使编写数据到屏幕的关注点分开。
所以你的Hour
和Day
类没有2个责任(单一责任原则),以及使代码更容易更新与更复杂的输出功能在未来,因为你只需要改变在作家类的代码。(或抽象并创建例如FileMomentWriter
等)
public interface IMoment
{
string MomentType {get;}
string Date {get;set;}
string Time {get;set;}
}
public class Hour:IMoment
{
public string MomentType {get{return "Hour";}}
public string Date {get;set;}
public string Time {get;set;}
public Hour (string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
}
public class Day: IMoment
{
public string MomentType {get{return "Day";}}
public string Date{get;set;}
public string Time{get;set;}
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
}
public class ConsoleMomentWriter
{
public void Write(IMoment moment)
{
Console.WriteLine("{0}: {1} {2}",moment.MomentType,moment.Date,moment.Time);
}
}
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715 080000");
Day day = new Day(hour);
var writer = new ConsoleMomentWriter();
writer.Write(hour);
writer.Write(day);
}
}
你应该用abstract class
代替interface
:
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715;080000");
Day day = new Day(hour);
Console.WriteLine(String.Format("Hour: {0}", hour.OutputMoment()));
Console.WriteLine(String.Format("Day: {0}", day.OutputMoment()));
}
}
public abstract class Moment
{
public string Date;
public string Time;
public virtual string OutputMoment()
{
return Date + " " + Time;
}
public override string ToString()
{
return OutputMoment();
}
}
class Hour : Moment
{
public Hour(string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
}
class Day : Moment
{
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
}
如果需要的话,将OutputMoment()
标记为virtual
还将允许您超越默认实现。我还重写了ToString()
这样你就可以直接使用Console.WriteLine(hour);
而不用调用OutputMoment()
直接继承一个拥有public成员的类:)
class HasOutput
{
public string Date;
public string Time;
public string Output()
{
return Date + " " + Time;
}
}
class Hour : HasOutput, IMoment
{
public Hour (string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
}
class Day : HasOutput
{
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
}