我一直在阅读一些关于 SOLID 原则和依赖倒置的文章。从我的角度来看,我必须使用一个接口(interface)来与任何类对话。我的类(class)正在使用界面聊天。
第一个问题:
我使用的是抽象类,但对于代码的第二部分,我使用的是接口(interface)。
用法1
namespace DependencyInjection
{
public interface IMessage
{
}
public abstract class Message
{
public abstract void Get();
public abstract void Send();
}
public class Sms : Message, IMessage
{
public override void Get()
{
Console.WriteLine("Message Get!");
}
public override void Send()
{
Console.WriteLine("Message Send!");
}
}
public class MessageManager
{
private IMessage _message;
public Sms Sms
{
get { return _message as Sms; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
}
用法:
class Program
{
static void Main(string[] args)
{
MessageManager msg = new MessageManager(new Sms());
msg.Sms.Get();
msg.Sms.Send();
Console.Read();
}
}
用法2
namespace DependencyInjection
{
public interface IMessage
{
public void Get();
public void Send();
}
public class Sms : IMessage
{
public void IMessage.Get()
{
Console.WriteLine("Message Get!");
}
public void IMessage.Send()
{
Console.WriteLine("Message Send!");
}
}
public class MessageManager
{
private IMessage _message;
public Sms Sms
{
get { return _message as Sms; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
}
Usage1 和 usage2 有什么区别?什么时候选择用法 1 或用法 2?
最佳答案
此处的抽象类与重复代码作斗争。接口(interface) - 定义契约 (API)。
依赖于接口(interface) - 它们只是描述依赖关系的契约 (API),并且它们可以很容易地被模拟。所以,从界面开始:
public interface IMessage
{
void Get(); // modifiers like public are not allowed here
void Send();
}
这是你的依赖类,它应该只依赖于抽象(即接口(interface)):
public class MessageManager
{
private IMessage _message;
// depend only on abstraction
// no references to interface implementations should be here
public IMessage Message
{
get { return _message; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
然后创建类,它将实现您的接口(interface):
public class Sms : IMessage
{
// do not use explicit implementation
// unless you need to have methods with same signature
// or you want to hide interface implementation
public void Get()
{
Console.WriteLine("Message Get!");
}
public void Send()
{
Console.WriteLine("Message Send!");
}
}
现在您已经反转了依赖关系 - MessageManager
和 Sms
仅依赖于 IMessage
。您可以将任何 IMessage
实现注入(inject)到 MessageManager
(MessageManager 现在适合 OCP - 对扩展开放,但对修改关闭)。
当您在多个 IMessage
实现程序中有重复代码时,仅创建基础抽象消息类。当你创建抽象类(地方,你移动重复代码的地方)时,你不应该改变接口(interface),因为契约(Contract)保持不变。只需从原始 IMessage
接口(interface)继承您的基类。
关于c# - 关于依赖注入(inject),何时使用抽象类与接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13442312/