这个“接口编程”是如何实现的? 东西工作吗?

发布于 2024-07-20 11:31:52 字数 329 浏览 5 评论 0原文

我喜欢“接口编程”并避免使用“new”关键字的想法。

但是,当我有两个具有相同接口但设置根本不同的类时,我该怎么办? 在不详细了解我的具体代码的情况下,我有一个带有方法“DoStuff”的接口。 两个类实现了这个接口。 一种非常简单,不需要初始化。 另一个有五个不同的变量需要设置。 当组合起来时,它们允许类在调用 DoStuff 时有数百万种工作方式。

那么我什么时候“新”这些课程呢? 我考虑过使用工厂,但我认为它们不适合这种情况,因为设置存在巨大差异。 (顺便说一句:实际上有大约十个不同的类使用该接口,每个类都允许形成复杂管道的一部分,并且每个类都有不同的配置要求)。

I like the idea of "programming to interfaces" and avoiding the use of the "new" keyword.

However, what do I do when I have two classes that have the same interface but are fundamentally different to set up. Without going into detail about my specific code, I have an interface with a method, "DoStuff". Two classes implement this interface. One is very simple and requires no initialisation to speak of. The other has five different variables that need to be set up. When combined, they allow for literally millions of ways for the class to work when DoStuff is called.

So when do I "new" these classes? I though about using factories but I don't think they are suitable in this case because of the vast difference in setup. (BTW: there are actually about ten different classes using the interface, each allowing the formation of part of a complex pipeline and each with different configuration requirements).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我三岁 2024-07-27 11:31:52

我认为您可能误解了接口编程的概念。 在面向对象语言中,您始终必须使用 new 关键字来创建对象的新实例。 仅仅因为您对接口进行编程并不能消除该要求。

对接口进行编程意味着所有具体类的行为都在接口中定义,而不是在具体类本身中定义。 因此,当您定义变量的类型时,您将其定义为接口而不是具体类型。

在您的情况下,只需在具体类中实现 DoStuff 即可,因为每个类都需要实现它(无论是简单地实现还是与其他 10 个初始化对象和设置一起实现)。 例如,如果您有一个接口 IInterface 和实现 IInterface 的类 SomeClass。 您可以这样声明 SomeClass 的实例:

IInterface myInstance = new SomeClass();

这允许您将此实例传递给其他函数,而不必让这些函数担心该实例的类的实现细节。

I think you may be misunderstanding the concept of programming to interfaces. You always have to use the new keyword in object oriented languages to create new instances of objects. Just because you program to interfaces doesn't remove that requirement.

Programming to an interface simply means that all your concrete classes have their behavior defined in an interface instead of in the concrete class itself. So when you define the type of a variable, you define it to be the interface instead of a concrete type.

In your case, just implement DoStuff in your concrete classes as each class needs it implemented (whether doing it simply or with 10 other initialized objects and setup). For example, if you have an interface IInterface and class SomeClass which implements IInterface. You might declare an instance of SomeClass as such:

IInterface myInstance = new SomeClass();

This allows you to pass this instance around to other functions without having to have those functions worry about the implementation details of that instance's class.

风向决定发型 2024-07-27 11:31:52

好吧,你确实有 3 个选择。 使用 new、使用工厂或使用 DI 容器。 对于 DI 容器,您的五个变量很可能需要位于某种配置文件中。

但说实话,这听起来像是你把自己逼到了墙角,让自己的生活变得比实际需要的更加困难。 不要按照某种理想的方式进行编码,而是以最有利于解决手头问题的方式进行编码。 并不是说你应该对其进行修改,而是说你不想使用新的,这确实让你的生活变得比需要的更困难......

Well you really have 3 options. Use new, use a factory or use an DI container. With a DI container your five variables would most likely need to be in a configuration file of some sorts.

But to be completely honest it sounds like you're making your life harder than it needs to be by forcing yourself into a corner. Instead of coding to some ideal, rather code in a manner which best facilitates solving the problem at hand. Not saying you should do a hack job of it, but really, saying you don't want to use new, that is really making your life harder than it needs to be...

财迷小姐 2024-07-27 11:31:52

无论您使用什么,在某些时候您都必须构造类的实例才能使用它们,这是没有办法解决的。

如何去做取决于您想要完成的任务以及这些类的语义。

