I'm having a bit of a gesign issue(again). Say I have this Buttonpad object:
我有一点gesign问题(再次)。说我有这个Buttonpad对象:
alt text http://img530.imageshack.us/img530/7513/buttonpad.jpg
alt text http://img530.imageshack.us/img530/7513/buttonpad.jpg
now this object is a wrapper object over one in a com object. At the moment it has a method on it called CreateInto(IComObject). Now to make a new button pad in the Com Object.
现在,此对象是com对象中的一个包装器对象。目前它有一个名为CreateInto(IComObject)的方法。现在在Com对象中创建一个新的按钮板。
You do:
ButtonPad pad = new ButtonPad();
pad.Title = "Hello";
// Set some more properties.
pad.CreateInto(Cominstance);
The createinfo method will excute the right commands to buid the button pad in the com object. After it has been created it any calls against it are foward to the underlying object for change so:
createinfo方法将执行正确的命令来buid com对象中的按钮板。在创建之后,对它的任何调用都是对底层对象的改变,所以:
pad.Title = "New title";
will call the com object to set the title and also set the internal title variable.
将调用com对象来设置标题并设置内部标题变量。
Basically any calls before the CreateInfo method only affect the .NET object anything after has the side effect of calling the com object also. I'm not very good at sequence diagrams but here is my attempt to explain whats going on:
基本上,在CreateInfo方法之前的任何调用只会影响.NET对象之后的任何调用com对象的副作用。我不太擅长序列图,但这是我尝试解释最新情况:
alt text http://img196.imageshack.us/img196/5885/seqa.jpg
alt text http://img196.imageshack.us/img196/5885/seqa.jpg
This doesn't feel good to me, it feels like I'm lying to the user about what the button pad does.
这对我来说感觉不太好,感觉我正在向用户说谎按钮垫的功能。
I was going to have a object called WrappedButtonPad, which is returned from CreateInto and the user could make calls against that to make changes to the Com Object, but I feel having two objects that almost do the same thing but only differ by names might be even worse.
我将有一个名为WrappedButtonPad的对象,它从CreateInto返回,用户可以对其进行调用以对Com对象进行更改,但我觉得有两个对象几乎做同样的事情,但只是名称不同可能是更糟。
Are these valid designs, or am I right to be worried?
这些有效的设计,还是我担心的权利?
How else would you handle a object the can create and query a com object?
你怎么处理可以创建和查询com对象的对象?
3 个解决方案
#1
I would allow the ButtonPad to create its own ComInstance. I note in your sequence diagram, that the ButtonPad is the only object that touches the ComInstance. So keep it internal.
我会允许ButtonPad创建自己的ComInstance。我在序列图中注意到,ButtonPad是唯一接触ComInstance的对象。所以保持内部。
#2
I would agree with John's answer.
我同意约翰的回答。
The other alternative would be to replicate the internal state of the ButtonPad to the COM Object when you instantiate it.
另一种方法是在实例化时将ButtonPad的内部状态复制到COM对象。
ie: Option 1 (John's) is to create the COM Object from the ButtonPad constructor.
即:选项1(John's)是从ButtonPad构造函数创建COM对象。
Option 2 is to reflect the state of ButtonPad to the COM Object inside ButtonPad.CreatePad(...). ButtonPad.CreatePad(...) would then call CreateButtonPad on the COM object, and then call SetTitle(), etc. on the COM Object before returning so that ButtonPad ensures that the state of the COM Object is consistent.
选项2是将ButtonPad的状态反映到ButtonPad.CreatePad(...)中的COM对象。然后ButtonPad.CreatePad(...)将在COM对象上调用CreateButtonPad,然后在返回之前调用COM对象上的SetTitle()等,以便ButtonPad确保COM对象的状态是一致的。
I would prefer option 2 if it makes sense for the ButtonPad to exist without the COM Object, or possibly if you didn't have access to the IComObject required to instantiate the COM Object at the time the ButtonPad is instantiated. Otherwise I'd go with option 1.
如果ButtonPad在没有COM对象的情况下存在是有意义的,或者如果你无法访问实例化ButtonPad时实例化COM对象所需的IComObject,我更喜欢选项2。否则我会选择选项1。
#3
I'd first ask: what's the use case for manipulating ButtonPad
properties independently of the underlying properties that they're hiding? There are most likely two answers for that: 1) there isn't one, 2) it's critically important that we be able to do that.
我首先要问:操作ButtonPad属性的用例是什么,而与它们隐藏的底层属性无关?最有可能有两个答案:1)没有一个,2)我们能够做到这一点至关重要。
The answer in the first case is pretty straightforward: create the underlying COM object in your class's constructor, map your properties onto its properties, and call it a day.
第一种情况的答案非常简单:在类的构造函数中创建底层COM对象,将属性映射到其属性,并在一天内调用它。
In the second case, though, you're getting into territory that smells a lot like data binding. You have a data source (your object), the thing it's bound to (the COM object), the need to convert property values between the two things (i.e. parsing and formatting, if the communication is two-way), and possibly even a need for mapping property changes through event notifications. (Like, if something else manipulates a property of the COM object, does your .NET object need to be notified?)
然而,在第二种情况下,你进入的领域有点像数据绑定。你有一个数据源(你的对象),它绑定的东西(COM对象),需要在两件事之间转换属性值(即解析和格式化,如果通信是双向的),甚至可能是需要通过事件通知映射属性更改。 (比如,如果其他东西操纵COM对象的属性,是否需要通知您的.NET对象?)
I'm not saying that you'd actually want to use binding to do this, but I'd certainly look at the way .NET data binding is designed and see how many pieces of that design you actually are going to need.
我并不是说你真的想用绑定来做这件事,但我当然会看看.NET数据绑定的设计方式,看看你实际需要多少件设计。
In all likelihood, you'll look at it and say "Wow, that's really complicated." That's because what you're trying to do is fundamentally really complicated. It's a lot more complicated if your design doesn't implement separation of concerns.
很有可能,你会看到它并说“哇,这真的很复杂。”那是因为你想要做的事情从根本上说是非常复杂的。如果您的设计没有实现关注点的分离,那就复杂得多。
#1
I would allow the ButtonPad to create its own ComInstance. I note in your sequence diagram, that the ButtonPad is the only object that touches the ComInstance. So keep it internal.
我会允许ButtonPad创建自己的ComInstance。我在序列图中注意到,ButtonPad是唯一接触ComInstance的对象。所以保持内部。
#2
I would agree with John's answer.
我同意约翰的回答。
The other alternative would be to replicate the internal state of the ButtonPad to the COM Object when you instantiate it.
另一种方法是在实例化时将ButtonPad的内部状态复制到COM对象。
ie: Option 1 (John's) is to create the COM Object from the ButtonPad constructor.
即:选项1(John's)是从ButtonPad构造函数创建COM对象。
Option 2 is to reflect the state of ButtonPad to the COM Object inside ButtonPad.CreatePad(...). ButtonPad.CreatePad(...) would then call CreateButtonPad on the COM object, and then call SetTitle(), etc. on the COM Object before returning so that ButtonPad ensures that the state of the COM Object is consistent.
选项2是将ButtonPad的状态反映到ButtonPad.CreatePad(...)中的COM对象。然后ButtonPad.CreatePad(...)将在COM对象上调用CreateButtonPad,然后在返回之前调用COM对象上的SetTitle()等,以便ButtonPad确保COM对象的状态是一致的。
I would prefer option 2 if it makes sense for the ButtonPad to exist without the COM Object, or possibly if you didn't have access to the IComObject required to instantiate the COM Object at the time the ButtonPad is instantiated. Otherwise I'd go with option 1.
如果ButtonPad在没有COM对象的情况下存在是有意义的,或者如果你无法访问实例化ButtonPad时实例化COM对象所需的IComObject,我更喜欢选项2。否则我会选择选项1。
#3
I'd first ask: what's the use case for manipulating ButtonPad
properties independently of the underlying properties that they're hiding? There are most likely two answers for that: 1) there isn't one, 2) it's critically important that we be able to do that.
我首先要问:操作ButtonPad属性的用例是什么,而与它们隐藏的底层属性无关?最有可能有两个答案:1)没有一个,2)我们能够做到这一点至关重要。
The answer in the first case is pretty straightforward: create the underlying COM object in your class's constructor, map your properties onto its properties, and call it a day.
第一种情况的答案非常简单:在类的构造函数中创建底层COM对象,将属性映射到其属性,并在一天内调用它。
In the second case, though, you're getting into territory that smells a lot like data binding. You have a data source (your object), the thing it's bound to (the COM object), the need to convert property values between the two things (i.e. parsing and formatting, if the communication is two-way), and possibly even a need for mapping property changes through event notifications. (Like, if something else manipulates a property of the COM object, does your .NET object need to be notified?)
然而,在第二种情况下,你进入的领域有点像数据绑定。你有一个数据源(你的对象),它绑定的东西(COM对象),需要在两件事之间转换属性值(即解析和格式化,如果通信是双向的),甚至可能是需要通过事件通知映射属性更改。 (比如,如果其他东西操纵COM对象的属性,是否需要通知您的.NET对象?)
I'm not saying that you'd actually want to use binding to do this, but I'd certainly look at the way .NET data binding is designed and see how many pieces of that design you actually are going to need.
我并不是说你真的想用绑定来做这件事,但我当然会看看.NET数据绑定的设计方式,看看你实际需要多少件设计。
In all likelihood, you'll look at it and say "Wow, that's really complicated." That's because what you're trying to do is fundamentally really complicated. It's a lot more complicated if your design doesn't implement separation of concerns.
很有可能,你会看到它并说“哇,这真的很复杂。”那是因为你想要做的事情从根本上说是非常复杂的。如果您的设计没有实现关注点的分离,那就复杂得多。