带接口的优雅设计(C#中) [英] Elegant design with interfaces (in C#)

查看:109
本文介绍了带接口的优雅设计(C#中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于最佳使用接口的问题:


假设有一个''Master''类需要实现一些

接口:


级硕士:I1,I2,I3

{

}


实际代码已存在于较小的类中,每个类实现其中一个或两个接口:


class Group1:I1

{

}


class Group2:I2,I3

{

}


目标是让较大的Master对象作为替换

用于(即包装)两个较小的Group对象。 IOW,我需要

才能调用Master.Function1(),就像我调用Group1.Function1()一样。

或者将I1指针转换为工作状态在Master中的代码。


我想要实例化Group1和Group2并且'指向'

主对象'的接口在他们身上整体而言。我正在寻找

以某种方式让一家工厂说:


等级大师:I1,I2,I3

{

I1 = new Group1();

I2 = new Group2();

...

}


当然我知道上面是一个理想化的抽象,但我会像b $ b一样避免在每个界面中映射每个单独的函数

手工制作。最好的方法是什么?

Question about best use of interfaces:

Say there''s a ''Master'' class that needs to implement a few
interfaces:

class Master : I1, I2, I3
{
}

The actual code already exists in smaller classes that each
implement one or two of those interfaces:

class Group1 : I1
{
}

class Group2 : I2, I3
{
}

The goal is to have the larger Master object serve as a substitute
for (ie wrap) the two smaller Group objects. IOW, I need to be
able to call Master.Function1() just like I''d call Group1.Function1().
Or cast an I1 pointer to working code in Master.

I''d love to just instantiate Group1 and Group2 and ''point'' the
Master object''s interfaces at them en masse. I''m looking
for some way for a factory to say:

class Master : I1, I2, I3
{
I1 = new Group1();
I2 = new Group2();
...
}

Of course I know the above is an idealized abstraction, but I''d
like avoid having to map each individual function in every interface
by hand. What is the best way to do this?

推荐答案

你怎么没有''主'级课程另外三个

接口,而是将它封装起来。


class Master

{

public I1 referenceI1;

public I2 referenceI2;


public Master()

{

referenceI1 = new I1();

referenceI2 = new I2();

}

}


公共电话代码()

{

主人m =新主人();

m.referenceI1.I1method();

m.referenceI2.I2method();

}


nope ...不是OO。但话说回来,有一个原因是C#不支持多重继承




这是效率低下,缺陷和脆弱的根源码。不是很好

练习。我的猜测是你从C ++转到C#并且你认为你可以使用这种机制让它运行起来。


如果你真的崩溃了你使用CVA等技术的问题,你可以

几乎总是考虑到多重继承并最终得到更好的设计。在那些罕见的情况下,你不能......上面的kludge

或你引用的那个(每个方法的硬编码调用)。


想想你想要做什么,我愿意打赌你好吧b $ b可能不需要多重继承。


好好运,

-

--- Nick Malik [微软]

MCSD,CFPS,认证Scrummaster
http://blogs.msdn.com/nickmalik


免责声明:本论坛中表达的意见是我自己的意见,而不是我雇主的b $ b代表。

我不代表我的雇主回答问题。我只是一个帮助程序员的
程序员。

-

" _dee" <无**** @ nomail.com>在消息中写道

news:86 ******************************** @ 4ax.com ...
How about you don''t have the ''master'' class implement the three other
interfaces, but rather have it encapsulate them.

class Master
{
public I1 referenceI1;
public I2 referenceI2;

public Master()
{
referenceI1 = new I1();
referenceI2 = new I2();
}
}

public callingcode()
{
Master m = new Master();
m.referenceI1.I1method();
m.referenceI2.I2method();
}

nope... not OO. But then again, there''s a reason that multiple inheritance
is not supported in C#.

It''s a source of inefficiency, defects, and brittle code. Not a good
practice. My guess is that you came over to C# from C++ and you figure you
can use this mechanism to get it to work.

If you really break down your problem with techniques like CVA, you can
nearly always factor out the multiple inheritance and end up with a better
design. In those rare cases where you cannot... either do the kludge above
or the one you refer to (hard-coding calls for each method).

Think about what you are trying to do and I''m willing to bet that you
probably don''t need the multiple inheritance.

Good luck,
--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I''m just a
programmer helping programmers.
--
"_dee" <no****@nomail.com> wrote in message
news:86********************************@4ax.com...
关于最佳使用接口的问题:

说有一个''Master''类需要实现一些
接口:<大师:I1,I2,I3



实际的代码已经存在于较小的类中,每个类都实现一个或者其中两个接口:

类Group1:I1
{
}

类Group2:I2,I3
{
}

目标是让更大的Master对象充当(即包装)两个较小的Group对象的替代品。 IOW,我需要能够调用Master.Function1(),就像我调用Group1.Function1()一样。
或者在Master中使用I1指针指向工作代码。

我很乐意只是实例化Group1和Group2,并且点'
主对象'的接口就在他们身边。我正在寻找工厂的某种方式说:

类Master:I1,I2,I3
{/ I1 =新Group1();
I2 =新的Group2();
......
}

当然我知道上面是一个理想化的抽象,但我会
就像避免必须手动映射每个界面中的每个单独功能一样。最好的方法是什么?
Question about best use of interfaces:

Say there''s a ''Master'' class that needs to implement a few
interfaces:

class Master : I1, I2, I3
{
}

The actual code already exists in smaller classes that each
implement one or two of those interfaces:

class Group1 : I1
{
}

class Group2 : I2, I3
{
}

The goal is to have the larger Master object serve as a substitute
for (ie wrap) the two smaller Group objects. IOW, I need to be
able to call Master.Function1() just like I''d call Group1.Function1().
Or cast an I1 pointer to working code in Master.

I''d love to just instantiate Group1 and Group2 and ''point'' the
Master object''s interfaces at them en masse. I''m looking
for some way for a factory to say:

class Master : I1, I2, I3
{
I1 = new Group1();
I2 = new Group2();
...
}

Of course I know the above is an idealized abstraction, but I''d
like avoid having to map each individual function in every interface
by hand. What is the best way to do this?



Nick Malik [微软]写道:
Nick Malik [Microsoft] wrote:
你呢?没有''主'级实现其他三个接口,而是将它封装起来。

类大师
公共I1 referenceI1;
public I2 referenceI2;

public Master()
{
referenceI1 = new I1();
referenceI2 = new I2();
}

公共调用码()
{
Master m = new Master();
m.referenceI1.I1method();
m.referenceI2.I2method();
}

不...不是OO。但话说回来,C#中不支持多重继承的原因。
这是低效率,缺陷和脆弱代码的根源。不是很好的练习。我的猜测是你从C ++转到C#并且你认为你可以使用这种机制让它工作。
How about you don''t have the ''master'' class implement the three other
interfaces, but rather have it encapsulate them.

class Master
{
public I1 referenceI1;
public I2 referenceI2;

public Master()
{
referenceI1 = new I1();
referenceI2 = new I2();
}
}

public callingcode()
{
Master m = new Master();
m.referenceI1.I1method();
m.referenceI2.I2method();
}

nope... not OO. But then again, there''s a reason that multiple
inheritance is not supported in C#.

It''s a source of inefficiency, defects, and brittle code. Not a good
practice. My guess is that you came over to C# from C++ and you
figure you can use this mechanism to get it to work.




我总是发现一个很难相信论点。如果我看看艾丽斯如何做MI,我不认为每天的代码都存在重大问题。

当然,角落案件一直存在问题,但是那个'还有SI的

案例。


如果看一下界面,它们就是定义多种类型的方式

继承,您自己填写实现。使用

多次IMPLEMENTATION继承(即简称为MI)

您可以免费获得该实现。没错,你可以轻松地用足球拍摄自己的足球,但这也是SI +多种类型的情况

继承:因为你必须提供实现自己,你这个b $ b最终可能会有重复的代码。


在这种特殊情况下,我同意聚合可能是好的

方法,其中master简单地继承所有接口,并且
将实现委托给Group1的聚合实例和

Group2。虽然恕我直言并不理想。


FB


-

---------- -------------------------------------------------- ------------

LLBLGen Pro的首席开发人员,.NET的高效O / R映射器

LLBLGen Pro网站: http://www.llblgen.com

我的.NET博客:< a rel =nofollowhref =http://weblogs.asp.net/fboumatarget =_ blank> http://weblogs.asp.net/fbouma

Microsoft MVP(C#)

------------------------------------- -----------------------------------



I always find that a hard to believe argument. If I look at how Eiffel
does MI, I dont think there are major problems with every day code.
Sure, there are always problems with corner cases, but that''s also the
case with SI.

If you look at interfaces, they''re a way to define multiple TYPE
inheritance, where you fill in the implementation yourself. With
multiple IMPLEMENTATION inheritance (i.e. what''s called MI in short)
you get that implementation for free. True, you can shoot yourself in
the foot easily, but that''s also the case with SI + multiple type
inheritance: because you''ve to provide the implementation yourself, you
can end up with duplicate code.

In this particular case, I agree that aggregation is perhaps a good
approach, where the master simply inherits all the interfaces and
delegates the implementation to aggregated instances of Group1 and
Group2. Though IMHO not ideal.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------


2006年6月24日星期六02:11:07 -0700,Nick Malik [微软]

< ni ******* @ hotmail.nospam.com>写道:
On Sat, 24 Jun 2006 02:11:07 -0700, "Nick Malik [Microsoft]"
<ni*******@hotmail.nospam.com> wrote:
你怎么没有''主''类实现其他三个
接口,而是让它封装它们。

班级大师
{公共I1 referenceI1;
公共I2 referenceI2;

公共大师()
{
referenceI1 =新的I1();
referenceI2 = new I2();
}

公共调用码()
{
Master m = new Master();
m.referenceI1.I1method();
m.referenceI2.I2method();
}


感谢您的回复,尼克。目标是避免上面的第二个参考水平(referenceI1)。这是一个工厂可以将b-b
组合成一个更大的实体,被认为是一个更大的实体,作为一个主。对象并将其传递给使用它的函数,而不需要知道什么更多的接口。

用于调用较小子对象的用户函数现在可以使用

较大的一个。


想想可能是一个蹩脚的比喻,说你有选择

来使用模拟3D图形,或使用硬件加速3D。那里

是对象:


Sim3DCircle:IDrawCircle

Sim3DBox:IDrawBox

Accel3DCircle:IDrawCircle

Accel3DBox:IDrawBox


您希望工厂将这些放在一个更大的对象中,根据可用的硬件,
,然后传递那个更大的对象

,好像它直接实现了IDrawCircle和IDrawBox。所以在

用户方面,你可以这样做:


Master M = Factory(params); //工厂组装子对象

IDrawCircle IDC =(IDrawCircle)Master;

IDrawBox IDB =(IDrawBox)Master;


你不需要知道工厂放在Master

对象中的内容。 (这听起来像是一个设计模式练习,

但是我对工厂如何连接Master'的
内部结构更感兴趣


上面的接口结构类似于在DirectX中完成,对于

实例,你可以创建一个FilterGraph,然后转换IMediaControl,
$ b来自FilterGraph对象的$ b等。 IMediaControl可以控制一个

视频文件,一个音频文件等。用户不需要知道。


但魅力的一部分是接口可以直接投射。

nope ...不是OO。但话说回来,有一个原因是C#不支持多重继承。

这是低效率,缺陷和脆弱代码的根源。不是很好的练习。我的猜测是你从C ++转到C#并且你认为你可以使用这种机制来使它工作。


我可能会遗漏一些东西,但我认为

接口的重点是解决多重继承(MI)的问题,

包括钻石继承模型。


所以虽然我确实来自C ++(并不是每个人?),但我从来没有

迷恋MI。事实上,我从来没有看过多个接口,因为

多重继承。

如果你真的用CVA这样的技术解决你的问题,你可以
几乎总是考虑到多重继承并最终得到更好的设计。在那些罕见的情况下,你不能......或者上面的kludge或者你所指的那个(每种方法的硬编码调用)。

想想你想要的是什么做,而且我愿意打赌你可能不需要多重继承。
How about you don''t have the ''master'' class implement the three other
interfaces, but rather have it encapsulate them.

class Master
{
public I1 referenceI1;
public I2 referenceI2;

public Master()
{
referenceI1 = new I1();
referenceI2 = new I2();
}
}

public callingcode()
{
Master m = new Master();
m.referenceI1.I1method();
m.referenceI2.I2method();
}
Thanks for your reply, Nick. The objective was to avoid the second
level of reference (referenceI1) above. This is so a factory can
assemble groups of sub-objects into one larger entity that is regarded
as a "Master" object and pass that to a function that uses it without
knowing anything more than what interfaces are available.
User-functions that used to call the smaller sub-objects can now use
the larger one.

To think of what is probably a crappy analogy, say you had the option
to use simulated 3D graphics, or to use hardware-accelerated 3D. There
are objects:

Sim3DCircle : IDrawCircle
Sim3DBox : IDrawBox
Accel3DCircle : IDrawCircle
Accel3DBox : IDrawBox

You want the factory to put those together into a larger object,
according to what hardware is available, then pass that larger object
as though it implements IDrawCircle and IDrawBox directly. So on the
user side, you could do this:

Master M = Factory(params); // factory assembles sub-objects
IDrawCircle IDC = (IDrawCircle)Master;
IDrawBox IDB = (IDrawBox)Master;

You would not need to know what the factory put inside the Master
object. (This is starting to sound like a Design Patterns excercise,
but I''m more interested in how the factory would wire up the Master''s
internals)

Something like the interface structure above is done in DirectX, for
instance, where you can create a FilterGraph, then cast IMediaControl,
etc. from the FilterGraph object. IMediaControl can be controlling a
video file, an audio file, etc. The user doesn''t need to know.

But part of the charm is that the interfaces can be cast directly.
nope... not OO. But then again, there''s a reason that multiple inheritance
is not supported in C#.

It''s a source of inefficiency, defects, and brittle code. Not a good
practice. My guess is that you came over to C# from C++ and you figure you
can use this mechanism to get it to work.
I may be missing something, but I thought the whole point of
interfaces was to get around problems with multiple inheritance (MI),
including the diamond inheritance model.

So while I did indeed come from C++ (didn''t everyone?), I was never
enamored of MI. In fact, I''ve never looked at multiple interfaces as
multiple inheritance.
If you really break down your problem with techniques like CVA, you can
nearly always factor out the multiple inheritance and end up with a better
design. In those rare cases where you cannot... either do the kludge above
or the one you refer to (hard-coding calls for each method).

Think about what you are trying to do and I''m willing to bet that you
probably don''t need the multiple inheritance.




我试图接近初始设计一个抽象的

观点,从用户的角度来看,这是最好看和最简单的
。实现内部可能是另一个

的故事。


所以...关于工厂如何连接接口的任何想法我的

示例上面的Circle / Box代码?看起来我必须首先创建

内部Circle和Box绘图对象,然后在Master中写入与其接口函数匹配的函数

,但调用

内部对象。这是很多丑陋的代码。



I was trying to approach the initial design from an abstract
viewpoint, and thought that this was the best looking and simplest
from the user standpoint. Implementing the internals may be another
story.

So...any ideas on how the factory could wire up the interfaces in my
example Circle/Box code above? It looks like I''d have to create the
internal Circle and Box drawing objects first, then write functions
inside Master that matched their Interface functions, but called into
the internal objects. That''s a lot of ugly code.


这篇关于带接口的优雅设计(C#中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