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. Design and Architecture
  4. Dilemma on exposing methods in interface based programming

Dilemma on exposing methods in interface based programming

Scheduled Pinned Locked Moved Design and Architecture
helplearning
10 Posts 4 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.
  • S Offline
    S Offline
    SSEAR
    wrote on last edited by
    #1

    Recently I fell in love with dependency injection and interface based programming. Though, as a beginner, I couldn’t grasp all the advantages of this methodology, I greatly influenced in the discipline we can bring into the project to handle the army of objects. What I learned that by using interface based programming, components are expose their functionalities only though an interface. At first I designed as like below.

    namespace Component1
    {
    public interface Interface1
    {
    void Func();
    }

    public class Class1 : Interface1
    {
        public void Func() { }
    }
    
    public static class IOContainer
    {
        public static void Register() { }
    
        public static TInterface Resolve() { }
    }
    

    }

    One drawback I found here that someone can directly create objects of Class1 and use its functions. This will break the essence of interface based programming. So I redesigned it like below.

    namespace Component1
    {
    public interface Interface1
    {
    void Func();
    }

    internal class Class1 : Interface1
    {
        public void Func() { }
    }
    
    public static class IOContainer
    {
        internal static void Register() { }
    
        public static void Register()
        {
            Register();
        }
    
        public static TInterface Resolve() { }
    }
    

    }

    This will work fine. So no one can access the implementations from outside the assembly. They have to call Register function and Resolve function to create objects. The component will use only in one discipline. But I fell I lost flexibility. Outsider can't determine which class should resolve at run time. Both methods have their own advantages and disadvantages. Kindly help me to choose a suitable method. Thanks in advance, Thomas

    V J B 3 Replies Last reply
    0
    • S SSEAR

      Recently I fell in love with dependency injection and interface based programming. Though, as a beginner, I couldn’t grasp all the advantages of this methodology, I greatly influenced in the discipline we can bring into the project to handle the army of objects. What I learned that by using interface based programming, components are expose their functionalities only though an interface. At first I designed as like below.

      namespace Component1
      {
      public interface Interface1
      {
      void Func();
      }

      public class Class1 : Interface1
      {
          public void Func() { }
      }
      
      public static class IOContainer
      {
          public static void Register() { }
      
          public static TInterface Resolve() { }
      }
      

      }

      One drawback I found here that someone can directly create objects of Class1 and use its functions. This will break the essence of interface based programming. So I redesigned it like below.

      namespace Component1
      {
      public interface Interface1
      {
      void Func();
      }

      internal class Class1 : Interface1
      {
          public void Func() { }
      }
      
      public static class IOContainer
      {
          internal static void Register() { }
      
          public static void Register()
          {
              Register();
          }
      
          public static TInterface Resolve() { }
      }
      

      }

      This will work fine. So no one can access the implementations from outside the assembly. They have to call Register function and Resolve function to create objects. The component will use only in one discipline. But I fell I lost flexibility. Outsider can't determine which class should resolve at run time. Both methods have their own advantages and disadvantages. Kindly help me to choose a suitable method. Thanks in advance, Thomas

      V Offline
      V Offline
      VallarasuS
      wrote on last edited by
      #2

      Explicit implementation might help!? Do i make sense here?!

      public class Foo : ILazy
      {
          void ILazy.Sleep()
          {
      
          }
      }
      
      public interface ILazy
      {
          void Sleep();
      }
      
         var foo = new Foo();
         ((ILazy)foo).Sleep();
      

      Hope it helps!!

      Regards Vallarasu S | FSharpMe.blogspot.com

      1 Reply Last reply
      0
      • S SSEAR

        Recently I fell in love with dependency injection and interface based programming. Though, as a beginner, I couldn’t grasp all the advantages of this methodology, I greatly influenced in the discipline we can bring into the project to handle the army of objects. What I learned that by using interface based programming, components are expose their functionalities only though an interface. At first I designed as like below.

        namespace Component1
        {
        public interface Interface1
        {
        void Func();
        }

        public class Class1 : Interface1
        {
            public void Func() { }
        }
        
        public static class IOContainer
        {
            public static void Register() { }
        
            public static TInterface Resolve() { }
        }
        

        }

        One drawback I found here that someone can directly create objects of Class1 and use its functions. This will break the essence of interface based programming. So I redesigned it like below.

        namespace Component1
        {
        public interface Interface1
        {
        void Func();
        }

        internal class Class1 : Interface1
        {
            public void Func() { }
        }
        
        public static class IOContainer
        {
            internal static void Register() { }
        
            public static void Register()
            {
                Register();
            }
        
            public static TInterface Resolve() { }
        }
        

        }

        This will work fine. So no one can access the implementations from outside the assembly. They have to call Register function and Resolve function to create objects. The component will use only in one discipline. But I fell I lost flexibility. Outsider can't determine which class should resolve at run time. Both methods have their own advantages and disadvantages. Kindly help me to choose a suitable method. Thanks in advance, Thomas

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

        Keep in mind that all things should be done in moderation. Not everything needs interfaces and there is very seldom a need to "protect" code from users. In a very large number of cases code that is using other code will always directly create other classes, because it is expedient and no other requirements exist. However to solve a 'creation' problem one uses a Factory Pattern. This of course supposes that there is a problem in the first place.

        S 1 Reply Last reply
        0
        • J jschell

          Keep in mind that all things should be done in moderation. Not everything needs interfaces and there is very seldom a need to "protect" code from users. In a very large number of cases code that is using other code will always directly create other classes, because it is expedient and no other requirements exist. However to solve a 'creation' problem one uses a Factory Pattern. This of course supposes that there is a problem in the first place.

          S Offline
          S Offline
          SSEAR
          wrote on last edited by
          #4

          jschell wrote:

          Not everything needs interfaces and there is very seldom a need to "protect" code from users. In a very large number of cases code that is using other code will always directly create other classes, because it is expedient and no other requirements exist.

          Though I agree with you that not all the code are need not protected, still i have to implement interfaces in core areas. This is because the reason to implement interfaces is to develop extendable, maintainable and testable code.

          jschell wrote:

          However to solve a 'creation' problem one uses a Factory Pattern. This of course supposes that there is a problem in the first place.

          I didnt get this. Can you please explain it?

          J 1 Reply Last reply
          0
          • S SSEAR

            Recently I fell in love with dependency injection and interface based programming. Though, as a beginner, I couldn’t grasp all the advantages of this methodology, I greatly influenced in the discipline we can bring into the project to handle the army of objects. What I learned that by using interface based programming, components are expose their functionalities only though an interface. At first I designed as like below.

            namespace Component1
            {
            public interface Interface1
            {
            void Func();
            }

            public class Class1 : Interface1
            {
                public void Func() { }
            }
            
            public static class IOContainer
            {
                public static void Register() { }
            
                public static TInterface Resolve() { }
            }
            

            }

            One drawback I found here that someone can directly create objects of Class1 and use its functions. This will break the essence of interface based programming. So I redesigned it like below.

            namespace Component1
            {
            public interface Interface1
            {
            void Func();
            }

            internal class Class1 : Interface1
            {
                public void Func() { }
            }
            
            public static class IOContainer
            {
                internal static void Register() { }
            
                public static void Register()
                {
                    Register();
                }
            
                public static TInterface Resolve() { }
            }
            

            }

            This will work fine. So no one can access the implementations from outside the assembly. They have to call Register function and Resolve function to create objects. The component will use only in one discipline. But I fell I lost flexibility. Outsider can't determine which class should resolve at run time. Both methods have their own advantages and disadvantages. Kindly help me to choose a suitable method. Thanks in advance, Thomas

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

            I don't understand what the problem with allowing users to create instances of their classes directly is. (Users in this case meaning users of the framework; that could well be you as well.) The important thing about interface based programming is that the core code, including the dependency injection mechanism if you want such a thing, deal with the interfaces. Methods in your core logic should take and return interfaces, not concrete subclasses; this makes them easily mockable and re-usable. But there's no reason to try to prevent someone from declaring a Class1 which implements one of the public interfaces and creating it directly; sometimes that's actually what you need in a specific case. You should advise your users (again, that might be yourself or other team members) that generally it's better to use the interfaces and get a resolved instance from the container, but that should be 'enforced' with coder discipline, not a technical solution. A final point is that it is essentially impossible to provide an extensible container, which allows registration of arbitrary classes, and also to prevent people instantiating those classes directly, because the container needs to use a constructor to resolve a request. You could require that a factory class is passed instead, but that's abstraction for the sake of it, and if it's a user specified factory, they can just call the factory method directly anyway.

            S 1 Reply Last reply
            0
            • S SSEAR

              jschell wrote:

              Not everything needs interfaces and there is very seldom a need to "protect" code from users. In a very large number of cases code that is using other code will always directly create other classes, because it is expedient and no other requirements exist.

              Though I agree with you that not all the code are need not protected, still i have to implement interfaces in core areas. This is because the reason to implement interfaces is to develop extendable, maintainable and testable code.

              jschell wrote:

              However to solve a 'creation' problem one uses a Factory Pattern. This of course supposes that there is a problem in the first place.

              I didnt get this. Can you please explain it?

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

              SSEAR wrote:

              develop extendable, maintainable and testable code.

              Those are feel good subjective terms, especially the first two. One can create code using interfaces that meet none of those.

              SSEAR wrote:

              Can you please explain it?

              Google the following term with the quotes "Factory Pattern"

              S 1 Reply Last reply
              0
              • J jschell

                SSEAR wrote:

                develop extendable, maintainable and testable code.

                Those are feel good subjective terms, especially the first two. One can create code using interfaces that meet none of those.

                SSEAR wrote:

                Can you please explain it?

                Google the following term with the quotes "Factory Pattern"

                S Offline
                S Offline
                SSEAR
                wrote on last edited by
                #7

                jschell wrote:

                Those are feel good subjective terms, especially the first two.
                One can create code using interfaces that meet none of those.

                So you think dependency injection does not solve these issues?

                J 1 Reply Last reply
                0
                • B BobJanova

                  I don't understand what the problem with allowing users to create instances of their classes directly is. (Users in this case meaning users of the framework; that could well be you as well.) The important thing about interface based programming is that the core code, including the dependency injection mechanism if you want such a thing, deal with the interfaces. Methods in your core logic should take and return interfaces, not concrete subclasses; this makes them easily mockable and re-usable. But there's no reason to try to prevent someone from declaring a Class1 which implements one of the public interfaces and creating it directly; sometimes that's actually what you need in a specific case. You should advise your users (again, that might be yourself or other team members) that generally it's better to use the interfaces and get a resolved instance from the container, but that should be 'enforced' with coder discipline, not a technical solution. A final point is that it is essentially impossible to provide an extensible container, which allows registration of arbitrary classes, and also to prevent people instantiating those classes directly, because the container needs to use a constructor to resolve a request. You could require that a factory class is passed instead, but that's abstraction for the sake of it, and if it's a user specified factory, they can just call the factory method directly anyway.

                  S Offline
                  S Offline
                  SSEAR
                  wrote on last edited by
                  #8

                  BobJanova wrote:

                  I don't understand what the problem with allowing users to create instances of their classes directly is. (Users in this case meaning users of the framework; that could well be you as well.)

                  Last month I developed a Microsoft Exchange Server wrapper component. Interfaces will expose methods and there is a wrapper class to resolve the implementation using an IOC container. That was for an old version of exchange server. I uploaded the code to the code database. Few days later the Exchange Server upgraded and there was a requirement to implement the new API. So I created new classes for the newer version and also changed the wrapper class to register new classes with IOC container. But some developers from other projects directly access the classes of old version so that they lost the new changes. As you said I can advise them to follow this discipline. But I feel it is a burden for me. I have to spend my precious time to watch them. Hope you understand my situation.

                  J 1 Reply Last reply
                  0
                  • S SSEAR

                    jschell wrote:

                    Those are feel good subjective terms, especially the first two.
                    One can create code using interfaces that meet none of those.

                    So you think dependency injection does not solve these issues?

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

                    SSEAR wrote:

                    So you think dependency injection does not solve these issues?

                    First one can write code using dependency injection which fails all of the issues you listed. Second the terms you posted are almost always used subjectively, in that there are no objective measurements in place to verify success or failure.

                    1 Reply Last reply
                    0
                    • S SSEAR

                      BobJanova wrote:

                      I don't understand what the problem with allowing users to create instances of their classes directly is. (Users in this case meaning users of the framework; that could well be you as well.)

                      Last month I developed a Microsoft Exchange Server wrapper component. Interfaces will expose methods and there is a wrapper class to resolve the implementation using an IOC container. That was for an old version of exchange server. I uploaded the code to the code database. Few days later the Exchange Server upgraded and there was a requirement to implement the new API. So I created new classes for the newer version and also changed the wrapper class to register new classes with IOC container. But some developers from other projects directly access the classes of old version so that they lost the new changes. As you said I can advise them to follow this discipline. But I feel it is a burden for me. I have to spend my precious time to watch them. Hope you understand my situation.

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

                      SSEAR wrote:

                      Hope you understand my situation.

                      I certainly don't. Some problem involving X occured some time ago. What X is is irrelevant. How long ago is irrelevant. From that some less than ideal situation occurred. The causes for that are one or more of the following. 1. You failed to implement all of the known functionality. 2. You failed to design for known future uses. 3. Other uses failed to use your design (and thus implementation) correctly. 4. New features were needed. Obviously 1/2 are your fault. 3 is not something that you fix with code, but instead fix it with process (humans interacting with other humans in a defined way with the goal of reducing future problems.) 4 is a benefit of software development since it insures that there will always be jobs.

                      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