参加你提到的那些领域的课程。

可以从某个地方读取这些字段吗? 例如配置文件? 如果是这样,也许您所需要的只是一个默认构造函数,用于从此类配置文件中初始化这些字段。

但是,如果这些字段的内容确实需要从外界传入,那就没有办法了。

也许您应该看看 IoC 容器和依赖注入?

Regardless of what you use, at some point you're going to have to construct instances of your classes in order to use them, there's no way around that.

How to go about doing that depends on what you want to accomplish, and the semantics of those classes.

Take the class you mention with those fields.

Can those fields be read from somewhere? A configuration file, as an example? If so, perhaps all you need is just a default constructor that initializes those fields from such a configuration file.

However, if the content of those fields really needs to be passed in from the outside world, there's no way around that.

Perhaps you should look at a IoC container and Dependency Injection?

辞慾 2024-07-27 11:31:52

如果您将如此多的配置参数传递到您的类中,它可能有太多的责任。 您应该考虑将其分解为仅具有单一职责的更小的类。

避免使用 new 关键字可能很有价值,因为它会创建对实现类的依赖。 更好的解决方案是使用依赖注入。

例如

public interface IDoStuff
{
    void DoStuff();
}

public class DoStuffService
{
    private IDoStuff doer;

    public DoStuffService()
    {
        //Class is now dependant on DoLotsOfStuff
        doer = new DoLotsOfStuff(1,true, "config string");
    }
}

public class DoStuffBetterService
{
    private IDoStuff doer;

    //inject dependancy - no longer dependant on DoLotsOfStuff
    public DoStuffBetterService(IDoStuff doer)
    {
        this.doer = doer;
    }
}

,显然您仍然必须创建在某处传递的 IDoStuff 对象。
控制反转 (IoC) 容器是帮助实现此目的的好工具。
如果您有兴趣了解更多信息,这里有一个关于Castle Windsor Container的很好的教程。 (还有很多其他的 IoC 容器,我只是碰巧使用了这个。)

您问题中的示例非常抽象,所以我希望这个答案有所帮助。

If you are passing that many configuration parameters into your class it may have too many responsibilities. You should look into breaking it up into smaller classes that only have a single responsibility.

Avoiding the new keyword can be valuable because it creates a dependancy on the implementing class. A better solution would be to use Dependancy Injection.

for example

public interface IDoStuff
{
    void DoStuff();
}

public class DoStuffService
{
    private IDoStuff doer;

    public DoStuffService()
    {
        //Class is now dependant on DoLotsOfStuff
        doer = new DoLotsOfStuff(1,true, "config string");
    }
}

public class DoStuffBetterService
{
    private IDoStuff doer;

    //inject dependancy - no longer dependant on DoLotsOfStuff
    public DoStuffBetterService(IDoStuff doer)
    {
        this.doer = doer;
    }
}

Obviously you still have to create the IDoStuff object being passed in somewhere.
An Inversion of Control (IoC) container is a good tool to help with implementing this.
Here is a good tutorial for Castle Windsor Container if you are interested in learning more. (There are many other IoC containers, I just happen to use this one.)

The example in your question was very abstract, so I hope this answer is helpful.

ま柒月 2024-07-27 11:31:52

如果我理解正确的话,问题在于不同的初始化。 您需要提供具有相同接口的两个类。 一个不需要任何东西,另一个需要一些参数并调用一些复杂的初始化。

您应该使用一个获取InitializationParameter 的构造函数。 两个班级都应该得到它。 一个具有简单的界面,不需要从中获取任何东西。 另一个需要参数并从中获取它们。

如果您担心初始化,您可以使用工厂,只需要求它提供一些提供此初始化参数的接口,工厂将根据您提供的值创建、初始化并返回对象。

如果有不清楚的地方 - 请询问。

If I understand you correctly the problem is with different initialization. You need to provide for two classes that have the same interface. One does not need anything, and the other needs some paramaters and calls some complex initialization.

You should use have a constructor that gets InitializationParameter. Both classes should get it. One with a simple interface that does not need to get anything from it. The other that needs params and will get them from it.

If you are concerned about initialization you can use factory, just ask it for some interface providing this init parameter and factory will create, init and return to you the object according to the values you provided.

If something is not clear - please ask.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文