Tag Info

Hot answers tagged

155

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 ...


147

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 ...


102

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 ...


53

Gosh, there are some weird misconceptions on what OCP and LSP and some are due to mismatch of some terminologies. 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. Lets take a dive into the principles and describe the discrepancy a bit better ...


52

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 ...


44

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) { ...


29

Better maintenance, easy testing, faster bug-fixing are just (very pleasant) outcomes of applying SRP. The main reason (as Robert C. Matin puts it) is: A class should have one, and only one, reason to change. In other words, SRP raises change locality. SRP also promotes DRY code. As long as we have classes that have only one responsibility, we may ...


27

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


27

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 ...


26

LSP applies to passing an instance of a class into a method, having the method do some stuff with that instance, and often produce some sort of result. This doesn't matter for static classes since in C# you cannot create an instance of a static class. Even more importantly, static classes are sealed and therefore cannot be inherited. This makes your ...


25

I think it's stated very well in that question which is one of the reasons that was voted so highly. Now when calling Close() on a Task, there is a chance the call will fail if it is a ProjectTask with the started status, when it wouldn't if it was a base Task. Imagine if you will: public void ProcessTaskAndClose(Task taskToProcess) { ...


25

[Note: I'm going to be talking about objects here. Objects is what object-oriented programming is about, after all, not classes.] What the responsibility of an object is depends mostly on your domain model. There are usually many ways to model the same domain, and you will choose one way or the other based on how the system is going to be used. As we all ...


24

It's always difficult to judge an approach based on a screencast, since the problems picked for demos are typically so small that applying principles like SOLID quickly makes it look like the solution is completely overengineered. I'd say SOLID principles are almost always useful. Once you become proficient with them, using them doesn't seem like something ...


22

I submit that this anti-pattern be named Jack of All Trades, or perhaps Too Many Hats.


21

my project managers told me that I am really in the wrong way and too idealist for the Bank world. GTFO! Time to leave and pity them. Why should you give a fuck? You know it'll cost them money in the long run with their incompetent staff. This ain't a game of technical discussion. This is about politics. Have them train the other developers or GTFO! ...


21

Is easy to create code to fix a particular problem. Is more complicated to create code that fixes that problem while allowing later changes to be made safely. SOLID provides a set of practices that makes the code better. As to which one is correct: All three of them. They are all benefits of using single responsibility and the reason that you should use it. ...


21

If all your objects are immutable, there is no problem. Every Square is also a Rectangle. All the properties of a Rectangle are also properties of a Square. The problem begins when you add the ability to modify the objects. Or really - when you start passing arguments to the object, not just reading property getters. There are modifications that you can do ...


19

First of all, TDD does not strictly force you to write SOLID code. You could do TDD and create one big mess if you wanted to. Of course, knowing SOLID principles helps, because otherwise you may just end up not having a good answer to many of your problems, and hence write bad code accompanied by bad tests. If you already know about SOLID principles, TDD ...


16

Tough spot. I think you can go two ways in parallel, standing your point and showing will to compromise: This is about money. As any dev job in fact, but since you emphasize the bank environment, this should work even better ;). Show them that your style saves money. Find an example of how a change in requirements could be done really easily because of ...


15

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 ...


15

If I had to give it a name, I think I'd call it the Hydra: In Greek mythology, the Lernaean Hydra (Greek: Λερναία Ὕδρα) was an ancient nameless serpent-like chthonic water beast, with reptilian traits, (as its name evinces) that possessed many heads — the poets mention more heads than the vase-painters could paint, and for each head cut off it grew ...


15

I do believe that this refers to what Robert Martin calls the Interface Segregation Principle. Interfaces are separated into small and concise ones so that the consumers (clients) will only have to know about the methods that are of interest to them. You can check out more on SOLID.


14

The God Object comes to mind; a single object that knows how to do EVERYTHING. This comes from low adherence to the "cohesion" requirements of the two major design methodologies; if you have an object with 23 interfaces, you have an object that knows how to be 23 different things to its users, and those 23 different things are likely not along the lines of a ...


14

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 ...


13

Liskov substitution principle states that a base class should be replaceable with any of his sub-classes without altering any of the desirable properties of the program. Since only ProjectTask raises an exception when closed, a program would have to be changed to acommodate for that, should ProjectTask be used in substitution of Task. So it is a violation. ...


13

It's a lot more simple than that quote makes it sound, accurate as it is. When you look at an inheritance hierarchy, imagine a method which receives an object of the base class. Now ask yourself, are there any assumptions that someone editing this method might make which would be invalid for that class. For example (originally seen on Uncle Bob's site): ...


12

Think about the problem at hand first and foremost. If you blindly apply the principles of YAGNI or SOLID, you can hurt yourself later on. Something that I hope we can all understand is that there is no "one" design approach that fits all problems. You can see evidence of that when a store sells a hat advertised as "one size fits all", but it doesn't fit ...


12

But, a majority of developers came to me in order to precise that all my code is too complex for reading comprehension Has it occurred to you at all that they may be right? I worked with someone who put a lot of effort into writing code which he described as elegant. He spent a lot of time decrying other people's work as not being elegant. When it ...


12

A lot of small classes and interfaces with dependency injection all over the place. Probably in a big project you would also use a IoC framework to help you construct and manage the lifetimes of all those small objects. See Which .NET Dependency Injection frameworks are worth looking into? Note that a big .NET project that STRICTLY follows SOLID principles ...


12

And why would Square be usable anywhere you expect a rectangle? Because that's part of what being a subtype means (see also: Liskov substitution principle). You can do, need to be able to do this: Square s = new Square(5); Rect r = s; doSomethingWith(r); // written assuming a Rect, actually calls Square methods You actually do this all the time ...



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