我有3个班级:InputSocket
,InternalSocket
,OutputSocket
。它们都从具有实现BaseSocket
接口的ISocket
继承,在这里我对所有类都有通用代码,而这部分工作正常,部分共享代码存在问题。
InputSocket
和InternalSocket
共享与OutputSocket
没有的解析部分。
InputSocket
和OutputSocket
与InternalSocket
没有共享GUI部分。
我正在寻找一种在InputSocket
/ InternalSocket
和InputSocket
/ OutputSocket
之间共享代码公共部分的方法。带有的代码由方法和参数组成。
我已经尝试过使用多个接口,但是并不能解决问题,它使它更易于管理。当我为解析部分创建IParsable
并为 Input / Output公用部分创建IExternal
时,我需要为{ {1}的{1}} IParsableSocket
和InternalSocket
的{{1}}。它并没有改变我仍然需要为每种情况实现代码的观点,从而导致代码重复。
不幸的是,在c#中,IParsableExternalSocket
无法同时从InputSocket
和IExternalSocket
继承。
是否有替代方法,以复制/粘贴代码或使用if逻辑和null组成一堆通用Socket类?
答案 0 :(得分:1)
我认为inheritance
在这里不适合您。您的接口中不应有不打算在继承的类中使用/实现的方法。这违反了Interface Segregation Principle
接口隔离原则(ISP)规定没有客户端应 被迫依赖不使用的方法
在您的情况下,这意味着BaseSocket
不应该是具有所有“通用”方法的上帝班级。取而代之的是,您需要多个接口和实现来执行一种特定的操作,例如您的情况下为Parse
和Gui
。
您不同的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