Does the decorator pattern violate the SRP? - oop

I've heard a number of sources state that the decorator pattern violates the single responsibility principle. Me (being new to design patterns) am unsure how.
Does the decorator design pattern violate the single responsibility principle? And if so, how?
Cheers

No...
https://en.wikipedia.org/wiki/Decorator_pattern even states:
The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.
....So I'd be even more curious to see your 'sources'.
Speaking of... when asking a question like this, when you say "several sources" it should be a hint for you to list them and then do a little bit to compare and contrast them. This will help others to see the nuance of the question you are asking, or debunk it entirely... but either way to help you answer your question.

Related

Misunderstanding of a sentence in "UML Reference Manual" book (Booch, Rumbaugh, Jacobson)

Recently, i go back to read some parts of the "UML Reference Manual" book, second edition (obviously by: Booch, Rumbaugh, Jacobson).
(see: http://www.amazon.com/Unified-Modeling-Language-Reference-Manual/dp/020130998X)
Meanwhile, i have found these "strange" words in the first chapiter "UML overview" at "Complexity of UML" section:
There is far too much use of generalization at the expense of essential distinctions. The myth that inheritance is always good has been a curse of object orientation from earliest days.
I can't see how this sentence can be fully in line with Object Oriented Paradigm which states that inheritance is a fundamental principle.
Any idea/help please?
You seem to believe the two points are mutually exclusive. They are not. Inheritance is a fundamental and powerful principle of object-oriented programming, and it is overused.
It is overused typically by inexperienced developers who are so captivated with the idea of inheritance that they are more focused on the inheritance tree than solving the problem. They try to factor out as much code as possible to some parent base class so they can just reuse it throughout the tree, and as a result they have a brittle design.
One of the greatest evils of software engineering is tight coupling between classes. That's the sort of thing that causes you to have to work through the weekend after the customer asks for a simple change. Why? Because making a change in one class has an effect on another class, and fixing that class has an effect on another, and so on.
Well, there is no tighter coupling than inheritance.
When you factor too much out to the "top level," every derived class is coupled to it. And as you find more and more code you want to factor out to various levels, you eventually have these deep trees, and every change made at the top cascades throughout the tree. As a result, you start to have methods that return null or are empty. They're unnecessary for the class, but the inheritance contract demands they be there. This violates the Liskov Substitution Principle.
So use inheritance of course. But do it smartly. Favor delegation to inheritance if you have any doubt. And when you do use inheritance, make sure you aren't factoring commonalities to the top level (of the whole tree or a subtree) just to reuse common code, but rather do so because there is a commonality of behavior from top to bottom.
If your tree is more than two or three levels deep (and I think three is really pushing it), you are almost certainly setting yourself up for trouble.
Everything is good in moderation. Remember that the quote is not saying do not use it, or avoid, etc. Rather it is saying it is an overused principal when other OO abstractions or principals work better. Inheritance is powerful but it's coupling is tight.
Wisely or rather randomly the author of the UML book is saying pointing out this current truism that inheritance is often over-used and over-referenced. What about all the other principals and abstractions. I find that developers typically only hit the OO highlights (inheritance being one) and use that abstraction to excess.
For me in UML it is a good reminder that UML is OO generally, but it is not limited to Java or .Net OO features. Many languages only offer of the abstractions available across all languages. UML attempts to help you model and express many of them.
Remember the author only said 'too much use', not bad or incorrect. Also remember that maybe you are an expert developer who does not apply inheritance incorrectly.

Few words in this definition of Abstraction

I'm sorry if my question doesn't meet the standards of SO, but I really had some hard time going through the last few words within this definition of ABSTRACTION from Grady Booch
“An abstraction denotes the essential
characteristics of an object that distinguish it from all other kinds
of objects and thus provide crisply defined conceptual boundaries,
relative to the perspective of the viewer"
Please explain what does he mean by "relative to the perspective of the viewer". Any example would be really helpful.
They simply mean that from the point of view of the person trying to understand the abstraction, it should be clear what it is, what in includes and what it doesn't.
However, how is implemented might not be that clearly different from other abstractions.
For example:
A URI is a different abstraction from a Name. It's clear to a developer and a user what either are. However, implementation-wise they both might be little more than strings.
I think that what they are trying to say is that the semantics and the behaviors define abstractions correctly, not how they are going to be implemented.
Definitions in OOP world are different and not always very clear, for example, I can bring you a definition of abstraction from Tony Hoare:
"Abstraction arises from a recognition of similarities
between certain objects, situations, or processes in the real world,
and the decision to concentrate upon those similarities and to
ignore for the time being the differences."
Maybe this is clearer to you. However, I do not care too much about the words of these definitions.
What is important to understand about abstraction is that it has the function to expose to the user (or viewer) a set of behaviors (an interface) that completely describe and identify an entity (or object). Once you know these behaviors (methods) you can and should ignore the actual implementation of these methods. What the user should care is to provide input parameters and to receive the right results.
I think this is a more practical definition of abstraction.

OOP, class/objects overkill

What is a good gauge for knowing when a class is poorly designed or even necessary. In other words when to write a class and when no to.
SOLID might help if a class is poorly designed, but it won't help answer a question like "Is object-oriented programming the best approach for this problem?"
People have done a lot of very good work in programming for mathematics and science before object-oriented programming came into vogue. If your problem falls into those categories, perhaps object-oriented programming isn't for you.
Objects are state and behavior together; they tend to map onto problem domain objects one-to-one. If that's not true for your problem, perhaps object-oriented programming isn't for you.
If you don't know an object-oriented language well, perhaps object-oriented programming isn't for you.
If your organization doesn't know and can't support object-oriented solutions, perhaps object-oriented programming isn't for you.
A lot of people will say the "SOLID Principles" are a good guideline for class design.
There are a lot of articles/podcasts concerning the SOLID Principles, just do a quick search. Here's a good start:
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
rather than list a bunch of don't-do-this rules for recognizing a poorly-designed class, it is easier - and more efficient - to list the few rules governing a good class design:
a class is a collection of related state and behavior
the behavior should use only the state and method parameters
if you think about the state as a relation (i.e. as the columns in a relational database table), the object ID (pointer) is the primary (synthetic) key and the state comprises the non-key attributes. Is the object in third normal form? If not, split it into two or more objects.
is the lifecycle of the object complete? In other words, do you have enough methods to take the object from creation through use and finally to destruction/disposal? If not, what methods (or states/transitions) are missing?
is all of the state used by at least one method? If not, does it provide descriptive information useful to a user of the object? If the answer to both of these is no, then get rid of the extraneous state.
if the problem you're trying to solve requires no state, you don't need an object.
On top of the SOLID principles, have a look at Code Smells. They were mentioned first (IIRC) in Martin Fowler's "Refactoring" book, which is an excellent read.
Code smells generally apply to OO and also procedural development to some degree, including things like "Shotgun Surgery" where edits are required all over the codebase to change one small thing, or "Switch Case Smell" where giant switch cases control the flow of your app.
The best thing about Refactoring (book) is that it recommends ways to fix code smells and takes a pragmatic view about them - they are just like real smells - you can live with some of them, but not with others.

Design Principles [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
What principles do you generally follow when doing class design?
Principles Of Object Oriented Class Design (the "SOLID" principles)
SRP: The Single Responsibility
Principle A class should have one,
and only one, reason to change.
OCP: The Open Closed Principle You
should be able to extend a classes
behavior, without modifying it.
LSP: The Liskov Substitution
Principle Derived classes must be
substitutable for their base
classes.
ISP: The Interface Segregation
Principle Make fine grained
interfaces that are client specific.
DIP: The Dependency
Inversion Principle Depend on
abstractions, not on concretions.
Source: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Video (Uncle Bob): Clean Coding By Robert C. Martin ( Uncle Bob )
Don't forget the Law of Demeter.
The S.O.L.I.D. principles.
Or at least I try not to steer away too much from them.
The most fundamental design pattern should be KISS (keep it simple stupid)
Which means that sometimes not using classes for some elements at all it the right solution.
That and CRC(Class, Responsibility, Collaborators) cards (write the card down in your header files, not on actual cards that way they because easy to understand documentation too)
As mentioned above, some of the fundamental Object Oriented Design principles are OCP, LSP, DIP and ISP.
An excellent overview of these by Robert C. Martin (of Object Mentor) is available here: OOD Principles and Patterns
The "Resource Acquisition Is Initialization" paradigm is handy, particularly when writing in C++ and dealing with operating system resources (file handles, ports, etc.).
A key benefit of this approach is that an object, once created, is "complete" - there is no need for two-phase initialization and no possibility of partially-initialized objects.
loosely coupled, highly cohesive.
Composition over inheritance.
Domain Driven Design is generally a good principle to follow.
Basically I get away with programming to interfaces. I try to encapsulate that which changes through cases to avoid code duplication and to isolate code into managable (for my brain) chunks. Later, if I need, I can then refactor the code quite easily.
SOLID principles and Liskov's pattern, along with Single responsibility pattern.
A thing which I would like to add to all this is layering, Define layers in your application, the overall responsibility of a layer, they way two layers will interact. Only classes which have the same responsibility as that of the layer should be allowed in that layer. Doing this resolves a lot of chaos, ensures exceptions are handled appropriately, and it makes sure that new developers know where to place their code.
Another way to design is by designing your class to be configurable creating a mechanism where the configuration can be plugged in your class, rather than overriding methods in sub classes, identify what changes, see if that can be made configurable and ensures that this functionality is derived from configurations
I usually try to fit the class into one of the oo design patterns.

Is having a ubiquitous base object an anti pattern?

I remember seeing a debate about this somewhere, and am currently considering removing a base object that every business object, in a system I'm working on, inherits from. It contains a few properties, some database logic, and some constructor logic.
Is this an anti pattern, or is the jury still out? Would it be better to have a base contract to inherit from, which would require a certain amount of boilerplate coding to be done in each object?
EDIT: I do like dsimcha and feel it reflects very well on the issue, I am still happy to hear any further answers
The standard rule of thumb is to use inheritance only to provide flexibility for users of a class through polymorphism, and use composition if you want to reuse code from other classes. However, as long as you're not violating the Liskov Substitution Principle it's probably not too bad. Writing tons of boilerplate is inherently a bad thing, too, since it obscures the parts of your code where the real action is happening and is anti-DRY. If you are violating the Liskov Substitution Principle, though, then absolutely this is a bad idea.
I also would like to understand what problems I may encounter, or should be aware of
A potential problem is if you use multiple inheritance: your subclass then inherits two instances of the 'Eve' classes ... which is why C++ supports so-called virtual inheritance.
It's a frequently-used idiom: for example in .Net everything derives from System.Object ... and/or, all COM objects implement the IQueryInterface interface.
Nothing is an anti-pattern in a vacuum. Is your 'Eve class' causing you problems? What benefits do you expect to realize from removing it? Asking whether it's on some standard list of anti-patterns only helps if it aids in identifying actual issues.