具有部分共享的属性,方法的分类。如何避免重复代码?

时间:2019-01-04 20:43:36

标签: c# interface multiple-inheritance

我有3个班级:InputSocketInternalSocketOutputSocket。它们都从具有实现BaseSocket接口的ISocket继承,在这里我对所有类都有通用代码,而这部分工作正常,部分共享代码存在问题。

InputSocketInternalSocket共享与OutputSocket没有的解析部分。

InputSocketOutputSocketInternalSocket没有共享GUI部分。

我正在寻找一种在InputSocket / InternalSocketInputSocket / OutputSocket之间共享代码公共部分的方法。带有的代码由方法和参数组成。 我已经尝试过使用多个接口,但是并不能解决问题,它使它更易于管理。当我为解析部分创建IParsable并为 Input / Output公用部分创建IExternal时,我需要为{ {1}的{1}} IParsableSocketInternalSocket的{​​{1}}。它并没有改变我仍然需要为每种情况实现代码的观点,从而导致代码重复。

不幸的是,在c#中,IParsableExternalSocket无法同时从InputSocketIExternalSocket继承。

是否有替代方法,以复制/粘贴代码或使用if逻辑和null组成一堆通用Socket类?

2 个答案:

答案 0 :(得分:1)

我认为inheritance在这里不适合您。您的接口中不应有不打算在继承的类中使用/实现的方法。这违反了Interface Segregation Principle

  

接口隔离原则(ISP)规定没有客户端应   被迫依赖不使用的方法

在您的情况下,这意味着BaseSocket不应该是具有所有“通用”方法的上帝班级。取而代之的是,您需要多个接口和实现来执行一种特定的操作,例如您的情况下为ParseGui

您不同的Socket类然后获得Composed的那些行为/操作,而不是inhert。这就是所谓的Composition over Inheritance

  

在面向对象程序设计中,继承之上的组合是   类应实现多态行为和代码的原则   按其组成重用,而不是从基础继承   家长班。这是OOP经常陈述的原则,例如   有影响力的书籍设计模式。

希望这会有所帮助。

答案 1 :(得分:1)

(您应该以base为后缀,而不是以base为前缀)

所以你有

public class InputSocket : BaseSocket { }
public class InternalSocket : BaseSocket {}
public class OutputSocket : BaseSocket {}
public abstract class BaseSocket : ISocket { }
public interface ISocket {}
  

InputSocket和InternalSocket共享与OutputSocket共享的解析部分。

public interface IParsingSocket {}

public class InputSocket : BaseSocket, IParsingSocket  { }
public class InternalSocket : BaseSocket, IParsingSocket  {}
public class OutputSocket : BaseSocket {}
  

InputSocket和OutputSocket与InternalSocket共享GUI部分。

public interface IParsingSocket {}
public interface IGUISOcket {}

public class InputSocket : BaseSocket, IParsingSocket, IGUISOcket  { }
public class InternalSocket : BaseSocket, IParsingSocket  {}
public class OutputSocket : BaseSocket, IGUISOcket {}

使用扩展方法的实现:

public static class IParsingSocketExtensions
{
  public static void Parse(this IParsingSocket) {}
}

public static class IGUISOcketExtensions
{
  public static void DoGUI(this IGUISOcket) {}
}

现在您可以

var inps = new InputSocket();
var ints = new InternalSocket();
var outs = new OutputSocket();

inps.Parse() // valid
ints.Parse() // valid
outs.Parse() // invalid

inps.DoGUI() // valid
ints.DoGUI() // invalid
outs.DoGUI() // valid