Go Back   { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Microsoft > .NET Framework

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 07-22-2008, 03:54 PM
=?Utf-8?B?d2R1ZGVr?=
 
Posts: n/a
Changing an interface

I've seen 2 differnt approaches people take to interfaces and am just curious
on some other opinions. For purposes of this post I am talking about adding a
new method to an existing interface. The first is that an interface can
never change, once it's "published" it is fixed in stone and if a change
needs to be made you should create a new interface that possibly inherits
from the old one. The second is that it is ok as long as the change does not
break the existing contracts, which wouldn't happen if a new method was
added, since they were not using it before they wouldn't need to be aware of
it now.

thoughts?
Reply With Quote
  #2 (permalink)  
Old 07-22-2008, 04:34 PM
Pavel Minaev
 
Posts: n/a
Re: Changing an interface

On Jul 22, 7:54*pm, wdudek <wdu...@newsgroup.nospam> wrote:
> I've seen 2 differnt approaches people take to interfaces and am just curious
> on some other opinions. For purposes of this post I am talking about adding a
> new method to an existing interface. *The first is that an interface can
> never change, once it's "published" it is fixed in stone and if a change
> needs to be made you should create a new interface that possibly inherits
> from the old one. The second is that it is ok as long as the change does not
> break the existing contracts, which wouldn't happen if a new method was
> added, since they were not using it before they wouldn't need to be awareof
> it now.


The second approach is incorrect since the interface can be
implemented as well as used; in fact, it is the whole point of having
an interface! If you change the interface, all existing
implementations would immediately break. Just imagine what would
happen if Microsoft added, say, a new method to IEnumerable tomorrow.

If you do not want to allow users to implement your interfaces, then
interfaces are the wrong tool for the job. Use abstract classes with
internal constructors. Those can only be used but not derived from by
code outside of your assembly (and friend assemblies, as needed), so
there you can safely add new methods. Well, almost - keeping in mind
that adding a new overload can break existing code; if you had a
method Foo(double), and in your new version added an overload
Foo(decimal), any code that called it passing an integer - e.g.
Foo(123) - would now stop compiling because of ambiguity.
Reply With Quote
  #3 (permalink)  
Old 07-22-2008, 04:50 PM
Peter Duniho
 
Posts: n/a
Re: Changing an interface

On Tue, 22 Jul 2008 09:34:45 -0700, Pavel Minaev <int19h@gmail.com> wrote:

> The second approach is incorrect since the interface can be
> implemented as well as used; in fact, it is the whole point of having
> an interface! [...]


While I agree with pretty much everything else you wrote, I'll point out
that allowing the client to implement the interface is not "the WHOLE
point of having an interface".

There are examples of interfaces that are read-only as far as the client
is concerned. In those situations, it shouldn't be a breaking change to
add a member to the interface. For example, using an interface to control
accessibility (C# doesn't provide as fine-grained accessibility control as
some other languages, and so an interface might be used to keep an entire
class private except to some specific other class while allowing _some_ of
the members of the class to be public to the rest of the world).

Which is not the same as saying that doing so should be considered
lightly. Just that there are in fact scenarios in which changing the
interface after the fact wouldn't be disastrous.

Pete
Reply With Quote
  #4 (permalink)  
Old 07-22-2008, 05:43 PM
=?Utf-8?B?d2R1ZGVr?=
 
Posts: n/a
Re: Changing an interface

I understand Pavel's comments about if Microsoft added a method to
IEnumerable, and definately see how that would cause problems. From Peter's
perspective I guess I need to provide more background information on what we
are changing and why. Probably the most important piece to this is that we
are writing this strictly in house, not that this should allow us to bend the
rules and make changes we shouldn't. Secondly what I started off doing that
caused me to post this was add functionality to an existing wcf service. The
service currently has a method that returns a list of products a user can
see. The new method did the same thing but also limited the list by an
application name provided by the calling client. There are numerous
applications using the old code so they need to see the interface with the
current method. Meanwhile new applications need to see both methods. I didn't
want to create a second service because the functionality is very integrated
and people calling this wouldn't expect to look elsewhere for it. After doing
some testing I found that I could add the new method and the existing code
would work fine while the new code would get the additional method. I didn't
seem to have much choice here. My dilema arose when I got to the library the
service calls and how to handle this there. I originally added a new
interface but then decided that since there wasn't a new interface in the wcf
service that this was confusing. This led me to go back and add the method to
the existing interface. I guess the one caveat about this all being in house
code is that I know that the only code implementing the interface that was
added to is the class inside the library containing the interface. All other
references to the interface are to the return valeu of my factory class. Does
this change anyone's opinion?

"Peter Duniho" wrote:

> On Tue, 22 Jul 2008 09:34:45 -0700, Pavel Minaev <int19h@gmail.com> wrote:
>
> > The second approach is incorrect since the interface can be
> > implemented as well as used; in fact, it is the whole point of having
> > an interface! [...]

>
> While I agree with pretty much everything else you wrote, I'll point out
> that allowing the client to implement the interface is not "the WHOLE
> point of having an interface".
>
> There are examples of interfaces that are read-only as far as the client
> is concerned. In those situations, it shouldn't be a breaking change to
> add a member to the interface. For example, using an interface to control
> accessibility (C# doesn't provide as fine-grained accessibility control as
> some other languages, and so an interface might be used to keep an entire
> class private except to some specific other class while allowing _some_ of
> the members of the class to be public to the rest of the world).
>
> Which is not the same as saying that doing so should be considered
> lightly. Just that there are in fact scenarios in which changing the
> interface after the fact wouldn't be disastrous.
>
> Pete
>

Reply With Quote
  #5 (permalink)  
Old 07-22-2008, 06:10 PM
Peter Duniho
 
Posts: n/a
Re: Changing an interface

On Tue, 22 Jul 2008 10:43:02 -0700, wdudek <wdudek@newsgroup.nospam> wrote:

> [...] Does this change anyone's opinion?


Not mine. And I think you could use an occasional paragraph break. :)

