lok*_*oki 9 .net c# oop design-patterns
我一直在阅读一些关于SOLID原则和依赖Inversion的文章.从我的角度来看,我必须使用一个界面来与任何一个班级交谈.我的课程是通过使用接口聊天.
我正在使用抽象类,但对于我的代码的第二部分,我使用了一个接口.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
class Program
{
static void Main(string[] args)
{
MessageManager msg = new MessageManager(new Sms());
msg.Sms.Get();
msg.Sms.Send();
Console.Read();
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Usage1和usage2有什么区别?我什么时候选择usage1或Usage2?
Ser*_*kiy 22
这里的抽象类用重复的代码来对抗.接口 - 定义合同(API).
依赖于接口 - 它们只是描述依赖的契约(API),并且可以轻松地模拟它们.所以,从界面开始:
public interface IMessage
{
void Get(); // modifiers like public are not allowed here
void Send();
}
Run Code Online (Sandbox Code Playgroud)
这是你的依赖类,它应该只依赖于抽象(即接口):
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建类,它将实现您的接口:
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!");
}
}
Run Code Online (Sandbox Code Playgroud)
现在你已经反转了依赖 - MessageManager并且Sms只依赖于IMessage.您可以将任何IMessage实现注入MessageManager(MessageManager现在适合OCP - 打开以进行扩展,但关闭以进行修改).
仅当您在多个IMessage实现者中有重复的代码时才创建基本抽象消息类.当您创建抽象类(位置,移动重复代码的位置)时,您不应更改接口,因为合同保持不变.只需从原始IMessage界面继承您的基类.