-2

I´m looking for some kind of better compilation of principles which takes the old basic concepts (DRY, KISS, etc...) and applies them to OOP related concepts like abstract clasess, interfaces etc...


Some reasoning behind this quest:

I find some interpretations of the SOLID principles very compelling, but I've found so diverse interpretations of these principles on the web that I find them close to useless. The idea of a software design principle IMHO, is to provide a base framework for developers to discuss software development best practices. But when the advocators can't even agree on what their principles mean, it's time to look for alternatives.

I also have found that people trying to follow these principles create extremely over-modularized architectures mostly because they decompose simple implementations into even smaller modules, disperse over the project which makes it close to imposible to discern the purpose of these micro-modules in the context of the whole project.


Summarizing, I just want to know if there is any other well known name for a different group of OOP principles that are more tied to the old basic KISS, DRY, etc...


The question has been considered too broad by the community, so let's see how this goes for clarification:

Let A be a set of renown names of sets of OOP design principles (call them "High Level Principles"). I know SOLID to be an element of A. I found GRASP seems to be another element of A, which I found out thanks to a comment from user949300 on this question.

Let B be the set of the General Principles listed here which includes these and only these: ML, KISS, MIMC, DRY, GP and RoE. Let's call them "Low Level Principles"

Let's say that there is a function T that measures how much a High Level Principle from A is tied to the Low Level Principles from B (as a whole). Eg: T(e) = Tieness of e where e is an element from A.

I am asking if anyone can name any x such that T(x) >> T(SOLID). Where ">>" means "considerably higher than".

Such an an answer should explain how T(x) is being estimated. I understand the estimation of T will be highly subjective, but with a good explanation, subjective can be useful.

How can I tell if an answer is better than another answer? I'll consider the explanation and the number of new elements of A that is provided in the answer, but any answer mentioning at least an element from A different than "SOLID", and explaining how T(x) is higher for this element shall be considered as correct.

I hope that makes the question clear enough for the community...

closed as too broad by Greg Burghardt, Doc Brown, rwong, amon, gnat Jan 3 at 14:31

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    So what is your question? There are lots of principles besides SOLID (which is just a catchy name for five principles of software design out the multitudes of principles, patterns, guidelines and rules-of-thumbs). But there is probably not a single principles which is always correct and which nobody disagrees with. All the rules have limited applicability and can be misused. – JacquesB Jan 2 at 20:16
  • 4
    The issue is that there are no principles which apply all the time. People create over-engineered architecture in the name of SOLID principles due to blindly applying them. If you're looking for a general recipe which works all the time, I'm afraid there isn't one. Your best bet is to be critical of what you read, and gain practical experience of what works and what doesn't (and when!). – Vincent Savard Jan 2 at 20:17
  • 1
    Since that question would have been off-topic, we hoped that you could clarify it a little. – Vincent Savard Jan 2 at 20:30
  • 1
    "'when the advocators can't even agree on what their principles mean, it's time to look for alternatives" Ho ho, not so fast. First, your perception is not mine. Stick around here and you will learn there is little disagreement on SOLID in the SE community. Just the occasional misunderstanding. Do you have sources on this perceived disagreement? – Martin Maat Jan 2 at 20:51
  • 1
    @jacmkno: The number of software design principles is vast. Are you looking for a complete list - because that would be be book-length (at least!), or can you make your question more specific? – JacquesB Jan 2 at 20:55
4

Yes. It applies to all code.

Universal Principle: The only code that must be changed is code that is wrong.

You can act two ways on this:

  1. Don't get the code wrong to start with.
  2. Make it so that changing the code is easier.

Option 1

How do you not get the code wrong? So far as an industry we have tried:

  • Type systems
  • CASE and other high level diagramming tools
  • Business Analysts
  • Databases
  • New Languages
  • Static Analysis tools
  • Unit Testing
  • Use Cases/Stories/Epics/Conversations
  • Quality Assurance
  • Running three or more separately and differently coded versions of the same algorithm
  • BDD, DDD, TDD
  • Cross Functional Teams

To name a few...

Was it successful? No.

Was it a failure? No, we found and fixed a lot of issues.

So what really happened? We had to change a lot of code.

Sounds like option 2 would have been awfully useful! sheepish industry looks askance

Option 2

How do you make code easy to change? ... by at least not making it harder to change.

There are three sorts of code:

  • No Code
  • Understood Code
  • Legacy Code

No Code

Beautiful Verdant fields of blissful nothingness... Not really.

Before there is code, there already exist processes, people, resources, questions, curiosity, and all sorts of other stuff. Writing code is often proclaimed as the solution to the woes this stuff is already experiencing. All code does it make the woe happen faster. So before coding anything straighten up the mess.

Once the mess is straightened up, now comes the really hard part: resisting the urge to go and start writing something.

Why? Because any code you do write, necessarily makes it harder to change. So if you do write code, make sure it is code that absolutely must be written. Draft it, edit, re-edit, and so forth until the code reads well. Pass it to other developers for critical review.

Understood code

There are some problems that are so well understood that we have documented hundreds of precise ways to solve them. The Pythagorean Theorem is one such problem. Sorting is another.

These problems are so well understood that codifying them follows a very preset proscribed pattern. In these situations following that pattern makes the code very easy to read, and very easy to change. Attempting to elaborate them further, or be terser in their expression only hurts legibility, which makes it harder to change them.