Basically, I think that there are times when you can get away with simply
modifying an existing interface. But I agree with Pavel in the sense that
I think one should consider those situations carefully.

The usual way to deal with versioning issues like this is actually to
create a second interface, either as a new version of the old interface
(so includes both methods) or as a whole new interface (including only the
new method). You can use casting or "is" and "as" (in C#) to convert a
reference to the old interface to one of the new interface.

I'm not aware of a better general-purpose versioning mechanism in .NET. I
wish there were one, but I'm not sure what it would look like :). If you
have a really good, compelling reason to avoid using the standard approach
and just modify the existing interface, there are (as I said) situations
in which that could be justified. But otherwise, I think it's better to
stick with the "tried and true", clunky though it might be. :)

Pete
Reply With Quote
  #6 (permalink)  
Old 07-22-2008, 07:15 PM
Pavel Minaev
 
Posts: n/a
Re: Changing an interface

On Jul 22, 8:50*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

> While I agree with pretty much everything else you wrote, I'll point out *
> that allowing the client to implement the interface is not "the WHOLE *
> point of having an interface".


I disagree, but do read on.

> There are examples of interfaces that are read-only as far as the client *
> is concerned. *In those situations, it shouldn't be a breaking change to *
> add a member to the interface. *For example, using an interface to control *
> accessibility (C# doesn't provide as fine-grained accessibility control as *
> some other languages, and so an interface might be used to keep an entire*
> class private except to some specific other class while allowing _some_ of *
> the members of the class to be public to the rest of the world).


That was precisely why I went on to explain how abstract classes can
be used for the same purpose. The reason being, you can't force the
client to avoid implementing an interface and passing it to your
methods which take arguments of corresponding types; and with abstract
classes, you have that option, and for the task you described (hiding
implementation classes, exposing only a limited surface), they work
just as well. Therefore, it would seem that using abstract classes for
that purpose is more appropriate.

Reply With Quote
  #7 (permalink)  
Old 07-22-2008, 08:05 PM
=?Utf-8?B?d2R1ZGVr?=
 
Posts: n/a
Re: Changing an interface

