- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下面的例子为例,我有多个继承自同一个“IChannelIntegration”接口(interface)的“Integration”类。
public interface IChannelIntegration
{
}
public class IntegrationA : IChannelIntegration
{
}
public class IntegrationB : IChannelIntegration
{
}
public IChannelIntegration CreateIntegration(string letter)
{
if(letter = "A")
{
return new IntegrationA();
}
else if (letter = "B")
{
return new IntegrationB();
}
else
{
return null;
}
}
我的一个集成提供了一些其他集成所没有的功能。我需要一种在从 CreateIntegration 函数返回的 IChannelIntegration 对象上调用此功能的方法。
我创建了以下类集合来处理这些自定义 IntegrationFeatures。 IntergrationFeature 接口(interface)是所有功能的来源。
public interface IIntegrationFeature {}
public interface ICustomLogic : IIntegrationFeature
{
void DoSomething() {}
}
//Provides a concrete implementation of the logic.
public class CustomLogic : ICustomLogic
{
public void DoSomething() {}
}
然后创建了另一个接口(interface),该接口(interface)将附加到集成类以支持集成提供自定义功能。
public interface ISupportsFeature<T> where T : Interfaces.IIntegrationFeature
{
T GetFeature();
}
将按如下方式实现;
public class IntegrationC : IChannelIntegration, ISupportsFeature<ICustomLogic>
{
public ICustomLogic GetFeature()
{
return new CustomLogic ();
}
}
这就是您如何为集成提供特定逻辑,然后使用以下内容调用它;
public static IIntegrationFeature GetIntegrationFeature<IIntegrationFeature>()
where IIntegrationFeature : Interfaces.IIntegrationFeature
{
IIntegrationFeature integrationFeature = null;
IChannelIntegration service = CreateIntegration();
//Attempt to cast the integration too determine if it supports the Integration Feature.
ISupportsFeature<IIntegrationFeature> supportsFeature = service as ISupportsFeature<IIntegrationFeature>;
if(supportsFeature != null)
{
integrationFeature = supportsFeature.GetFeature();
}
return integrationFeature;
}
public void TestMethod()
{
ICustomLogic customLogic = GetIntegrationFeature<ICustomLogic>();
if (customLogic != null)
{
customLogic.DoSomething();
}
}
我不确定我对这个实现的看法,我的一部分认为我把情况复杂化了很多,但我也认为它很容易使用,因为我的许多集成都需要为其提供自定义逻辑。
另一个问题是,如果集成提供多个 IntegrationFeatures,您将不得不显式调用接口(interface)函数,因为它们具有相同的 GetFeature 名称,这可能会给其他开发人员带来更多混淆。
最佳答案
我会从上到下,从您的需求到实现。
据我所知,您需要在运行时访问由特定系统根据给定值创建的集成所提供的功能。所以你的第一个 Actor 是
interface IIntegrationFeature {}
以及可以为您提供此功能的东西
interface IIntegratedSystem
{
T GetFeature<T>(string integrationType) where T : IIntegrationFeature;
}
此设置的客户端将使用这样的 actors
IIntegratedSystem system = .... // system implementation
T feature = system.GetFeature<T>("Which integration type?");
if (feature != null)
{
//the feature exists and I'm using it
}
IIntegratedSystem
实现的责任是提供 IIntegrationFeature
来自现有的 IChannelIntegration
实时选择或创建。您考虑过通知任何客户 IChannelIntegration
实现通过实现 ISupportFeature<IIntegrationFeature>
实现了一个特性.当集成有大约 20 个功能时会发生什么?您将拥有一个实现集成接口(interface)本身的类和另外 20 个 ISupports
接口(interface)。你如何添加另一个功能?您可以通过添加这个新的 ISupports<INewFeature>
来修改类违反单一职责原则。而且您不需要在编译时知道集成实现了某个功能,因为客户端可能会也可能不会使用它。基本上 IChannelIntegration
听起来更像是集成的复合,应该能够提供 IIntegrationFeature
因此 IChannelIntegration
会有类似于 IIntegratedSystem
的定义
interface IChannelIntegration
{
T GetFeature<T>() where T : IIntegrationFeature;
}
构建实现的方式 IChannelIntegration
取决于你,但我更愿意在你的应用程序的根目录下创建功能。我的应该是这样的
class ChannelIntegration : IChannelIntegration
{
private Dictionary<Type, IIntegrationFeature> features;
public ChannelIntegration()
{
features = new Dictionary<Type, IIntegrationFeature>();
}
public void RegisterFeature<T>(IIntegrationFeature feature) where T:IIntegrationFeature
{
features.Add(typeof(T), feature);
}
public T GetFeature<T>() where T : IIntegrationFeature
{
IIntegrationFeature feature = features.TryGetValue(typeof(T), out feature) ? feature : null;
return (T)feature;
}
}
ChannelIntegration
类维护功能列表。您使用 RegisterFeature
要添加更多功能并确保是一个功能,您可以约束它们来实现 IIntegrationFeature
界面。因此,当您添加新功能时,您不会更改 ChannelIntegration
类,你用它。
IIntegratedSystem
将从 IChannelIntegration
访问功能基于运行时值。正如您所说,这要求使用抽象工厂。这看起来像
interface IChannelIntegrationFactory
{
IChannelIntegration CreateIntegration(string integrationType);
}
IIntegratedSystem
将使用该工厂创建 IChannelIntegration
为了实现这一点,我将使用构造函数注入(inject)机制。
class IntegratedSystem : IIntegratedSystem
{
private IChannelIntegrationFactory integrationFactory;
public IntegratedSystem(IChannelIntegrationFactory integrationFactory)
{
this.integrationFactory = integrationFactory;
}
public T GetFeature<T>(string integrationType) where T: IIntegrationFeature
{
T integrationFeature = default(T);
IChannelIntegration integration = integrationFactory.CreateIntegration(integrationType);
if (integration != null)
{
integrationFeature = (T)integration.GetFeature<T>();
}
return integrationFeature;
}
}
现在 IntegratedSystem
类正在使用 IChannelIntegrationFactory
创建一个 IChannelIntegration
基于运行时值,然后它将从中检索已实现的 IIntegrationFeature
如果有的话。
我们现在需要的是实现这个将创建 IChannelIntegration
的工厂。与他们的 IIntegrationFeature
让我们先创建一个新功能
interface ICustomFeature : IIntegrationFeature {}
class CustomFeature : ICustomFeature
{
}
基于此抽象工厂实现就像
class ChannelIntegrationFactory : IChannelIntegrationFactory
{
public IChannelIntegration CreateIntegration(string integrationType)
{
// use integrationType to decide witch IChannelIntegration to use
IChannelIntegration integration = new ChannelIntegration();
integration.RegisterFeature<ICustomFeature>(new CustomFeature());
return integration;
}
}
我们在这里创建了一个 ChannelIntegration
以其单一的功能。当然你可以有多个路径,就像你开始创建不同的 IChannelIntegrations
用自己的ICustomFeature
s 并检索基于 integrationType
的那个参数。
那么你如何消费它?
IIntegratedSystem system = new IntegratedSystem(new ChannelIntegrationFactory());
ICustomFeature customFeature = system.GetFeature<ICustomFeature>("Which Integration?");
if (customFeature != null)
{
//use this custom feature
}
else
{
// that's OK, will wait until is registered.
}
您想添加新功能吗?在抽象工厂实现中注册它。
So would you expect to create a new abstract factory of type ChannelIntegrationFactory for each different type of ChannelIntegration?
没有。工厂从具体实现列表中选择一个。这是一个例子
class ChannelIntegrationFactory : IChannelIntegrationFactory
{
public IChannelIntegration CreateIntegration(string integrationType)
{
IChannelIntegration integration = null;
switch (integrationType)
{
case "MobileIntegration":
integration = new ChannelIntegration();
integration.Register<ITapGestureTrack>(new TapGestureTrack());
break;
case "DesktopIntegration":
integration = new ChannelIntegration();
integration.Register<IClickTrack>(new ClickTracker());
integration.Register<ILargeImagesProvider>(new LargeImagesProvider());
break;
}
return integration;
}
}
您甚至可以制作 ChannelIntegration
作为抽象并创建专门的集成:
class MobileIntegration : ChannelIntegration
{
public MobileIntegration()
{
Register<ITapGestureTrack>(new TapGestureTrack());
}
}
class DesktopIntegration : ChannelIntegration
{
public DesktopIntegration()
{
Register<IClickTrack>(new ClickTracker());
Register<ILargeImagesProvider>(new LargeImagesProvider());
}
}
抽象工厂变成了
class ChannelIntegrationFactory : IChannelIntegrationFactory
{
public IChannelIntegration CreateIntegration(string integrationType)
{
IChannelIntegration integration = null;
switch (integrationType)
{
case "MobileIntegration":
integration = new MobileIntegration();
break;
case "DesktopIntegration":
integration = new DesktopIntegration();
break;
}
return integration;
}
}
只需将此类视为系统的 Bootstrap 类即可。这是唯一创建与功能集成的类。顺便说一句,这就是您可以使用您喜欢的 IoC 轻松启用依赖倒置的方法。 Fiddle
关于c# - 这是对接口(interface)的错误使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37806663/
编写一个仅用于集中其他接口(interface)的接口(interface)是好的做法还是坏的做法? interface InterfaceA : InterfaceB, InterfaceC { }
有没有一种方法可以确定具体类型从任意接口(interface)列表?我知道类型转换,但我想知道所有满意的接口(interface)。 例如,给定: type Mover interface { Mo
我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface): package node type
这是我的代码: type IA interface { FB() IB } type IB interface { Bar() string } type A struct {
示例 A: // pseudo code interface IFoo { void bar(); } class FooPlatformA : IFoo { void bar() {
合并它编译的 leppies 反馈 - 但 IMO 有一些缺点,我希望编译器强制每个子类定义它们自己的 Uri 属性。现在的代码: [] type UriUserControl() = inh
我正在构建一个项目,该项目从用户那里获取一个术语,然后执行谷歌搜索并返回一个 json 格式的标题列表。 我正在使用 serpwow API 来执行谷歌搜索并试图解析响应。 但是我收到的错误是: pa
我只想在其他接口(interface)中实现某些接口(interface),我不希望它们能够被类直接继承。 提前致谢! 最佳答案 您不能在 C# 中执行此操作 - 任何类都可以实现它有权访问的任何接口
我是 Go 的新手,还有一些我还没有掌握的技巧 例如,我有一个可以这样调用的函数: myVar.InitOperation("foo",Operator.EQUAL,"bar") myVar.Init
我有一个通用接口(interface)来描述对输出流的访问,如下所示: interface IOutput { function writeInteger(aValue:Int):Void;
我正在做一个项目,我想通过某种接口(interface)(最好是 USB)将光电探测器电路安装到计算机上。但是,由于我是新手,所以我不知道应该朝哪个方向处理这个问题。假设我有一个带有 USB 连接的光
背景 我正在尝试创建一个简单的应用程序,以真正理解DDD + TDD + etc的整个堆栈。我的目标是在运行时动态注入DAL存储库类。这让我 域和应用程序服务层可测试。我打算用“穷人的DI”来完成 现
在 Java 中,接口(interface)扩展接口(interface)是完全合法的。 UML 中的这种关系看起来像“扩展”关系(实线、闭合、未填充的箭头)还是“实现”关系(虚线、闭合、未填充的箭头
我想创建一个具有相等和比较函数默认实现的接口(interface)。 如果我从类型 IKeyable 中删除所有内容除了Key成员,只要我不添加默认实现,它就是一个有效的接口(interface)。从
COM 中的双接口(interface)是能够通过 DispInterface 或 VTable 方法访问的接口(interface)。 现在有人可以告诉我这两种方法之间到底有什么区别吗? 我认为 V
我有一个类方法,它返回一个可以迭代的员工列表。返回列表的最佳方式是什么?通常我只返回一个 ArrayList。然而,据我了解,界面更适合这种类型的操作。哪个是最好使用的界面?另外,为什么返回接口(in
我想从包装类外部实例化一个内部非静态接口(interface)。 这可能吗? 考虑以下代码: shared class AOuterClass() { Integer val = 3; shared
我为一个类编写了一个接口(interface),如下所示: public interface IGenericMultipleRepository { Lazy> addresses { ge
我是 UML 的初学者,现在我正在创建一个序列图,问题是我想根据用户输入实现 DAO 接口(interface)。如何在时序图中正确绘制以实现接口(interface)。 最佳答案 您不会在 SD 上
要使用 jsr 303 验证创建有条件验证的组,请将接口(interface)类传递给注释,如下所示: @NotEmpty (groups={UpdateValue.class}) 我有很多不同的接口
我是一名优秀的程序员,十分优秀!