gpt4 book ai didi

c# - 当您想在从接口(interface)继承的不同类之间进行选择时,如何不违反 OCP?

转载 作者:太空狗 更新时间:2023-10-30 01:24:23 25 4
gpt4 key购买 nike

我有一个接口(interface)可以说 ISendOut 我从它继承了两个不同的类例如 TransferViaSerialPort 和 TransferViaWirelessModule(我的意思是在这两个类中实现这个接口(interface))。我怎样才能设计我的软件,使用户能够选择(在用户界面中)通过SerialPort发送他/她的数据的方法>WirelessModule 并没有违反OCP?因为如果我想要一个“Switch Case”或“If/Else”语句,我将违反 OCP。

最佳答案

你需要使用工厂模式。为了使工厂模式动态化,您可以使用反射并在 UI 中显示类的类型,这些类是从 ISendOut 实现的,您可以使用自定义属性或其他方法,例如使用字典

[System.AttributeUsage(System.AttributeTargets.Class)]
public class DisplayNameAttribute : Attribute
{
public DisplayNameAttribute(string displayName)
{
DisplayName = displayName;
}

public string DisplayName { get; set; }
}

public interface ISendOut
{
void Send(string data);
}

[DisplayName("Wireless")]
public class WirelessSendOut : ISendOut
{
public void Send(string data)
{
MessageBox.Show("data sent through wireless.");
}
}

[DisplayName("Serial")]
public class SerialSendOut : ISendOut
{
public void Send(string data)
{
MessageBox.Show("data sent through serial port.");
}
}

public static class SendOutFactory
{
public static ISendOut CreateSendOut(string typeName)
{
var types = Assembly.GetExecutingAssembly().GetTypes();
var sendOutType = types.First(x => (typeof(ISendOut)).IsAssignableFrom(x) && x.Name == typeName);
return (ISendOut) Activator.CreateInstance(sendOutType);
}
}

public static class SendOutDiscovery
{
public static IEnumerable<NameType> Discover()
{
var types = Assembly.GetExecutingAssembly().GetTypes();
var sendOutTypes = types.Where(x => x != typeof(ISendOut) && (typeof(ISendOut)).IsAssignableFrom(x));
return sendOutTypes.Select(type => GetNameType(type)).ToList();
}

private static NameType GetNameType(Type type)
{
var nameType = new NameType
{
DisplayName = GetDisplayName(type),
TypeName = type.Name
};
return nameType;
}

private static string GetDisplayName(Type type)
{
return ((DisplayNameAttribute)type.GetCustomAttributes(typeof (DisplayNameAttribute), false).First()).DisplayName;
}
}

public class NameType //for binding in UI
{
public string DisplayName { get; set; }
public string TypeName { get; set; }
}

public class SendOutViewModel //sample using in wpf (window contains a combobox)
{
public SendOutViewModel()
{
SendTypes = new ObservableCollection<NameType>(SendOutDiscovery.Discover());
}

public NameType SelectedSendType { get; set; } //bind to selected item in combobox

public ObservableCollection<NameType> SendTypes { get; private set; } //bind to item source of combo

public string Data { get; set; } //data to be sent

public void Send()
{
ISendOut sendOut = SendOutFactory.CreateSendOut(SelectedSendType.TypeName);
sendOut.Send(Data);
}
}

稍后我在不修改现有代码的情况下添加 UsbSendOut(因此不会破坏 OCP)

[DisplayName("Usb")]
public class UsbSendOut : ISendOut
{
public void Send(string data)
{
MessageBox.Show("data sent through usb.");
}
}

关于c# - 当您想在从接口(interface)继承的不同类之间进行选择时,如何不违反 OCP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9573201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com