Why use Interfaces?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • dj

    #1

    Why use Interfaces?

    I know seasoned OOP-savvy developers will roll their eyes at this one, but
    can anyone provide a clear explanation as to *why* one would need to use an
    Interface in a VB.NET application?

    Every book and article I seem to run across jumps right into "and here's how
    Interfaces are implemented..." followed by a block of meaningless (to me)
    code without explaining why this is being used in the first place. e.g. Why
    not use a Class object?

    TIA,
    dj
  • _AnonCoward

    #2
    Re: Why use Interfaces?


    "dj" <dj@discussions .microsoft.com> wrote in message
    news:31A406FA-C220-4686-B5E8-83FC05A880B4@mi crosoft.com...
    :
    : I know seasoned OOP-savvy developers will roll their eyes at this one,
    : but can anyone provide a clear explanation as to *why* one would need
    : to use an Interface in a VB.NET application?
    :
    : Every book and article I seem to run across jumps right into "and
    : here's how Interfaces are implemented..." followed by a block of
    : meaningless (to me) code without explaining why this is being used
    : in the first place. e.g. Why not use a Class object?
    :
    : TIA,
    : dj


    Interfaces are not intended to be used directly - rather, they describe
    the behavior and traits a class implementing the interface can be
    expected to exhibit. They do not provide their own implemention details
    however, which is what differentiates them from classes or structures.
    According to the documentation:


    "Interfaces are reference types that other types implement
    to guarantee that they support certain operations. An interface
    is never directly created and has no actual representation - other
    types must be converted to an interface type.


    "An interface defines a contract. A class or structure that
    implements an interface must adhere to its contract."


    If a class implements a given interface, it can be treated as an
    instance of that interface by anything that needs to use it. The example
    that follows is a little contrived, but it is loosely based on an actual
    situation I had to deal with once.


    In this case, I want a component that can process different types of
    payments. To do this, I've defined a generic payment handler interface
    that defined a single method: process payment. Three separate classes
    implement this interface: a credit card payment handler, a check payment
    handler and a cash payment handler. These classes handle the actual
    details for processing the different payment types.


    When a payment is submitted, a single class is available that handles
    all payments regardless of type. Consumers of the class don't need to
    worry about having to call one class for credit card payments, another
    for checks and a third for cash. They simply call a single class that
    handles all of the details. If I decide to add another type of payment
    in the future (e.g.: money orders), existing consumers of the class
    won't be impacted.


    This exposed class in turn checks the payment type and calls the
    appropriate child class. Since each of the child classes implement the
    payment handler interface, I can use a single type that calls the
    process payment function of the appropriate payment handler.


    Hopefully the code example below will clear this up a bit (please
    forgive the use of line continuation characters - they are there get the
    code to display correctly in this format):


    '-----------------------------------------------
    Option Strict

    Imports Microsoft.Visua lBasic
    Imports System
    Imports System.XML

    Public Module [module]
    Public Sub Main
    Dim Details As String
    Dim PH As New PaymentHandler

    Details = "<Request>" _
    & "<Payment Type='CreditCar d'/>" _
    & "<CCDetails />" _
    & "</Request>"

    PH.ProcessPayme nt(details)

    Details = "<Request>" _
    & "<Payment Type='Check'/>" _
    & "<CheckDeta ils />" _
    & "</Request>"

    PH.ProcessPayme nt(details)

    Details = "<Request>" _
    & "<Payment Type='Cash'/>" _
    & "<CashDetai ls />" _
    & "</Request>"

    PH.ProcessPayme nt(details)
    End SUb
    End Module

    Public Class PaymentHandler


    'XML String with payment details
    'Available Types = "CreditCard ", "Check", "Cash"
    '
    '<Request>
    ' <Payment Type="" Date="" Amount=""/>
    '
    ' <!-- As appropriate below -->
    ' <CCDetails Name="" Type="" Number="" Expires="" Date="" Amount=""/>
    ' <CheckDetails Routing="" Account="" Number="" Date="" Amount=""/>
    ' <CashDetails Date="" Amount=""/>
    '
    '</Request>
    '
    Public Sub ProcessPayment( Details As String)

    Dim PaymentType As String
    Dim PmtHandler As IPaymentHandler

    With New XMLDocument
    .LoadXML(Detail s)
    PaymentType = _
    .SelectSingleNo de( _
    "/Request/Payment/@Type").InnerTe xt

    '************** *************** *************** *****
    Select Case PaymentType
    Case "CreditCard "
    PmtHandler = New CCPaymentHandle r
    Case "Check"
    PmtHandler = New CheckPaymentHan dler
    Case "Cash"
    PmtHandler = New CashPaymentHand ler
    End Select

    '************** *************** *************** *****

    End With

    PmtHandler.Proc essPayment(Deta ils)

    End Sub

    Private Class CCPaymentHandle r
    Implements IPaymentHandler

    Private Sub ProcessPayment( _
    Details As String) _
    Implements IPaymentHandler .ProcessPayment

    Console.WriteLi ne("Process CreditCard")
    End Sub
    End Class

    Private Class CheckPaymentHan dler
    Implements IPaymentHandler

    Private Sub ProcessPayment( _
    Details As String) _
    Implements IPaymentHandler .ProcessPayment

    Console.WriteLi ne("Process Check")
    End Sub
    End Class

    Private Class CashPaymentHand ler
    Implements IPaymentHandler

    Private Sub ProcessPayment( _
    Details As String) _
    Implements IPaymentHandler .ProcessPayment

    Console.WriteLi ne("Process Cash")
    End Sub
    End Class

    Private Interface IPaymentHandler
    Sub ProcessPayment( Details As String)
    End Interface

    End Class
    '-----------------------------------------------


    Ralf
    --
    ----------------------------------------------------------
    * ^~^ ^~^ *
    * _ {~ ~} {~ ~} _ *
    * /_``>*< >*<''_\ *
    * (\--_)++) (++(_--/) *
    ----------------------------------------------------------
    There are no advanced students in Aikido - there are only
    competent beginners. There are no advanced techniques -
    only the correct application of basic principles.


    Comment

    • Bob Powell [MVP]

      #3
      Re: Why use Interfaces?

      A class has a unique fingerprint which is defined by it's namespace, name,
      method and property signatures. This signature makes the class
      distinguishable from all other classes.

      This can be an advantage or a disadvantage. For example, if you want to
      create an object that knows how to draw itself you might do so by creating a
      base-class with a DrawMe method. Now, all classes derived from this base
      will have a DrawMe method and can override that somehow to draw their
      different appearences. The disadvantage to this is that the base class with
      the DrawMe method must be in the inheritance chain in order for the system
      to work. You could not create some other arbitrary class with a method
      called DrawMe and use it in your toolbox of objects because it wouldn't be
      derived from the expected base class.

      Using an interface however, you can create a system that will "morph" the
      signature of any class so that you can add a specific method or property to
      it and not have to be concerned about it's derivation. The interface
      provides this "contract" which simply says that the class which implements
      the interface agrees to behave in a certain manner regardless of it's true
      class or method signatures. Effectively, the interface can be thought of as
      the duplicate key that can be passed around so that anyone can use a
      particular car. Anyone with the key can drive the car, anyone with the
      interface can operate the functionality provided in the interface contract.

      In this example, an interface called IDrawable might have just a single
      method called DrawMe. This can be implemented by any class but whoever gets
      hold of hose classes will know that the thing draws itself by the fact that
      it implements IDrawable. If you can cast an object to IDrawable, it will
      obey the rules of the contract.

      Hope this helps.

      --
      Bob Powell [MVP]
      Visual C#, System.Drawing

      Ramuseco Limited .NET consulting


      Find great Windows Forms articles in Windows Forms Tips and Tricks


      Answer those GDI+ questions with the GDI+ FAQ


      All new articles provide code in C# and VB.NET.
      Subscribe to the RSS feeds provided and never miss a new article.





      "dj" <dj@discussions .microsoft.com> wrote in message
      news:31A406FA-C220-4686-B5E8-83FC05A880B4@mi crosoft.com...[color=blue]
      >I know seasoned OOP-savvy developers will roll their eyes at this one, but
      > can anyone provide a clear explanation as to *why* one would need to use
      > an
      > Interface in a VB.NET application?
      >
      > Every book and article I seem to run across jumps right into "and here's
      > how
      > Interfaces are implemented..." followed by a block of meaningless (to me)
      > code without explaining why this is being used in the first place. e.g.
      > Why
      > not use a Class object?
      >
      > TIA,
      > dj[/color]


      Comment

      • Bob Powell [MVP]

        #4
        Re: Why use Interfaces?

        A class has a unique fingerprint which is defined by it's namespace, name,
        method and property signatures. This signature makes the class
        distinguishable from all other classes.

        This can be an advantage or a disadvantage. For example, if you want to
        create an object that knows how to draw itself you might do so by creating a
        base-class with a DrawMe method. Now, all classes derived from this base
        will have a DrawMe method and can override that somehow to draw their
        different appearences. The disadvantage to this is that the base class with
        the DrawMe method must be in the inheritance chain in order for the system
        to work. You could not create some other arbitrary class with a method
        called DrawMe and use it in your toolbox of objects because it wouldn't be
        derived from the expected base class.

        Using an interface however, you can create a system that will "morph" the
        signature of any class so that you can add a specific method or property to
        it and not have to be concerned about it's derivation. The interface
        provides this "contract" which simply says that the class which implements
        the interface agrees to behave in a certain manner regardless of it's true
        class or method signatures. Effectively, the interface can be thought of as
        the duplicate key that can be passed around so that anyone can use a
        particular car. Anyone with the key can drive the car, anyone with the
        interface can operate the functionality provided in the interface contract.

        In this example, an interface called IDrawable might have just a single
        method called DrawMe. This can be implemented by any class but whoever gets
        hold of hose classes will know that the thing draws itself by the fact that
        it implements IDrawable. If you can cast an object to IDrawable, it will
        obey the rules of the contract.

        Hope this helps.

        --
        Bob Powell [MVP]
        Visual C#, System.Drawing

        Ramuseco Limited .NET consulting


        Find great Windows Forms articles in Windows Forms Tips and Tricks


        Answer those GDI+ questions with the GDI+ FAQ


        All new articles provide code in C# and VB.NET.
        Subscribe to the RSS feeds provided and never miss a new article.





        "dj" <dj@discussions .microsoft.com> wrote in message
        news:31A406FA-C220-4686-B5E8-83FC05A880B4@mi crosoft.com...[color=blue]
        >I know seasoned OOP-savvy developers will roll their eyes at this one, but
        > can anyone provide a clear explanation as to *why* one would need to use
        > an
        > Interface in a VB.NET application?
        >
        > Every book and article I seem to run across jumps right into "and here's
        > how
        > Interfaces are implemented..." followed by a block of meaningless (to me)
        > code without explaining why this is being used in the first place. e.g.
        > Why
        > not use a Class object?
        >
        > TIA,
        > dj[/color]



        Comment

        • dj

          #5
          Re: Why use Interfaces?

          Thank you both for your insightful explanations; it is becoming a little
          clearer now.
          Ralf- In your (very nice) example, after reading your description of what
          you were implementing, my initial thought was that you could overload a
          'ProcessPayment ' method in a class. As I thought and read further, it
          becomes clear this approach is not ideal after all.

          It strikes me that using an Interface, at least in the manner you illustrate
          here, could be described as another way of overloading a method, but in
          remote fashion.
          (I am attempting to describe what I don't quite understand with something I
          believe I understand here.)

          The Interface provides a means to implement different (or the same)
          functionality and expose it to any class object(s) that might require that
          functionality.

          One last point: the examples in the books I'm reading declare the Interface
          (IPaymentHandle r in this example) as Public, yet I see you have declared it
          as Private. Could you elaborate on why you chose this?

          Thank you very much!
          dj

          "_AnonCowar d" wrote:
          [color=blue]
          >
          > "dj" <dj@discussions .microsoft.com> wrote in message
          > news:31A406FA-C220-4686-B5E8-83FC05A880B4@mi crosoft.com...
          > :
          > : I know seasoned OOP-savvy developers will roll their eyes at this one,
          > : but can anyone provide a clear explanation as to *why* one would need
          > : to use an Interface in a VB.NET application?
          > :
          > : Every book and article I seem to run across jumps right into "and
          > : here's how Interfaces are implemented..." followed by a block of
          > : meaningless (to me) code without explaining why this is being used
          > : in the first place. e.g. Why not use a Class object?
          > :
          > : TIA,
          > : dj
          >
          >
          > Interfaces are not intended to be used directly - rather, they describe
          > the behavior and traits a class implementing the interface can be
          > expected to exhibit. They do not provide their own implemention details
          > however, which is what differentiates them from classes or structures.
          > According to the documentation:
          >
          >
          > "Interfaces are reference types that other types implement
          > to guarantee that they support certain operations. An interface
          > is never directly created and has no actual representation - other
          > types must be converted to an interface type.
          >
          >
          > "An interface defines a contract. A class or structure that
          > implements an interface must adhere to its contract."
          >
          >
          > If a class implements a given interface, it can be treated as an
          > instance of that interface by anything that needs to use it. The example
          > that follows is a little contrived, but it is loosely based on an actual
          > situation I had to deal with once.
          >
          >
          > In this case, I want a component that can process different types of
          > payments. To do this, I've defined a generic payment handler interface
          > that defined a single method: process payment. Three separate classes
          > implement this interface: a credit card payment handler, a check payment
          > handler and a cash payment handler. These classes handle the actual
          > details for processing the different payment types.
          >
          >
          > When a payment is submitted, a single class is available that handles
          > all payments regardless of type. Consumers of the class don't need to
          > worry about having to call one class for credit card payments, another
          > for checks and a third for cash. They simply call a single class that
          > handles all of the details. If I decide to add another type of payment
          > in the future (e.g.: money orders), existing consumers of the class
          > won't be impacted.
          >
          >
          > This exposed class in turn checks the payment type and calls the
          > appropriate child class. Since each of the child classes implement the
          > payment handler interface, I can use a single type that calls the
          > process payment function of the appropriate payment handler.
          >
          >
          > Hopefully the code example below will clear this up a bit (please
          > forgive the use of line continuation characters - they are there get the
          > code to display correctly in this format):
          >
          >
          > '-----------------------------------------------
          > Option Strict
          >
          > Imports Microsoft.Visua lBasic
          > Imports System
          > Imports System.XML
          >
          > Public Module [module]
          > Public Sub Main
          > Dim Details As String
          > Dim PH As New PaymentHandler
          >
          > Details = "<Request>" _
          > & "<Payment Type='CreditCar d'/>" _
          > & "<CCDetails />" _
          > & "</Request>"
          >
          > PH.ProcessPayme nt(details)
          >
          > Details = "<Request>" _
          > & "<Payment Type='Check'/>" _
          > & "<CheckDeta ils />" _
          > & "</Request>"
          >
          > PH.ProcessPayme nt(details)
          >
          > Details = "<Request>" _
          > & "<Payment Type='Cash'/>" _
          > & "<CashDetai ls />" _
          > & "</Request>"
          >
          > PH.ProcessPayme nt(details)
          > End SUb
          > End Module
          >
          > Public Class PaymentHandler
          >
          >
          > 'XML String with payment details
          > 'Available Types = "CreditCard ", "Check", "Cash"
          > '
          > '<Request>
          > ' <Payment Type="" Date="" Amount=""/>
          > '
          > ' <!-- As appropriate below -->
          > ' <CCDetails Name="" Type="" Number="" Expires="" Date="" Amount=""/>
          > ' <CheckDetails Routing="" Account="" Number="" Date="" Amount=""/>
          > ' <CashDetails Date="" Amount=""/>
          > '
          > '</Request>
          > '
          > Public Sub ProcessPayment( Details As String)
          >
          > Dim PaymentType As String
          > Dim PmtHandler As IPaymentHandler
          >
          > With New XMLDocument
          > .LoadXML(Detail s)
          > PaymentType = _
          > .SelectSingleNo de( _
          > "/Request/Payment/@Type").InnerTe xt
          >
          > '************** *************** *************** *****
          > Select Case PaymentType
          > Case "CreditCard "
          > PmtHandler = New CCPaymentHandle r
          > Case "Check"
          > PmtHandler = New CheckPaymentHan dler
          > Case "Cash"
          > PmtHandler = New CashPaymentHand ler
          > End Select
          >
          > '************** *************** *************** *****
          >
          > End With
          >
          > PmtHandler.Proc essPayment(Deta ils)
          >
          > End Sub
          >
          > Private Class CCPaymentHandle r
          > Implements IPaymentHandler
          >
          > Private Sub ProcessPayment( _
          > Details As String) _
          > Implements IPaymentHandler .ProcessPayment
          >
          > Console.WriteLi ne("Process CreditCard")
          > End Sub
          > End Class
          >
          > Private Class CheckPaymentHan dler
          > Implements IPaymentHandler
          >
          > Private Sub ProcessPayment( _
          > Details As String) _
          > Implements IPaymentHandler .ProcessPayment
          >
          > Console.WriteLi ne("Process Check")
          > End Sub
          > End Class
          >
          > Private Class CashPaymentHand ler
          > Implements IPaymentHandler
          >
          > Private Sub ProcessPayment( _
          > Details As String) _
          > Implements IPaymentHandler .ProcessPayment
          >
          > Console.WriteLi ne("Process Cash")
          > End Sub
          > End Class
          >
          > Private Interface IPaymentHandler
          > Sub ProcessPayment( Details As String)
          > End Interface
          >
          > End Class
          > '-----------------------------------------------
          >
          >
          > Ralf
          > --
          > ----------------------------------------------------------
          > * ^~^ ^~^ *
          > * _ {~ ~} {~ ~} _ *
          > * /_``>*< >*<''_\ *
          > * (\--_)++) (++(_--/) *
          > ----------------------------------------------------------
          > There are no advanced students in Aikido - there are only
          > competent beginners. There are no advanced techniques -
          > only the correct application of basic principles.
          >
          >
          >[/color]

          Comment

          • _AnonCoward

            #6
            Re: Why use Interfaces?


            "dj" <dj@discussions .microsoft.com> wrote in message
            news:EA278E27-79FB-4816-BABC-9F4D0B06B181@mi crosoft.com...
            :
            : Thank you both for your insightful explanations; it is becoming a
            : little clearer now.
            : Ralf- In your (very nice) example, after reading your description of
            : what you were implementing, my initial thought was that you could
            : overload a 'ProcessPayment ' method in a class. As I thought and
            : read further, it becomes clear this approach is not ideal after all.


            Indeed - there are any number of approaches you could take in this type
            of scenario. The use of an interface here was driven by several design
            constraints, not all of which were under my control. Also, I
            deliberately crafted this example in order to illustrate one way in
            which an interface could be used.


            : It strikes me that using an Interface, at least in the manner you
            : illustrate here, could be described as another way of overloading a
            : method, but in remote fashion.
            : (I am attempting to describe what I don't quite understand with
            : something I believe I understand here.)


            Perhaps, in a round about way. Method overloading allows for a type of
            polymorphism in that a single method call can be used to handle
            different input parameter types (e.g.: the way the String object's
            "IndexOf" method allows for more than one way to invoke the
            functionality).


            Interfaces also allow for polymorphic behavior, but in a different form.
            In this case, classes can expose the same functionality but with
            totally different implementations of that functionality. Two classes can
            be considered the same 'Type' (i.e., are a TypeOf) as long as they
            implement the same interface. Unlike inheriting from a class however,
            they do not share the same default behavior.


            : The Interface provides a means to implement different (or the same)
            : functionality and expose it to any class object(s) that might require
            : that functionality.


            The interface defines the 'contract' that any class implementing it must
            adhere to. Apart from that, the interface has no say at all as to how
            the functionality will be implemented. Any object that implements the
            functionality can be treated as an instance of that interface.


            Consider the following trivial example:


            ------------------------------------------------------
            Option Strict

            Imports Microsoft.Visua lBasic
            Imports System
            Imports System.Collecti ons

            Public Module [module]
            Public Sub Main
            Dim A As New MyArrayList
            Console.WriteLi ne(TypeOf A Is CollectionBase)
            Console.WriteLi ne(TypeOf A Is IList)
            Console.WriteLi ne(TypeOf A Is ICollection)
            Console.WriteLi ne(TypeOf A Is IEnumerable)
            Console.WriteLi ne(TypeOf A Is IDictionary)
            End SUb
            End Module

            Public Class MyArrayList : Inherits CollectionBase
            End Class
            ------------------------------------------------------


            If you run it, you'll see the following displayed on the console:


            True
            True
            True
            True
            False


            Only the last TypeOf expression (IDictionary) returned False because the
            CollectionBase class does not implement that interface and neither does
            the derived class.


            The point of this is to show how using interfaces allows the class
            MyArrayList to stand in for any of the different types - both the base
            classes (Object and CollectionBase) and the interfaces. This allows for
            the following modification to the example above:


            ------------------------------------------------------
            Option Strict

            Imports Microsoft.Visua lBasic
            Imports System
            Imports System.Collecti ons

            Public Module [module]
            Public Sub Main
            Dim A As New MyArrayList
            MySub1(A)
            MySub2(A)
            MySub3(A)
            MySub4(A)
            MySub5(A)
            MySub6(A)
            End SUb

            Public Sub MySub1(Item As Object)
            Console.WriteLi ne("Object")
            End Sub

            Public Sub MySub2(Item As CollectionBase)
            Console.WriteLi ne("CollectionB ase")
            End Sub

            Public Sub MySub3(Item As MyArrayList)
            Console.WriteLi ne("MyArrayList ")
            End Sub

            Public Sub MySub4(Item As IList)
            Console.WriteLi ne("IList")
            End Sub

            Public Sub MySub5(Item As ICollection)
            Console.WriteLi ne("ICollection ")
            End Sub

            Public Sub MySub6(Item As IEnumerable)
            Console.WriteLi ne("IEnumerable ")
            End Sub
            End Module

            Public Class MyArrayList : Inherits CollectionBase
            End Class
            ------------------------------------------------------


            In this case, the output is:


            Object
            CollectionBase
            MyArrayList
            IList
            ICollection
            IEnumerable


            While each of the Sub's accepted a different type, I was able to pass in
            the same object to each of them and none of them were the wiser for it.


            : One last point: the examples in the books I'm reading declare the
            : Interface (IPaymentHandle r in this example) as Public, yet I see
            : you have declared it as Private. Could you elaborate on why you
            : chose this?


            In the example I was using, I consciously chose not to expose the
            different payment classes to the consumer. My objective was to allow the
            consumer to only need to know about the single Public class exposed. The
            idea was the consumer would package the payment information and submit
            it to the same object in all cases.


            If I were to implement a new payment method in the future (e.g.: money
            orders), consumers would only need to be concerned with how to format
            the XML input string (possibly using an XSL style sheet or other
            mechanism). Apart from that, they would not be obligated to recompile
            their class in order to take advantage of the new payment type being
            supported.


            The internal classes were just that - internal. They were not exposed to
            the consumer and were not intended for direct consumption. Therefore I
            declared them as Private. Since the interface did not serve a purpose
            outside that context, I saw no reason to declare it Public.


            : Thank you very much!
            : dj


            You're welcome.


            <snip>


            Ralf
            --
            ----------------------------------------------------------
            * ^~^ ^~^ *
            * _ {~ ~} {~ ~} _ *
            * /_``>*< >*<''_\ *
            * (\--_)++) (++(_--/) *
            ----------------------------------------------------------
            There are no advanced students in Aikido - there are only
            competent beginners. There are no advanced techniques -
            only the correct application of basic principles.



            Comment

            Working...