Questions tagged «interfaces»

有关接口相关设计注意事项的问题,例如接口编程。

3
泛型与通用接口?
我不记得上次写泛型类的时间。每次经过思考后我都认为不需要时,我认为不需要它。 这个问题的第二个答案让我要求澄清(因为我还不能发表评论,所以我提出了一个新问题)。 因此,让我们以给定的代码为例,说明需要泛型的情况: public class Repository<T> where T : class, IBusinessOBject { T Get(int id) void Save(T obj); void Delete(T obj); } 它具有类型约束: IBusinessObject 我通常的想法是:该类只能使用IBusinessObject,使用该类的也是如此Repository。存储库存储这些对象IBusinessObject,最有可能的客户端Repository将希望通过IBusinessObject接口获取和使用对象。那为什么不只是为了 public class Repository { IBusinessOBject Get(int id) void Save(IBusinessOBject obj); void Delete(IBusinessOBject obj); } 那个例子不好,因为它只是另一种类型的集合,而通用集合是经典的。在这种情况下,类型约束看起来也很奇怪。 实际上,该示例class Repository<T> where T : class, IBusinessbBject与class BusinessObjectRepository我非常相似。泛型是要修复的东西。 重点是:泛型除了集合之外,是否对其他任何东西都有用,并且类型约束不会使泛型成为专用对象,就像使用类约束而不是在类内部使用泛型类型参数一样?

4
谁扩展接口?又为什么呢
AFAIK,我的班级extends父类和implements接口。但是我遇到了无法使用的情况implements SomeInterface。它是泛型类型的声明。例如: public interface CallsForGrow {...} public class GrowingArrayList <T implements CallsForGrow> // BAD, won't work! extends ArrayList<T> 在implements语法上禁止使用。我首先想到的是,完全禁止在<>中使用接口,但是没有。有可能,我只需要使用 extends而不是implements。结果,我正在“扩展”接口。这个另一个例子有效: public interface CallsForGrow {...} public class GrowingArrayList <T extends CallsForGrow> // this works! extends ArrayList<T> 在我看来,这似乎是句法上的不一致。但是也许我不理解Java 6的一些技巧?我应该在其他地方扩展接口吗?我要扩展的接口是否应该具有某些特殊功能?

6
作者将接口引用强制转换为任何实现是什么意思?
我目前在试图掌握C#的过程,所以我读通过C#自适应编码由加里·麦克莱恩大厅。 他撰写有关模式和反模式的文章。在实现与接口部分中,他写道: 不熟悉接口编程概念的开发人员通常很难放开接口背后的内容。 在编译时,接口的任何客户端都不应该知道接口正在使用哪种接口实现。这些知识可能导致错误的假设,从而使客户端耦合到接口的特定实现。 想象一下一个常见的示例,其中一个类需要在持久性存储中保存一条记录。为此,它正确地委托给一个接口,该接口隐藏了所使用的持久性存储机制的详细信息。但是,对运行时使用接口的哪个实现进行任何假设都是不正确的。例如,将接口引用强制转换为任何实现都是一个坏主意。 这可能是语言障碍,或者是我缺乏经验,但是我不太明白这意味着什么。这是我的理解: 我有一个免费的有趣的项目来练习C#。我在那里上课: public class SomeClass... 此类在很多地方都使用过。在学习C#时,我读到最好使用接口抽象,因此我做了以下工作 public interface ISomeClass <- Here I made a "contract" of all the public methods and properties SomeClass needs to have. public class SomeClass : ISomeClass <- Same as before. All implementation here. 因此,我进入了所有一些类引用,并用ISomeClass替换了它们。 除了在构造中,我写过: ISomeClass myClass = new SomeClass(); …

