Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. Designing to interfaces?

Designing to interfaces?

Scheduled Pinned Locked Moved Java
designtestingbeta-testingoophelp
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Neo10101
    wrote on last edited by
    #1

    I have just heard about the 'Designing to Interfaces' concept. I am required to implement this design methodology very soon, but I am not fully sure how it works. What I learned so far is this: Example A ------------- Here, using a ShapeInterface decouples this Main app from any subshape object (Rectangle, Triangle, etc.). So if I need to add a Shape type object in the future, I don't have to modify the client code because it's been 'coded to the interface'. I only have to change the actual implementation in the concrete class itself.

    ShapeInterface shape = ShapeFactory.getNewInstance("triangle");
    shape.draw();

    Example B ------------- This code is easy to break because this Main app will be tightly coupled to every future shape object I need (if there comes a Rectangle, I will need to change the code to instantiate a Rectangle etc.). Also, the implementations are different and so I have to apply the appropriate implementation (Rectangle.draw(), Triangle.draw(), etc.)

    Triangle triangle = ShapeFactory.getNewInstance("triangle");
    triangle.draw();

    I understood this concept. Using an interface so that you won't have the change the code that uses the underlying concrete classes. Ok, understandable. I see the advantage. Here's the concept that [b]I don't understand[/b]: Example C ------------- This example illustrates composition instead of inheritance (Object A has an Object B rather than IS-A B). A can't print directly, it has to delegate to B. Fine, I understand that. What I don't understand is the advantage of this. Couple of questions: 1) How was it decoupled? 2) Will putting the interface in between A and B decouple their relationship? 3) What if there was no interface between them? Then A would be tightly coupled to B? 4) If B disappears, can I simply replace it with a C class thanks to the interface? If I don't understand these concepts then I can't move on in my design.

    public interface ABInterface {
    public void print();
    }

    public class A implements ABInterface {
    private B b;

    public A() {
        b = new B();
    }
    
    public void print() {
        b.print();
    }
    

    }

    public class B implements ABInterface {
    public void print(){
    System.out.println("Testing B");
    }
    }

    Ok, so that's that. However, I have another big problem: Say I have a couple of classes that implement a particular interface. Now say that later, there is one method

    B J 2 Replies Last reply
    0
    • N Neo10101

      I have just heard about the 'Designing to Interfaces' concept. I am required to implement this design methodology very soon, but I am not fully sure how it works. What I learned so far is this: Example A ------------- Here, using a ShapeInterface decouples this Main app from any subshape object (Rectangle, Triangle, etc.). So if I need to add a Shape type object in the future, I don't have to modify the client code because it's been 'coded to the interface'. I only have to change the actual implementation in the concrete class itself.

      ShapeInterface shape = ShapeFactory.getNewInstance("triangle");
      shape.draw();

      Example B ------------- This code is easy to break because this Main app will be tightly coupled to every future shape object I need (if there comes a Rectangle, I will need to change the code to instantiate a Rectangle etc.). Also, the implementations are different and so I have to apply the appropriate implementation (Rectangle.draw(), Triangle.draw(), etc.)

      Triangle triangle = ShapeFactory.getNewInstance("triangle");
      triangle.draw();

      I understood this concept. Using an interface so that you won't have the change the code that uses the underlying concrete classes. Ok, understandable. I see the advantage. Here's the concept that [b]I don't understand[/b]: Example C ------------- This example illustrates composition instead of inheritance (Object A has an Object B rather than IS-A B). A can't print directly, it has to delegate to B. Fine, I understand that. What I don't understand is the advantage of this. Couple of questions: 1) How was it decoupled? 2) Will putting the interface in between A and B decouple their relationship? 3) What if there was no interface between them? Then A would be tightly coupled to B? 4) If B disappears, can I simply replace it with a C class thanks to the interface? If I don't understand these concepts then I can't move on in my design.

      public interface ABInterface {
      public void print();
      }

      public class A implements ABInterface {
      private B b;

      public A() {
          b = new B();
      }
      
      public void print() {
          b.print();
      }
      

      }

      public class B implements ABInterface {
      public void print(){
      System.out.println("Testing B");
      }
      }

      Ok, so that's that. However, I have another big problem: Say I have a couple of classes that implement a particular interface. Now say that later, there is one method

      B Offline
      B Offline
      BobJanova
      wrote on last edited by
      #2

      Composition allows you to switch the internal implementation of an interface easily. In your example you can easily change A so that it delegates to a new class X instead of B, and the client code won't notice (not even to change a new A() to new X(), or a DI container registration, as with inheritance). You can even write A so that it chooses a different internal implementation class at runtime (for example a file access wrapper which uses a local disk mapper, a memory mapper or a network resource mapper depending on what is passed to a constructor). Unlike an inherited solution, the class B is totally decoupled from the class which uses A. B can be package-visible, if it's in the same package as A (in .Net it can and probably should be internal). B won't be decoupled from A as long as A contains a 'new B()' type statement. You can, of course, use the normal interface and DI or factory mechanisms to decouple them, but you have to ask yourself what the purpose of that is, considering that A itself is already little more than a decoupling wrapper class (decoupling B from the outside world). If you find that a method on an interface isn't used any more, if you're using a decent IDE you can chase down all the implementations in subclasses and remove them as well. Alternatively, if you use @Override annotations, when you remove the interface method, the implementers' methods with @Override will cause a compilation failure (because they're now not overriding anything) and you can go and delete them.

      N 1 Reply Last reply
      0
      • B BobJanova

        Composition allows you to switch the internal implementation of an interface easily. In your example you can easily change A so that it delegates to a new class X instead of B, and the client code won't notice (not even to change a new A() to new X(), or a DI container registration, as with inheritance). You can even write A so that it chooses a different internal implementation class at runtime (for example a file access wrapper which uses a local disk mapper, a memory mapper or a network resource mapper depending on what is passed to a constructor). Unlike an inherited solution, the class B is totally decoupled from the class which uses A. B can be package-visible, if it's in the same package as A (in .Net it can and probably should be internal). B won't be decoupled from A as long as A contains a 'new B()' type statement. You can, of course, use the normal interface and DI or factory mechanisms to decouple them, but you have to ask yourself what the purpose of that is, considering that A itself is already little more than a decoupling wrapper class (decoupling B from the outside world). If you find that a method on an interface isn't used any more, if you're using a decent IDE you can chase down all the implementations in subclasses and remove them as well. Alternatively, if you use @Override annotations, when you remove the interface method, the implementers' methods with @Override will cause a compilation failure (because they're now not overriding anything) and you can go and delete them.

        N Offline
        N Offline
        Neo10101
        wrote on last edited by
        #3

        Well, an IDE shouldn't make up for my design mistakes. I do use @Override annotations (Ant). Going on and deleting each single implementation is not the right way to work. I suppose that if a change in my code (removing a method) causes a waterfall effect (change implementation everywhere) then my code is badly written.

        B 1 Reply Last reply
        0
        • N Neo10101

          Well, an IDE shouldn't make up for my design mistakes. I do use @Override annotations (Ant). Going on and deleting each single implementation is not the right way to work. I suppose that if a change in my code (removing a method) causes a waterfall effect (change implementation everywhere) then my code is badly written.

          B Offline
          B Offline
          BobJanova
          wrote on last edited by
          #4

          Discovering that you don't actually need something you thought you did can be a sign of over-design. But we all have to rework and modify our designs as we code – that's fine and a natural part of software development.

          1 Reply Last reply
          0
          • N Neo10101

            I have just heard about the 'Designing to Interfaces' concept. I am required to implement this design methodology very soon, but I am not fully sure how it works. What I learned so far is this: Example A ------------- Here, using a ShapeInterface decouples this Main app from any subshape object (Rectangle, Triangle, etc.). So if I need to add a Shape type object in the future, I don't have to modify the client code because it's been 'coded to the interface'. I only have to change the actual implementation in the concrete class itself.

            ShapeInterface shape = ShapeFactory.getNewInstance("triangle");
            shape.draw();

            Example B ------------- This code is easy to break because this Main app will be tightly coupled to every future shape object I need (if there comes a Rectangle, I will need to change the code to instantiate a Rectangle etc.). Also, the implementations are different and so I have to apply the appropriate implementation (Rectangle.draw(), Triangle.draw(), etc.)

            Triangle triangle = ShapeFactory.getNewInstance("triangle");
            triangle.draw();

            I understood this concept. Using an interface so that you won't have the change the code that uses the underlying concrete classes. Ok, understandable. I see the advantage. Here's the concept that [b]I don't understand[/b]: Example C ------------- This example illustrates composition instead of inheritance (Object A has an Object B rather than IS-A B). A can't print directly, it has to delegate to B. Fine, I understand that. What I don't understand is the advantage of this. Couple of questions: 1) How was it decoupled? 2) Will putting the interface in between A and B decouple their relationship? 3) What if there was no interface between them? Then A would be tightly coupled to B? 4) If B disappears, can I simply replace it with a C class thanks to the interface? If I don't understand these concepts then I can't move on in my design.

            public interface ABInterface {
            public void print();
            }

            public class A implements ABInterface {
            private B b;

            public A() {
                b = new B();
            }
            
            public void print() {
                b.print();
            }
            

            }

            public class B implements ABInterface {
            public void print(){
            System.out.println("Testing B");
            }
            }

            Ok, so that's that. However, I have another big problem: Say I have a couple of classes that implement a particular interface. Now say that later, there is one method

            J Offline
            J Offline
            jschell
            wrote on last edited by
            #5

            CsTreval wrote:

            Any ideas on this?

            Don't over use it. For that matter don't over use any abstraction concept. As an example of that one could suppose that because interfaces are "good" and so are factories that every class should have its own interface and its own factory. And that is just wrong. Also be aware that in terms of management abstraction conceptions via syntax are only self maintaining when there is only one deliverable. So if you have two deliverables (or 20) and you want to remove an interface method from shared code then you are going to need to determine the impact on all of the deliverables.

            CsTreval wrote:

            This example illustrates composition instead of inheritance

            You should strive to favor composition over inheritance. Or more specifically do not over use inheritance and specifically be wary of using inheritance solely as a mechanism to facilitate shared behavior (only.)

            CsTreval wrote:

            1. How was it decoupled?

            Answered by other responder.

            CsTreval wrote:

            1. Will putting the interface in between A and B decouple their relationship?

            Yes. However whether it is appropriate or not is a different question.

            CsTreval wrote:

            1. What if there was no interface between them? Then A would be tightly coupled to B?

            Yes. Again though that might not be appropriate. And especially for this specific example since 'print' suggests something that is very specific.

            CsTreval wrote:

            1. If B disappears, can I simply replace it with a C class thanks to the interface?

            Not sure what the question is. If you delete B and create C then updating A is still going to be easy even if B/C didn't implement ABInterface. For your example the same work would be required with or without the interface.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups