350

25000 errors basically means "don't touch that". Change it back. Create a new class that has the desired interface and slowly move the consumers of the class to the new one. Depending on the language, you can mark the old class as deprecated, which may cause all sorts of compiler warnings, but won't actually break your build. Unfortunately these things ...


208

Strictly speaking, no you don't, YAGNI applies. That said, the time you'll spend creating the interface is minimal, especially if you have a handy code generation tool doing most of the job for you. If you are uncertain on whether you are going to need the interface of or not, I'd say it's better to err on the side of towards supporting the definition of an ...


203

Reluctance to modify code for the sake of testing shows that a developer hasn't understood the role of tests, and by implication, their own role in the organization. The software business revolves around delivering a code base that creates business value. We have found, through long and bitter experience, that we cannot create such code bases of nontrivial ...


149

I would answer that whether you need an interface or not does not depend on how many classes will implement it. Interfaces are a tool for defining contracts between multiple subsystems of your application; so what really matters is how your application is divided into subsystems. There should be interfaces as the front-end to encapsulated subsystems, no ...


127

I am surprised nobody mentioned yet one of the most glaring examples: software-defined radio. If you took a present-day smartphone back in time some 50 years and showed it to a competent engineer from the mid-1960s, he would be able to comprehend most of it. That a supercomputer can be reduced to something that fits in your pocket? Check. That you can have ...


101

Interfaces are designated to define a behaviour, i.e. a set of prototypes of functions/methods. The types implementing the interface will implement that behavior, so when you deal with such a type you know (partly) what behavior it has. There is no need to define an interface if you know that the behavior defined by it will be used only once. KISS (keep it ...


98

It starts with a dog. In particular, a pug. The pug has various behaviors: public class Pug { private String name; public Pug(String n) { name = n; } public String getName() { return name; } public String bark() { return "Arf!"; } public boolean hasCurlyTail() { return ...


94

Your company is following the SOLID principles and targeting an interface rather than concrete class adds zero overhead to the program. What they're doing is a very moderate amount of extra work that can pay back volumes when the assumptions that you are making end up being false...and you can never tell what assumption that's going to be. What you're ...


90

You seem to suggest that the complexity of an interface is measured by the number of elements it has (methods, in this case). Many would argue that having to remember that the charge method can be used to return the balance of a Client adds much more complexity than having the extra element of the getBalance method. Making things more explicit is much ...


82

Preferring composition isn't just about polymorphism. Although that is part of it, and you are right that (at least in nominally typed languages) what people really mean is "prefer a combination of composition and interface implementation." But, the reasons to prefer composition (in many circumstances) are profound. Polymorphism is about one thing ...


82

Given your question I assume that the reasons for this kind design are not documented. Unjustified usage of an interface with single implementation is plain wrong since this violates YAGNI. In my experience, this also has been pretty damaging maintenance-wise, mostly because methods implementing interface are forced to be unnecessarily public. After you ...


81

I prefer SetVisible(bool visible), because it lets me write client code like this: SetVisible(DetermineIfItShouldBeVisible()); instead of having to write if (DetermineIfItShouldBeVisible()) { Show(); } else { Hide(); } The SetVisible approach may also allow for easier implementation. For example, if a particular concrete class simply delegates ...


79

Divide and conquer with refactorings Often, breaking up the change that you need to do into smaller steps can help because you can then perform most of the smaller steps in a way that doesn't break the software at all. Refactoring tools help a lot with such tasks. Divide First, identify the smallest possible changes (in terms of logical changes, not in ...


78

UPDATE: I've revised this answer. A number of good points were raised in the comments that deserved calling out. If my class implements an interface then can I say that I'm following inheritance? It is not entirely clear what you mean by "following inheritance". Let's ask a slightly different question? What is inheritance? When members of one type X ...


76

Programming to an interface means that you should focus on what the code does, not how it is actually implemented. See Telastyn's answer to Understanding “programming to an interface”. Interface classes help to enforce this guideline, but this does not mean that you should never use concrete classes. I really like the zip code example: In 1963, the United ...


75

It's not as simple as you might think. Let's break it down. Writing unit tests is definitely a good thing. BUT! Any change to your code can introduce a bug. So changing the code without a good business reason is not a good idea. Your 'very thin' webapi doesn't seem like the greatest case for unit testing. Changing code and tests at the same time is a bad ...


66

I think the confusing part is that if you write int Property { get; set; } inside a class, then it's an auto-property with implicit backing field. But if you write exactly the same thing in an interface, then it's not auto-property, it just declares that the property is part of the interface and that any type that implements the interface has to contain ...


62

While in theory you shouldn't have an interface just for having-an-interface's sake, Yannis Rizos's answer hints at further complications: When you're writing unit tests and using mock frameworks such as Moq or FakeItEasy (to name the two most recent ones I've used), you're implicitly creating another class that implements the interface. Searching the code ...


62

Invite him to learn about YAGNI. The Rationale part of Wikipedia page may be particularly interesting here: According to those who advocate the YAGNI approach, the temptation to write code that is not necessary at the moment, but might be in the future, has the following disadvantages: The time spent is taken from adding, testing or improving the ...


59

A good motivating example for default methods is in the Java standard library, where you now have list.sort(ordering); instead of Collections.sort(list, ordering); I don't think they could have done that otherwise without more than one identical implementation of List.sort.


52

This is a classical example of how people decide to violate the Liskov Subtitution Principle. I strongly discourage it but would encourage possibly a different solution: Perhaps the class you're writing doesn't provide the functionality the interface prescribes if it doesn't have use of all the members of the interface. Alternatively, that interface may be ...


51

Polymorphism does not necessarily imply inheritance. Often inheritance is used as an easy means to implement Polymorphic behaviour, because it is convenient to classify similar behaving objects as having entirely common root structure and behaviour. Think of all those car and dog code examples you've seen over the years. But what about objects that aren't ...


49

Visual Studio doesn't know what code you intend to write so includes the most common namespaces for you by default in the "new class" template. This is done so you don't have to resolve all the references for every single line of new code you write. Once you have written your basic code if you right click and select Organize Usings > Remove and Sort it will ...


48

"Programming to an interface" means, that when possible, one should refer to a more abstract level of a class (an interface, abstract class, or sometimes a superclass of some sort), instead of refering to a concrete implementation. This is not correct. Or at least, it is not entirely correct. The more important point comes from a program design perspective....


48

The correct answer is in fact found in the Java Documentation, which states: [d]efault methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. This has been a long-standing source of pain in Java, because interfaces tended to be impossible ...


47

I'd have to agree with your coworker. In both examples you give, BaseWorker defines the abstract method Work(), which means that all subclasses are capable of meeting IFooWorker's contract. In this case, I think BaseWorker should implement the interface, and that implementation would be inherited by its subclasses. This will save you from having to ...


47

"Programming to an interface" does not require the language keyword interface. It means you care about the what promises the type provides about it's behaviour. You don't care how java.lang.String does all the things it does, only that you can write name = "aacceeggiikk"; age = 42; "Programming to an implementation" would be using reflection to get at the ...


45

It's a redesign but you can prevent misuse of many APIs but not having available any method that shouldn't be called. For example, instead of first you init, then you start, then you stop Your constructor inits an object that can be started and start creates a session that can be stopped. Of course if you have a restriction to one session at a time you ...


Only top voted, non community-wiki answers of a minimum length are eligible