2
最小惊讶原理(POLA)和界面
25年前,当我学习C ++时,我被教导说接口应该是宽容的,并且尽可能不在乎方法的调用顺序,因为消费者可能无法访问源代码或文档来代替这个。 但是,每当我指导初级程序员和高级开发人员听到我的消息时,他们都会惊讶地做出反应,这让我怀疑这是否真的是一件事情,或者它是否已经过时了。 像泥一样清澈? 考虑具有以下方法的接口(用于创建数据文件): OpenFile SetHeaderString WriteDataLine SetTrailerString CloseFile 现在,您当然可以按顺序浏览这些文件,但是说您不关心文件名(认为a.out)或包括什么标题和尾部字符串,您可以致电AddDataLine。 一个不太极端的示例可能是省略标题和结尾。 还有一种可能是在打开文件之前设置标题和结尾字符串。 这是公认的接口设计原则,还是只是在命名之前采用POLA方式? 注意:不要被这个界面的细节所困扰,这仅仅是一个例子。

5
枚举会创建脆弱的接口吗?
考虑下面的示例。对ColorChoice枚举的任何更改都会影响所有IWindowColor子类。 枚举会导致界面脆弱吗?是否有比枚举更好的东西可以提供更多的多态灵活性? enum class ColorChoice { Blue = 0, Red = 1 }; class IWindowColor { public: ColorChoice getColor() const=0; void setColor( const ColorChoice value )=0; }; 编辑:很抱歉使用颜色作为我的示例,这不是问题所在。这是一个不同的示例,它避免出现红色鲱鱼,并提供有关灵活性的更多信息。 enum class CharacterType { orc = 0, elf = 1 }; class ISomethingThatNeedsToKnowWhatTypeOfCharacter { public: CharacterType getCharacterType() const; void setCharacterType( const CharacterType …

4
前端开发人员是否应该为后端开发人员指定JSON格式?
我在一个项目中担任前端角色。是否应该为我的后端团队成员指定他们的PHP返回我的JavaScript的JSON确切格式? 例如,我应该告诉他们,他们应该使用类似于此处所述的格式: 构造JSON以便前端使用的正确方法 还是应该尽可能地保持角色的无菌,只用文字描述我从后端接口需要的输入和输出?(当然,如果发生这种情况,就我而言,处理它们的不同数据结构格式可能会更加困难)

5
何时使用接口(单元测试,IoC?)
我怀疑我在这里犯了一个小学生错误,正在寻求澄清。我的解决方案(C#)中有很多类-敢于说大多数-我最终为之编写了相应的接口。例如,即使我永远不可能用其他实现替换该计算器,也可以使用“ ICalculator”接口和实现该接口的“ Calculator”类。而且,这些类中的大多数与其依赖项都位于同一个项目中-实际上,它们仅需为internal,但最终成为public实现其各自接口的副作用。 我认为这种为所有内容创建接口的做法源于一些谬误: 1)我本来以为创建单元测试模拟必须有一个接口(我使用的是Moq),但是后来我发现,如果类的成员为virtual,则可以模拟该类,并且该类具有无参数的构造函数(如果我错了)。 2)我本来以为必须要有一个接口才能向IoC框架(Castle Windsor)注册一个类,例如 Container.Register(Component.For<ICalculator>().ImplementedBy<Calculator>()... 实际上,我可以针对自身注册具体类型: Container.Register(Component.For<Calculator>().ImplementedBy<Calculator>()... 3)使用接口(例如,用于依赖项注入的构造函数参数)会导致“松散耦合”。 那我对接口发疯了吗?!我知道您通常会“使用”接口(例如公开公共API)或“可插入”功能之类的场景。我的解决方案只有少数适​​合此类用例的类,但我想知道是否所有其他接口都是不必要的,应该删除?关于上述第3点,如果这样做,我是否会违反“松散耦合”? 编辑:-我只是在玩Moq,它似乎要求方法是公共的和虚拟的,并具有公共的无参数构造函数,以便能够模拟它们。这样看来我不能拥有内部类了吗?

4
如何最好地组织类和接口文件?
好的..经过所有讨论之后,我将稍微更改我的问题以更好地反映我正在处理的具体示例。 我有两个类,ModelOne和ModelTwo,这些类执行类似的功能,但彼此无关。但是,我有一个第三类CommonFunc,其中包含一些公共功能,这两种功能都在两者中实现ModelOne,ModelTwo并且已根据进行了分解DRY。这两个模型是在ModelMain类中实例化的(它本身是在更高级别上实例化的,但是我将在这个级别上停止)。 我正在使用的IoC容器是Microsoft Unity。我不假装自己是专家,但是我的理解是,您在容器中注册了一个接口和类的元组,当您想要一个具体的类时,您会向IoC容器询问与特定接口匹配的任何对象。这意味着对于我要从Unity实例化的每个对象,都必须有一个匹配的接口。因为我的每个类都执行不同的功能(且不重叠),所以这意味着接口和类1之间的比例为1:1。但是,这并不意味着我正在为每个编写的类都刻苦地编写一个接口。 因此,在代码方面,我最终得到2: public interface ICommonFunc { } public interface IModelOne { ICommonFunc Common { get; } .. } public interface IModelTwo { ICommonFunc Common { get; } .. } public interface IModelMain { IModelOne One { get; } IModelTwo Two { get; } .. } public class …

5
在C#界面中使用关键字“使用”
当我使用C#编写一些代码并使用Visual Studio 2010定义接口时,它总是包含许多“使用”语句(如示例中所示) using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestEngine.TestNameSpace { interface ITest1 { bool testMethod(int xyz); } } 我想知道这些是做什么用的,以及它们是否真的必要。我可以省掉这些吗?仅当我在界面说明中使用这些部件时才需要它们吗?

2
PHP中的非法:是否存在OOP设计原因?
下面的接口继承在PHP中是非法的,但我认为它在现实生活中将非常有用。下面的设计是否存在实际的反模式或已记录的问题,PHP正在保护我免受其侵扰? <?php /** * Marker interface */ interface IConfig {} /** * An api sdk tool */ interface IApi { public __construct(IConfig $cfg); } /** * Api configuration specific to http */ interface IHttpConfig extends IConfig { public getSomeNiceHttpSpecificFeature(); } /** * Illegal, but would be really nice to have. …

5
将对象两次传递给相同的方法还是与合并的接口合并?
我有一种方法,可以在与数字板交谈后创建数据文件: CreateDataFile(IFileAccess boardFileAccess, IMeasurer boardMeasurer) 这里boardFileAccess和boardMeasurer是相同的实例Board对象,同时实现了IFileAccess和IMeasurer。IMeasurer在这种情况下,仅用于一种方法,该方法将使板上的一个引脚处于活动状态以进行简单的测量。然后,使用将该测量的数据本地存储在板上IFileAccess。Board位于一个单独的项目中。 我得出的结论CreateDataFile是,通过快速测量然后存储数据来做一件事,对于其他使用此代码然后必须进行测量并写入文件的人来说,使用同一方法进行这两种操作更直观作为单独的方法调用。 对我来说,将同一对象两次传递给方法似乎很尴尬。我认为做一个本地接口IDataFileCreator,可以扩展IFileAccess和IMeasurer再有一个包含一个实现Board的实例,将只需要调用所需的Board方法。考虑到同一板对象将始终用于测量和文件写入,将同一对象两次传递给方法是否是一种不好的做法?如果是这样,使用本地接口和实现是否是合适的解决方案?

3
为什么接口在实现松散耦合方面比父类更有用?
(出于这个问题的目的,当我说“接口”时,我的意思是语言结构interface,而不是用另一种意义上的“接口”,即,一个类提供了与外界进行交流的外部方法,并且操纵它。) 松散耦合可以通过使对象依赖于抽象而不是具体类型来实现。 这允许松散耦合,主要有两个原因:1-与具体类型相比,抽象的更改可能性较小,这意味着从属代码中断的可能性较小。2-不同的具体类型可以在运行时使用,因为它们都适合抽象。以后也可以添加新的具体类型,而无需更改现有的从属代码。 例如,考虑一个类Car和两个子类Volvo和Mazda。 如果您的代码依赖于Car,则可以在运行时使用Volvo或Mazda。同样,以后可以添加其他子类,而无需更改从属代码。 另外,Car-是一种抽象-,更改的可能性小于Volvo或Mazda。汽车在相当长的一段时间内大体相同,但沃尔沃和马自达的变化可能性更大。即抽象比具体类型更稳定。 所有这些都是为了表明我理解什么是松散耦合以及如何通过依赖抽象而不是依赖具体实现来实现松耦合。(如果我写的东西不准确,请这样说)。 我不明白的是: 抽象可以是超类或接口。 如果是这样,为什么接口因其允许松耦合而受到特别赞扬?我没有看到它与使用超类有什么不同。 我看到的唯一区别是:1-接口不受单一继承的限制,但这与松耦合这一主题无关。2-接口更加“抽象”,因为它们根本没有实现逻辑。但是,我仍然不明白为什么会有如此大的不同。 请向我解释为什么说接口在允许松散耦合方面是很棒的,而简单的超类却不是。

5
接口的功能编程替代方案是什么?
如果我想以“功能性”风格进行编程,我将用什么替换接口? interface IFace { string Name { get; set; } int Id { get; } } class Foo : IFace { ... } 也许一个Tuple<>? Tuple<Func<string> /*get_Name*/, Action<String> /*set_Name*/, Func<int> /*get_Id*/> Foo; 首先使用接口的唯一原因是,我总是希望某些属性/方法可用。 编辑:有关我在想什么/尝试的更多详细信息。 说,我有一个方法,它具有三个功能: static class Blarf { public static void DoSomething(Func<string> getName, Action<string> setName, Func<int> getId); } 对于BarI 的实例,可以使用此方法: …

6
抽象类,接口和何时使用它们之间有什么区别
最近,我开始全神贯注于OOP,现在到了这样的地步,我越了解抽象类和接口之间的差异,就越会感到困惑。到目前为止,都无法实例化。接口或多或少是结构的蓝图,它们通过能够部分实现代码来确定骨架和摘要是否不同。 我想通过我的具体情况了解更多有关这些的信息。这是我第一个问题的链接,如果您需要更多背景信息:新班级的良好设计模型是什么? 这是我创建的两个类: class Ad { $title; $description $price; function get_data($website){ } function validate_price(){ } } class calendar_event { $title; $description $start_date; function get_data($website){ //guts } function validate_dates(){ //guts } } 因此,如您所见,这些类几乎是相同的。这里没有显示,但也有其他的功能,like get_zip(),save_to_database()跨越我的课是常见的。我还添加了其他类“汽车”和“宠物”,这些类具有所有常用方法,并且当然具有这些类的特定属性(例如,里程,重量)。 现在,我违反了DRY原则,并且正在多个文件中管理和更改相同的代码。我打算开设更多课程,例如船,马或其他。 那么这是我要使用接口或抽象类的地方吗?根据我对抽象类的了解,我将使用超类作为模板,并将所有常见元素内置到抽象类中,然后仅添加将来类中特别需要的项目。例如: abstract class content { $title; $description function get_data($website){ } function common_function2() { } function common_function3() …

6
我可以将接口方法视为抽象方法吗?
我正在考虑这一点,我对此有些怀疑。 当我声明一个接口时,例如: public interface MyInterface { public void method1(); public void method2(); } 这些接口方法可以被认为是抽象的吗?我的意思是抽象方法的概念是: 抽象方法是已声明但不包含任何实现的方法。 那么,可以将这些方法视为抽象方法吗?它们不是“纯”抽象方法,因为我没有使用这个abstract词,但从概念上讲,它们看起来像是。 您能告诉我些什么? 谢谢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.