Useless interfaces

后端 未结 25 1504
南笙
南笙 2020-12-14 01:42

Why would you ever use an interface if you are only going to have one implementation of it?

相关标签:
25条回答
  • 2020-12-14 02:25

    because an interface is best suited to definitively indicate the type

    0 讨论(0)
  • 2020-12-14 02:27

    It bothers me too when people make an Interface, an Abstract, and an actual implementation for every class, even if there will never be more than one, and the 3 files are all nearly empty.

    However, big uses would be:

    1. Future expansion / enhancements placeholder

    2. Easy to implement Inversion of Control / Dependency Injection

    3. Easy to implement mocks for unit testing.

    *Edit:

    I noticed you have Spring in your tags too. If using Spring, then #2 above is probably the biggie. Its easier to design classes that expect interfaces, and you can swap out actual implementations of the interface in the Spring configuration (Dependency Injection).

    0 讨论(0)
  • 2020-12-14 02:27

    Single-method interfaces are usually avoidable when you work in languages which allow you to pass around functions as first-order values. To name a few examples:


    Single-method Interfaces to pass around snippets of implementation logic:

    public interface IComparable<T>
    {
        int CompareTo(T first, T second);
    }
    
    public static class Array<T>
    {
        public void Sort(T[] input)
        {
            if (T is IComparable) { /* sorting implementation */ }
            else { Throw new Exception("Doesn't implement IComparable"); }
        }
    }
    

    Can be replaced with:

    public static class Array<T>
    {
        public void Sort(T[] input, Func<T, T, int> compare)
        {
            /* sorting implementation */
        }
    }
    

    I consider the functional style above more readable and reusable.


    Single-method interfaces for dependency-injection / mocking:

    public interface IFailureNotifier
    {
        void HandleFailure(Exception ex);
    }
    
    public class TransactionProcessor
    {
        public IFailureNotifier FailureNotifier { get; set; }
    
        public TransactionProcessor(IFailureNotifier failureNotifier)
        {
            this.FailureNotifier = failureNotifier;
        }
    
        public void ProcessItems(object[] items)
        {
            try
            {
                for(object item in items) { /* do stuff */ }
            }
            catch(Exception ex)
            {
                FailureNotifier.HandleFailure(ex);
            }
        }
    }
    

    Can be re-written as:

    public class TransactionProcessor
    {
        public Action<Exception> FailureNotifier { get; set; }
    
        public TransactionProcessor(Action<Exception> failureNotifier)
        {
            this.FailureNotifier = failureNotifier;
        }
    
        public void ProcessItems(object[] items)
        {
            try
            {
                for(object item in items) { /* do stuff */ }
            }
            catch(Exception ex)
            {
                FailureNotifier(ex);
            }
        }
    }
    

    The advantage of this approach is simpler class library: I don't need a soup of tiny objects to implement IFailureNotifier's single method, I just pass the implementation directly instead.


    That's not to say that single-method interfaces are bad, you still want to wrap up a function in an interface if the function depends on underlying mutable state. However I personally find that most of the benefits of single-method interfaces are already provided by first-class functions.

    0 讨论(0)
  • 2020-12-14 02:30

    To promote loose coupling, it is considered better design to rely on an abstract dependency than tying yourself to a concrete class.

    One example of where this practice is especially useful is Spring's proxy-based remoting approach., where your single implementation resides in a different JVM.

    0 讨论(0)
  • 2020-12-14 02:31

    I prefer not to define an interface, unless I really need it. IMO, interface is one of the most abused design patterns. I think the case you are refering to is due to asking the question "What if ... will be needed in the future?". Since the developer is not a fortune teller yet... I would stick to interface "under-usage".

    0 讨论(0)
  • 2020-12-14 02:32

    It can be very good practice to set up an interface as a spec to code your class to.

    If you determine the public methods/functionality that your interface will have you can lock that in place. Then it becomes much easier to code a class when you have a clear functionality in mind for it.

    I feel it is more important to make writing good code easier than keep the code base clean.

    0 讨论(0)
提交回复
热议问题