Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange

Hot answers tagged

187

Basically we want things to behave sensibly. Consider the following problem: I am given a group of rectangles and I want to increase their area by 10%. So what I do is I set the length of the rectangle to 1.1 times what it was before. public void IncreaseRectangleSizeByTenPercent(IEnumerable<Rectangle> rectangles) { foreach(var rectangle in ...


186

S = Single Responsibility Principle So I'd expect to see a well organised folder/file structure & Object Hierarchy. Each class/piece of functionality should be named that its functionality is very obvious, and it should only contain logic to perform that task. If you saw huge manager classes with thousand of lines of code, that would be a sign that ...


172

Yes, it is a violation of the LSP. Liskov Substitution Principle requires that Preconditions cannot be strengthened in a subtype. Postconditions cannot be weakened in a subtype. Invariants of the supertype must be preserved in a subtype. History constraint (the "history rule"). Objects are regarded as being modifiable only through their methods (...


135

final expresses intent. It tells the user of a class, method or variable "This element is not supposed to change, and if you want to change it, you haven't understood the existing design." This is important because program architecture would be really, really hard if you had to anticipate that every class and every method you ever write might be changed to ...


117

Gosh, there are some weird misconceptions on what OCP and LSP and some are due to mismatch of some terminologies and confusing examples. Both principles are only the "same thing" if you implement them the same way. Patterns usually follow the principles in one way or another with few exceptions. The differences will be explained further down but first let ...


112

One way to wrap your head around this is to imagine potential requirements changes in future projects and ask yourself what you will need to do to make them happen. For example: New business requirement: Users located in California get a special discount. Example of "good" change: I need to modify code in a class that computes discounts. ...


104

These guidelines are a compass, not a map. They point you in a sensible direction. But they can't really tell you in absolute terms which solution is “best”. At some point, you need to stop walking into the direction your compass is pointing, because you have arrived at your destination. Clean Code encourages you to divide your code into very small, obvious ...


96

Classes should do 1 thing and do it well Yes, that is generally a good approach. but from the other hand they should represent real object we work with. No, that is a IMHO common misunderstanding. A good beginner's access to OOP is often "start with objects representing things from the real world", that is true. However, you should not stop with ...


86

In many cartoons or other media, the forces of good and evil are often illustrated by an angel and a demon sitting on the character's shoulders. In our story here, instead of good and evil, we have SOLID on one shoulder, and YAGNI (You ain't gonna need it!) sitting on the other. SOLID principles taken to the max are best suited for huge, complex, ultra-...


84

Your observation is correct, the SOLID principles are IMHO made with reusable libraries or framework code in mind. When you just follow all of them blindly, without asking if it makes sense or not, you are risking to overgeneralize and invest a lot more effort into your system than probably necessary. This is a trade-off, and it needs some experience to ...


80

Yes. This violates LSP. My suggestion is to add CanClose method/property to base task, so any task can tell if task in this state can be closed. It can also provide reason why. And remove the virtual from Close. Based on my comment: public class Task { public Status Status { get; private set; } public virtual bool CanClose(out String reason) { ...


74

Practically speaking, responsibilities are bounded by those things that are likely to change. Thus, there's no scientific or formulaic way to arrive at what constitutes a responsibility, unfortunately. It's a judgement call. It's about what, in your experience, is likely to change. We tend to apply the language of the principle in a hyperbolic, literal, ...


61

The ideal number of arguments for a function is zero (niladic) No! The ideal number of arguments for a function is one. If it's zero, then you are guaranteeing that the function has to access external information to be able to perform an action. "Uncle" Bob got this one very wrong. Regarding your code, your first example only has two lines in the block ...


59

It avoids the Fragile Base Class Problem. Every class comes with a set of implicit or explicit guarantees and invariants. The Liskov Substitution Principle mandates that all subtypes of that class must also provide all these guarantees. However, it is really easy to violate this if we don't use final. For example, let's have a password checker: public class ...


57

Modularity. Any decent language will give you the means to glue together pieces of code, but there's no general way to unglue a large piece of code without the programmer performing surgery on the source. By jamming a lot of tasks into one code construct, you rob yourself and others of the opportunity to combine its pieces in other ways, and introduce ...


56

Yes, SOLID is a very good way to design code that can be easily tested. As a short primer: S - Single Responsibility Principle: An object should do exactly one thing, and should be the only object in the codebase that does that one thing. For instance, take a domain class, say an Invoice. The Invoice class should represent the data structure and business ...


51

I was in your shoes couple months ago till I found a very helpful article. Each principle is nicely explained with real-world situations that each software developer may face in their projects. I am cutting short here and pointing to the reference - S.O.L.I.D. Software Development, One Step at a Time. As pointed in comments, there is another very good pdf ...


50

This is not a God object. It seems like it is because there is so much here, but, in a way, it's doing nothing at all. There is no behavior code here. This isn't an omnipotent God that does everything. It just finds everything. It's less a true object at all and more of a data structure. This pattern has a more proper name: Service Locator. It strongly ...


49

From my experience, when writing an app, you have three choices: Write code solely to fulfil the requirements, Write generic code that anticipates future requirements, as well as fulfilling the current requirements, Write code that only fulfils the current requirements, but in a way that's easy to change later to meet other needs. In the first case, it's ...


44

Doc Brown is spot-on: classes don’t need to represent real-world objects. They just need to be useful. Classes are fundamentally merely additional types, and what does int or string correspond to in the real world? They are abstract descriptions, not concrete, tangible things. That said, your case is special. According to your description: And if ...


42

No. SOLID exists as guidelines to account for inevitable change. Are you really never going to change your logging library, or target, or filtering, or formatting, or...? Are you really not going to change your caching library, or target, or strategy, or scoping, or...? Of course you are. At the very least, you're going to want to mock these things in a ...


41

SOLID turns out to be a good idea for the functional/imperative realms too. SRP - 'Only do one thing' was taken from imperative programming in the first place. Having small, focused functions is good. OCP - Allowing you to change behaviors without modifying code is good. Functional programming uses higher order functions more than inheritance, but the ...


38

Yes This is the whole point of the term "cross-cutting concern" - it means something that does not fit neatly in the SOLID principle. This is where idealism meets up with reality. People semi-new to SOLID and cross-cutting often run into this mental challenge. It's OK, don't freak out. Strive to put everything into terms of SOLID, but there are a few ...


37

Dependency Inversion in OOP means that you code against an interface which is then provided by an implementation in an object. Languages that support higher language functions can often solve simple dependency inversion problems by passing behaviour as a function instead of an object which implements an interface in the OO-sense. In such languages, the ...


36

Royal Family: They don't do anything particularly crazy but they have a billion titles and are related to most other royals somehow.


36

But isn't the problem here caused by having Circle be the subtype of an Ellipse? Couldn't we reverse the relationship? The problem with this (and the square/rectangle problem) is falsely assuming a relationship in one domain (geometry) holds in another (behaviour) A circle and ellipse are related if you are viewing them through the prism of geometrical ...


35

I'll go through your points numerically, but first, there's something you should be very careful of: don't conflate how a consumer uses a library with how the library is implemented. Good examples of this are Entity Framework (which you yourself cite as a good library) and ASP.NET's MVC. Both of these do an awful lot under the hood with, for example, ...


35

I am just designing my application and I am not sure if I understand SOLID and OOP correctly. Been at this over 20 years and I'm not sure either. Classes should do 1 thing and do it well Hard to go wrong here. they should represent real objects we work with. Oh really? Let me introduce you to the single most popular and successful class of all ...


33

I'm surprised that no one has yet mentioned Effective Java, 2nd Edition by Joshua Bloch (which should be required reading for every Java developer at least). Item 17 in the book discusses this in detail, and is titled: "Design and document for inheritance or else prohibit it". I won't repeat all the good advice in the book, but these particular paragraphs ...


33

The classic example of square not being able to substitute for rectangle without violating LSP is a bit of a "trick question" and sophistic. The problem arises because of a conflation... i.e. an implementation of a rectangle is not really a rectangle. Having independently settable width and height is not an inherent property of a rectangle. A rectangle is ...


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