Legacy Code

Legacy code is anything written be it in a text file, in a database, a picture, etc.. that if it were somehow missing that you could not write (or otherwise reproduce) completely in its entirety from memory with an accuracy of better than 99%.

Most software systems sit in the legacy area either because they are too large in terms of lines of code, too complicated in terms of the problems being solved, or too unknown in the sense that you the reader don't know how the system does actually do. By this definition a new or junior developer will even see known problems as legacy code.

Many people will tell you all sorts of ways to make the code easier to change. Not all of them will work on your code base, because at this size and scale no two code-bases are even remotely identical in what they are trying to solve or how they solve it. Otherwise we would either have a well known problem, or no code.

The problem is how do you define "easy to change"? Everyone will have a different opinion which is not useful. Also we are dealing with complex problems (otherwise they would already be solved and well understood) and simple problems are known to have multiple equally valid solutions (just look at sorting). So it just might be that there are several ways to write a program that is easy to change.

Kevlin Henney talks about this in a couple of lectures (easily located on YouTube) where he shows different approaches for writing software that generates the expected output for a game of FizzBuzz. It is interesting because each representation of the solution favours some sorts of change more easily than others.

This chases the idea that there is nothing more dangerous than having a single idea. With a single idea you cannot orientate yourself because it is a single point of reference.

The number of points needed to orientate yourself increases with the dimensionality of the space, 2D requires 2+, 3D requires 3+, etc... Its not just the number of points though, but the quality of the points. Each point needs to tell you something new that none of the other points contain, this new thing should be noticeably different, otherwise the point is useless for orientating (even though it might be a decent end solution).

Code has a very high dimensionality so you are going to need many points of reference to be somewhat sure that you have a good-enough orientation. Only then can you look at those points and make a decision as to what is better. You will know it is better because it outshines these other solutions.

OO Development

  • Focus less on it being Object Orientated. It is all code, the techniques are universal, if not always easy to implement.

  • You have a language, it provides you with a wealth of tools. Learn them.

  • Each tool has a place when and where it is useful, as it equally has places when and where it is useless, or even out-right dangerous.

  • Every tool is an implementation of some known problem domain. As there are many ways to solve problems, there are usually several tools that are implementations of that domain. Before picking one up, look at each in turn and contrast their strengths and weaknesses, perhaps solve the same simple problem that exercises the features you need with each tool, then decide.

  • Train yourself in other languages and other paradigms of programming. This will sharpen your skill at orientating in code space largely because it improves the quality of the points in code space you have knowledge of.

  • Don't throw out those general rules of thumb. They are general precisely because they represent problems that manifest regardless of you programming paradigm. Of course if you have out-grown them, great you have already internalised the wisdom they contain.

  • Find already existing software that solves similar problems. Read their code and study the patterns used (a.k.a. the well known solutions).

  • Make use of the techniques we as industry have discovered to not get code wrong to start with. Obviously mileage will vary for each code base.

3

I´m looking for some kind of better compilation of principles which takes the old basic concepts (DRY, KISS, etc...) and applies them to OOP related concepts like abstract clasess, interfaces etc...

What makes you think that DRY or KISS don't apply to OOP? Or functional programming? Or imperative programming?

The idea of a software design principle IMHO, is to provide a base framework for developers to discuss software development best practices.

And that's what SOLID does. They're best practices found from decades of software engineering projects of all sorts, not just OO.

But the problem with design at its core, not just software design is that there are inevitably competing desires. Nothing can be entirely easy to use, beautiful, inexpensive, modular, and powerful, etc, etc.

So when you're designing software, you're trying to balance all of these competing requirements. The SOLID principles are good practices because you'll usually benefit the most from favoring their guidelines over other ideas for which of those competing requirements to choose. But they are not rules. They are not a recipe that lead you to some mythical best design. It does not exist.

And they're focused almost entirely on code flexibility. Small interfaces are easier to change than large ones. A single responsibility is easier to change than many. Injected dependencies are easier to change than implicit ones. That makes sense - change is inevitable so preparing for it is valuable. But they don't talk about how easy the code is to read, or maintain. They don't talk about performance or scalability. Those competing design desires are there too. And if people blindly favor flexibility rules, they lose out on the rest.

That doesn't make them bad guidelines, because in the end flexibility and ease of change is pretty important too and the things they advocate for are invariably going to improve that (occasionally at the cost of other things).

  • "What makes you think that DRY or KISS don't apply to OOP?" I don't – jacmkno Jan 3 at 3:20
  • I believe SOLID has navigated too far away of these basic principles and I'm looking for alternatives. – jacmkno Jan 3 at 3:27
  • 4
    @jacmkno - why? because more people are aware of them, and the law of averages means that more people know them poorly? That doesn't change the impact of the guidelines on your code. – Telastyn Jan 3 at 4:40
0

Here is, I think, a great book that might be something like what you want. Object-Oriented Design Heuristics by Arthur J. Riel

One interesting thing the book points out is that OO heuristics sometimes contradict each other, but that's what you get with a complex topic. Context is important and there are few blanket sets of rules that cover all situations.

Not the answer you're looking for? Browse other questions tagged or ask your own question.