They really need a preview pane in here to prevent those run on paragraphs :)

Thanks though, in this case I did modify the existing interface, because
adding the second did seem a bit clunky to me but your argument for not doing
so does make sense and it's likely to be the direction I take going forward.

Bill

"Peter Duniho" wrote:

> On Tue, 22 Jul 2008 10:43:02 -0700, wdudek <wdudek@newsgroup.nospam> wrote:
>
> > [...] Does this change anyone's opinion?

>
> Not mine. And I think you could use an occasional paragraph break. :)
>
> Basically, I think that there are times when you can get away with simply
> modifying an existing interface. But I agree with Pavel in the sense that
> I think one should consider those situations carefully.
>
> The usual way to deal with versioning issues like this is actually to
> create a second interface, either as a new version of the old interface
> (so includes both methods) or as a whole new interface (including only the
> new method). You can use casting or "is" and "as" (in C#) to convert a
> reference to the old interface to one of the new interface.
>
> I'm not aware of a better general-purpose versioning mechanism in .NET. I
> wish there were one, but I'm not sure what it would look like :). If you
> have a really good, compelling reason to avoid using the standard approach
> and just modify the existing interface, there are (as I said) situations
> in which that could be justified. But otherwise, I think it's better to
> stick with the "tried and true", clunky though it might be. :)
>
> Pete
>

Reply With Quote
  #8 (permalink)  
Old 07-22-2008, 09:04 PM
Peter Duniho
 
Posts: n/a
Re: Changing an interface

On Tue, 22 Jul 2008 12:15:24 -0700, Pavel Minaev <int19h@gmail.com> wrote:

> [...]
> That was precisely why I went on to explain how abstract classes can
> be used for the same purpose.


I don't really understand your comment. You recommended an abstract class
with an internal constructor, but that assumes (to start with) you are
satisfied with "internal" as an appropriate level of accessibility for the
purpose of hiding the members from other classes.

I'm not going to waste a lot of time debating the point though. The fact
is, there are exceptions to the rule "don't modify the interface". You
can disagree if you like, I don't mind.

Pete
Reply With Quote
  #9 (permalink)  
Old 07-22-2008, 09:53 PM
Pavel Minaev
 
Posts: n/a
Re: Changing an interface

On Jul 23, 1:04*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> On Tue, 22 Jul 2008 12:15:24 -0700, Pavel Minaev <int...@gmail.com> wrote:
> I don't really understand your comment. *You recommended an abstract class *
> with an internal constructor, but that assumes (to start with) you are *
> satisfied with "internal" as an appropriate level of accessibility for the *
> purpose of hiding the members from other classes.


Yes. I am treating this from a reusable library design perspective
here. Of course, it would be preferrable to have even more fine-
grained control than just "internal", but we have what we have
with .NET.

When considering interfaces that are only used within an assembly and
not outside it (or within a bunch of coupled assemblies which expose
public members just so that they can interoperate, and not intended to
be called from outside that group), the things are obviously different
- if only because you can immediately fix all the classes broken by a
refactored interface.
Reply With Quote
  #10 (permalink)  
Old 07-22-2008, 09:58 PM
Peter Duniho
 
Posts: n/a
Re: Changing an interface

On Tue, 22 Jul 2008 14:53:23 -0700, Pavel Minaev <int19h@gmail.com> wrote:

> Yes. I am treating this from a reusable library design perspective
> here. Of course, it would be preferrable to have even more fine-
> grained control than just "internal", but we have what we have
> with .NET.


And that's my point. One exception to your statement is the use of
interfaces to get around the lack of fine-grained control of
accessibility. An abstract class does not necessarily address that issue
(it also assumes no need for multiple interface implementations, but I
don't think it's necessary to raise that as an issue to provide a useful
counter-example).

Pete
Reply With Quote
Reply

  { mindfrost82.com } > Gadget Corner > Tech Newsgroups > Microsoft > .NET Framework


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 10:58 AM.


Powered by vBulletin, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.1.0 ©2007, Crawlability, Inc.
© 1999-2008 mindfrost82.com v11.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109