Are there established alternatives to ISomething / ISomethingable for interfaces?

后端 未结 9 1980
囚心锁ツ
囚心锁ツ 2021-02-08 04:37

The .NET standard of prefixing an interface name with an I seems to be becoming widespread and isn\'t just limited to .NET any more. I have come across a lot of Java code that u

9条回答
  •  一整个雨季
    2021-02-08 05:13

    My main assumption is that the most important thing is to maintain readability in domain part of the implementation. Therefore:

    • If you have one behaviour and one possible implementation, then just don't create an interface:

      public class StackOverflowAnswerGenerator { }

    • If you have one behaviour and many possible implementations, then there is no problem and you can just drop the "I", and have:

      public interface StackOverflowAnswerGenerator {}

      public class StupidStackOverflowAnswerGenerator : StackOverflowAnswerGenerator {}

      public class RandomStackOverflowAnswerGenerator : StackOverflowAnswerGenerator {}

      public class GoogleSearchStackoverflowAnswerGenerator : StackOverflowAnswerGenerator {}

      //...

    • The real problem comes when you have one behaviour and one possible implementation but you need an interface to describe its behaviour (for example for convenient testing, because of convention in your project, using some library/framework which enforces this, ...). Possible solutions, other from prefixing the interface are:

      a) Prefix or suffix the implementation (as stated in some other answers in this topic)

      b) Use a different namespace for interface:

      namespace StackOverflowAnswerMachine.Interfaces 
      {
        public interface StackOverflowAnswerGenerator {}
      }
      
      namespace StackOverflowAnswerMachine 
      { 
        public class StackOverflowAnswerGenerator : Interfaces.StackOverflowAnswerGenerator
      {}
      
      }
      

      c) Use a different namespace for implementation:

      namespace StackOverflowAnswerMachine 
      {
        public interface StackOverflowAnswerGenerator {}
      }
      
      namespace StackOverflowAnswerMachine.Implementations 
      { 
        public class StackOverflowAnswerGenerator : StackOverflowAnswerMachine.StackOverflowAnswerGenerator 
      {}
      
      }
      

    Even though I think the last possibility is the cleanest, its one drawback is that even though using StackOverflowAnswerMachine; gives you access to all domain objects you must prefix all domain interfaces not to be confused with their implementations. That may feel like something not very convenient but in clean design usually a class doesn't use many other domain objects, and mostly you need to use the prefix only in field declaration and constructor parameter list. So, that is my current recommendation.

    The client of domain functionality shouldn't need to know whether they're using an interface, an abstract class or a concrete class. If they need to know this, then there is some serious problem in such a project, because it has domain logic and infrastructural concerns mixed on the same abstraction layer. Therefore I recommend "a" or "c" solutions.

提交回复
热议问题