Although not a pure OOD principle - should DRY also be included when thinking about SOLID principles? If not - why not?
It's a bit like asking why you shouldn't add a monkey-wrench to a basket of apples: they're not really the same thing.
SOLID is a set of principles that specifically address object-oriented design.
DRY is, I'd say, somewhat orthogonal to those - it's a programming principle that can apply to anything you write.
(Having said that, the acronym is almost too good to pass up on)
I think "DRY" is probably not specific enough to make it into SOLID. "DRY" might be an underlying principle of the other principles, and it applies to any kind of development, not just object-oriented development, like SOLID does.
SOLID embraces DRY. If you ahdhere to the SOLID principles you are almost automatically DRY.
Related
Recently i'm reading the Clean Architecture by Robert Martin.
I have some misunderstading about couple of SOLID principles definitions. Exactly the Single Responsibility Principle and Open/Closed Principle.
Well for the first one we have the following
A class (module) should have only one reason to change
Where the reason means actor. Sounds pretty clear.
Move on the next one - OCP. Here we have such example
The misunderstood part is the Database and Interactor relation. We implement the Financial Data Gateway interface in the Database component by Financial Data Mapper, so we have two modules with one responsibility. Seems like SRP violation.
Am i right or just missing something for a correct understanding?
I would like to highlight that the listed design approach is neither object-oriented nor a good architecture to have for most if not all situations. Here is an article of mine with more details of why this is the case.
The single responsibility principle has also multiple, sometimes conflicting interpretations. What it should mean in an object-oriented context is basically strong cohesion and loose coupling. Here is a slidedeck of mine explaining all this from a pragmatical standpoint.
So, with due respect, I think you may have the wrong concept of SRP, OCP, the practicality or viability of the "Clean Architecture" and of object-orientation in general.
With all that said, the answer is: the grammar of your question is all wrong. There is no such thing as an "SRP violation". SRP is very loosely defined, and even if you pick an interpretation it is not a binary thing. It is a scale that depends heavily on requirements and context and can not (should not) be evaluated on its own in isolation.
Say I break the principle of Separation of Concerns (SoC) and deliberately write, plan, and design my code to break, avoid and go against the SoC principle.
What other OO and SOLID principles will necessarily be affected, and how? Is some SoC necessary for code to work, or can it be completely avoided?
S and O will be mostly affected, but you could still preserve L, I and D if you were disciplined. You can write bad code without following any design best practices and still get it to work. I see the data scientists at my company do this every day!
I am working on a very large ASP.NET application. The problem is that there is not a lot of logic behind the design. The original developer chose about ten classes and that was it. There is high coupling and low cohesion. For example, clsPerson holds all the functionality for Person and breakes most of the rules of SOLID.
I have started to incorporate design patterns into my toolkit. My question is: what is the best way to incorporate badly designed classes into the better design. For example, if you had a class clsStudent that contained all the Student functionality to date and then created a class called clsUndergraduate then would you simply derive clsStudent? I realise that a lot of this depends on context but I am looking for general guidelines.
There is a lot of information online that talks about SOLID, but not a lot that talks about how to adapt an existing application to be SOLID.
It could be argued that you should only aim to implement SOLID principles as, and when the need arrives. However, I'm an advocate and believe that it's not difficult to add elements of SOLIDity to your design without too much overhead or heartache.
Trying to move an existing model to a more SOLID model can be difficult. I would suggest taking small, manageable parts and gradually refactoring. If you have the safety net of automated tests, this should be achievable with confidence. If not, make sure you fully understand the scope of the changes you are making. It's easy to introduce subtle bugs. Ultimately, serious changes will be likely to introduce new tests anyway.
Complying with the SRP is likely to be the easiest place to start. Try to define the main responsibility of each class. If they currently have more than one responsibility, note them and look at how these responsibilities can be moved out and elsewhere. For example, many 'God' classes will be managing persistence, validation, initialisation, etc. along with business logic. See if you can begin to take the persistence code out and put it into mappers/repositories/etc.
If you do this logically and sequentially, my experience is that, as you go, making lots of mistakes along the way, the relevance and importance of the other principles will emerge and make themselves, sort of, obvious.
I found that as I experimented with SOLID principles, by reading and re-reading (mainly Bob Martin and ObjectMentor) more clarity emerges as you have practical experience of implementation. Don't forget the opening principles defined in the Gang of Four, also. Concepts like 'favour composition over inheritance' go hand-in-hand with SOLID OO principles.
Bear in mind that SOLID code is generally more complex than non-SOLID code and can, therefore, be harder to maintain and debug by those not familiar with it. Skeptics might lay the accusation of 'over-engineering' at your door, which can be difficult to argue against with those who haven't wrestled with enhancing/fixing tightly coupled, incohesive code.
Good luck. Please feel free to ask more as I'd love to hear the input of others on this subject. It's scope is wide and varied.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Are design patterns really language weaknesses?
After spending years pouring over books on OOP and the techniques of OOP, and recently getting involved more and more in Functional Styles of programming, would it be fair to extrapolate that design patterns are pointers to systemic problems with Object Oriented programming as a whole. Is there a fundamental flaw in Object Oriented Programming (not to be confused with Design), in that in the treatment of state through encapsulation, has led to more and more patterns to resolve the problems with such a paradigm.
I have not come to any conclusions on this, but my "gut" feeling is that there might be something more seriously wrong with the paradigm of OOP.
Is the very idea of encapsulation causing more problems than they solve.
A very good question and something that I have thought about some time ago. This is my conclusion \ opinion:
The idea of object oriented programming is not without flaws, but does provide the most complete design paradigm. If the problem domain is expressed properly, clearly defined object, who knows their responsibilities, can interact in a fairly elegant way, that closely resembles the real world interaction of the objects. (or ideas).
To make some of the more abstract concepts, specific, OOP makes some assertive statements. (Like encapsulation, not expose more than you have to and object responsibility).
Like all generic assumptions, there would be exceptions, when what normally would be a good idea, may not fit a particular problem in hand. It is also not helped by the fact that OOP, covers almost all problem conceived ( unlike AOP or even the more complex semantic modeling, that caters to a specific kind of problem).
So in situations, when you need to make exceptions and move away from OOP assertions, the designers needed a way to keep in bounds of good design, so that they do not stray far too much from accepted design practices.
So design patterns, for me is just case studies of problems, that will not be served by some of the core assertion of OOP. Apart from collaboration and collation of solution, design pattern also helps augment OOP. (especially for newbie designers).
Note: Most of the time, design patterns are not needed. There needs to be, clear justification for using patterns. I know, some greenhorns, trying to implement some design pattern, just because they know them ( and sometime not so greenhorns ;)). Its square peg, round hole problem
Good question, I started wondering about this my self a few weeks ago whilst getting more into Python and Scala.
I think yes and no. There are definitely some intrinsic problems with OOP and the encapsulation of state, but it's not to say that OOP itself is inherently a bad way of doing things. I think the problem is that when all you have is a hammer everything becomes a nail. OOP is great for some things, GUIs come to mind first but functional programming has very clear benefits as well.
It's worth noting that the newer functional programming languages like Scala haven't thrown objects away.
I haven't thought about the issue in great detail but I certainly agree that OOP has some issues that I haven't seen addressed, other than in the form of design patters, which really are addressing the symptoms rather than the disease.
No. Although you see slightly different design patterns, you certainly still see design patterns in functional code as well. The basic difference has little (if anything) to do with lack of state. Rather, it stems primarily from (most) functional languages providing enough more versatility in creating functions that what would be a "design pattern" in another language simply becomes a function in a functional language.
If you provide a (roughly) similar level of versatility in a language that has state, you can get the same effect. Just for example, most of the introduction to Modern C++ Design is defending the position that a design pattern can be encoded as a template (and most of the book is design patterns implemented as templates).
I think there will invariably be problems when you try to apply a single programming paradigm to a problem. That's why I like C++: it's multi-paradigm; it doesn't force you into a single set of solutions.
I am repeating a basic theory of mine, but models are just that - only models. The model defined by OOP is a very effective way to structure a program, and for many application programming domains, is entirely appropriate. For some problem spaces, the model may become decreasingly effective (or less efficient, or both).
A potential metaphore exists with physics. For many, many years Newtonian physics did (and in fact, still does) a remarkable job of modelling the laws of motion, time, and space (with some help from euclidian and sperical geometry). But when science began probing into the micro-and macro aspects of the problem space, Newtonian physics (AND euclidian/Spherical geometry) begin to break down. Hence we now have Relativity and quantumn mechanics. These do a fantastic job of modelling the universe at the macro and micro levels respectively, but are overly convoluted for use as descriptors of every-day, human-scale events.
OOP is very effective for application programming in a lot of cases, when considered in the context of the complexity involved with modelling real-world problems and human interactions for consumption and processing by a linear machine. As someone above observed, there are no silver bullets. And my impression (having never used C++) is that languages which attempt to be multi-paradigm also become more complex, and not necessarily as efficient for smaller problems more easily handled with a higher-level, more targeted language. Much like Quantumn mechanics and/or relativity theories (I mean, really, is anyone interested in the relationship between mass and velocity when travelling at 60 MPH on the freeway? OR the probability of Los angeles being where you expect it to be when you arrive?).
In my impression, adherence to qa specific model is important, so long as the model is suited to the problem space. At the point when this stops being true, the model may need to evolve, and there will be resistence to this. There will be attempts to force the problem space into a model not suited (review the history of physics again, or check into the evolution of the helio-centric model of the solar system, and include the key word "epicycles").
All of the above is simply MY best understanding of the state of things, and if I have missed the mark somewhere, I am happy to hear some contrary news.
Assume: Your DRY senses are infallible. Repeated behavior in your code reeks to you; it's nails upon the chalkboard.
Question: Does keeping DRY in the forefront of your mind guarantee that you will notice when you should be seeking a design pattern?
It seems from what introductions to design patterns I've seen has been working around supposedly "needing" to repeat code. Is this an OOP truth?
The possibly more easy question: Is there ever a time when dry will lead you away from OOP design patterns?
IMHO that depends on the specific pattern. If you have the GoF patterns in mind: lot's of them are aimed at "separation of concerns". By factoring out a specific concern like object creation (Factory pattern) or object cloning (Prototype pattern) you will bring that part of your code dealing with this concern to a central place, making the code more DRY.
Other GoF patterns like Flyweight or Proxy have a different nature, they are aimed at more efficiency or less complexity. Those patterns are mostly orthogonal to the DRY principle.
DRY and OOP are orthogonal. DRY should be practiced whether or not one is coding in a OO language. Keep in mind that DRY doesn't just apply to code.
As others noticed, DRY and OOP are orthogonal concepts. The ultimate proof that DRY doesn't lead you away from OOP design patterns is that you can apply DRY when using languages which incorporate (some of the) OOP design patterns in themselves.
Why thinking about DRY lead you away from OOP design patterns. Design patterns are there so that you do not repeat the mistakes other has done many times and come up with solutions for specific problem. So, no DRY does not lead you away from OOP design patterns.