如何避免代码重复?
How to avoid code repeating?
我在 类 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;
}
}
只需继承具有 public 成员的 class :)
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;
}
}
你应该做一个 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()
不要错误地创建基础 class 来共享该方法。这是对继承的常见滥用。这种技术通常会失效,您会在 class 的 public 界面中引入无意义的 class。 继承不是为了代码共享。它是为了"Liskov substitution"。
相反,创建一个静态辅助方法,它将两个值作为参数并计算结果。这允许您实施一次格式化。这很容易实现,几乎总是有效,并且不会影响 classes 的 public API。不要害怕稍大的语法足迹。这不是什么大问题(大多数时候)。
作为 usr 答案的替代方案,您可以重构您的代码,将数据写入屏幕的问题分开。
所以你的 Hour
和 Day
classes 没有 2 个职责(单一职责原则),也使得代码更容易更新更复杂的输出将来的功能,因为您只需要更改编写器中的代码 class。 (或将其抽象化并为 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);
}
}
我在 类 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;
}
}
只需继承具有 public 成员的 class :)
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;
}
}
你应该做一个 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()
不要错误地创建基础 class 来共享该方法。这是对继承的常见滥用。这种技术通常会失效,您会在 class 的 public 界面中引入无意义的 class。 继承不是为了代码共享。它是为了"Liskov substitution"。
相反,创建一个静态辅助方法,它将两个值作为参数并计算结果。这允许您实施一次格式化。这很容易实现,几乎总是有效,并且不会影响 classes 的 public API。不要害怕稍大的语法足迹。这不是什么大问题(大多数时候)。
作为 usr 答案的替代方案,您可以重构您的代码,将数据写入屏幕的问题分开。
所以你的 Hour
和 Day
classes 没有 2 个职责(单一职责原则),也使得代码更容易更新更复杂的输出将来的功能,因为您只需要更改编写器中的代码 class。 (或将其抽象化并为 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);
}
}