我有一个类库,描述了不同的连接硬件,如钉子,螺钉和螺栓,我们称之为ConnectorLibrary。我试图在那个库之上构建一个库,它将处理分析该库中每个类的抓握能力,我们称之为ConnectorGripAnalysisLibrary。
对于此问题,我们将使用这些类:Screw
,Bolt
和Connector
。 Screw
和Bolt
都继承自Connector
(这是一个抽象类),它们都在ConnectorLibrary中实现。
我需要一种不同的方法来确定我需要实现的基础库中每个类的抓握。因此,对于Bolt
和Screw
,我需要实现DoesPassGripTest(Board board)
等方法。 (董事会只是一个示例参数)
如果我要在Connectorlibrary中实现它,我会将DoesPassGripTest
放入Connector
抽象方法中,并在各自的派生类中实现不同的公式。
目标是能够让我的代码在ConnectorGripAnalysisLibrary中像这样工作:
[Test()]
public static void CheckScrewAndBoltGripTest()
{
Board board = new Board();
Bolt b = new Bolt();
Screw s = new Screw();
List<Connector> connectors = new List<Connector>()
connectors.add(b);
connectors.add(s);
foreach(var connector in connectors)
{
if(!connector.DoesPassGripTest(board));
throw new Exception("Grip Test Fails");
}
}
我想保持&#34;开放封闭原则&#34;在ConnectorGripAnalysisLibrary中,如果将新连接器添加到ConnectorLibary,则除了添加新类之外,不需要修改ConnectorGripAnalysisLibrary。 &#34;为扩展而开放,为修改而关闭&#34;
但是如何将这个功能构建到构建于ConnectorLibrary之上的GripAnalysisLibrary中。我能做到这一点吗?
我不希望ConnectorLibrary包含GripAnalysis代码和功能。 ConnectorLibrary是开源的,而GripAnalysisLibrary是专有的。
答案 0 :(得分:0)
要将此作为扩展方法执行此操作,您需要创建一个类来定义 Connector 的扩展,并将类包含在您希望在Connector实例上使用DoesPassGripTest
方法的任何位置。扩展的基本概要是:
public static class ConnectorExtensions
{
public static bool DoesPassGripTest(this Connector connector, Board board)
{
// Some logic to determine which connector is being used
}
}
我不知道是否有任何其他方法可以确定哪个连接器正在传递,而不是类型检查,因为您没有提供有关连接器或夹点分析逻辑的任何详细信息。您的扩展需要知道如何评估给定每个连接器类型的给定板的测试。
编辑:
基于您希望ConnectorGripAnalysisLibrary可以轻松扩展且无需修改,这里是使用反射的方法的伪代码,允许您只需为每个新连接器添加一个类。
创建一个界面,提供运行分析的信息以及它所用的连接器类型:
public interface IConnectorGripAnalyzer
{
Type ConnectorType { get; }
bool DoesPassGripTest(Board board);
}
使用泛型创建基类,以便轻松实现具体类:
public class ConnectorGripAnalyzer<T> : IConnectorGripAnalyzer where T : Connector
{
public Type ConnectorType
{
get { return typeof(T); }
}
public virtual bool DoesPassGripTest(Board board)
{
return true;
}
}
创建一个可用于通过Type使用反射获取IConnectorGripAnalyzer实例的存储库。首次使用时,它会收集所有各种分析仪并按连接器类型存储它们:
public static class ConnectorAnalyzerRepository
{
private Dictionary<Type, IConnectorGripAnalyzer> connectorGripAnalyzers;
public IConnectorGripAnalyzer GetGripAnalyzer(Connector connector)
{
if (connectorGripAnalyzers == null)
{
connectorGripAnalyzers = new Dictionary<Type, IConnectorGripAnalyzer>();
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(IConnectorGripAnalyzer).IsAssignableFrom(t));
foreach (var t in types)
{
var c = Activator.CreateInstance(t) as IConnectorGripAnalyzer;
if (c == null)
continue;
connectorGripAnalyzers[c.ConnectorType] = c;
}
}
return connectorGripAnalyzers.ContainsKey(typeof(connector)) ? connectorGripAnalyzers[typeof(connector)] : null;
}
}
Connector的扩展利用存储库为给定的Connector创建适当的IConnectorGripAnalyzer实例。如果连接器的类型没有实现,则该示例将引发异常,但您可以返回false或将其记录为配置问题:
public static class ConnectorExtensions
{
public static bool DoesPassGripTest(this Connector connector, Board board)
{
var analyzer = ConnectorAnalyzerRepository.GetGripAnalyzer(connector);
if (analyzer == null)
throw new ArgumentException("Invalid connector type"); // Do whatever you want with the failure
return analyzer.DoesPassGripTest(board);
}
}
在ConnectorGripAnalysisLibrary中添加对Connector的支持现在需要添加一个继承自ConnectorGripAnalyzer的类和具体的Connector类型。所需的只是适当覆盖特定连接器的DoesPassGripTest(Board board)
:
public class NailConnectorGripAnalyzer : ConnectorGripAnalyzer<NailConnector>
{
public override bool DoesPassGripTest(Board board)
{
return true;
}
}
public class ScrewConnectorGripAnalyzer : ConnectorGripAnalyzer<ScrewConnector>
{
public override bool DoesPassGripTest(Board board)
{
return true;
}
}