What is the Demeter mean in Law of Demeter?
why does it stands for Least Knowledge Principle as it's Greek goddess?
There was a project (in 1987) named "Demeter" at the Northeastern University in Boston. It concerned itself with a hardware description language named "Zeus", and that is how they came up with the name "Demeter" (Zeus' sister).
Within this project, the "Law of Demeter" was being coined.
(Source: Wikipedia.DE on Law of Demeter referring to http://www.bradapp.com/docs/demeter-intro.html)
Related
I have recently finished reading Clean Architecture book by Unckle Bob.
There he wrote
Three paradigms. Three constraints. Structured Programming imposes
discipline on direct transfer of control. Object Oriented Programming
imposes discipline on indirect transfer of control. Functional
programming imposes discipline upon assignment. Each of these
paradigms took something away. None of them added any new capability.
Each increased discipline and decreased capability.
What does indirect transfer of control mean?
How it is restricted in OOP?
What does indirect transfer of control mean?
Pointers to functions.
How it is restricted in OOP?
Polymorphism.
A more complete explanation can be found on the bottom of page 42.
The bottom line is that polymorphism is an application of pointers to functions. Programmers have been using pointers to functions to achieve polymorphic behavior since... the late 1940s.
The problem with explicitly using pointers to functions to create polymorphic behavior is that pointers to functions are dangerous. Such use is driven by a set of manual conventions. You have to remember to follow the convention...
OO languages eliminate these conventions and, therefore, these dangers. Using an OO language makes polymorphism trivial. That fact provides an enormous power... On this basis, we can conclude that OO imposes discipline on indirect transfer of control.
The discipline imposed in OO is that pointers to functions are accessed exclusively through polymorphism and never used explicitly.
Recently I heard that there are 9 rules for OOP(Java). I know only four as Abstraction, Polymorphism, Inheritance and Encapsulation. Are there any more rules for OOP?
Seems like what you're looking for are the Principles of Object-Oriented Design.
Summarized from Agile Software Development Principles, Patterns, and Practices. These principles are the hard-won product of decades of experience in software engineering. They are not the product of a single mind, but they represent the integration and writings of a large number of software developers and researchers. Although they are presented here as principles of object-oriented design, they are really special cases of long-standing principles of software engineering.
SRP The Single Responsibility Principle A class should have only one reason to change.
OCP The Open-Closed Principle Software entities (classes, packages, methods, etc.) should be open for extension, but closed for modification.
LSP The Liskov Substition Principle Subtypes must be substitutable for their base types.
DIP The Dependency Inversion Principle Abstractions should not depend upon details. Details should depend upons abstractions.
ISP The Interface Segregation Principle
Clients shold not be forced to depend upon methods that they do not use. Interfaces belong to clients, not to hierarchies.
REP The Release-Reuse Equivalency Principle
The granule of reuse is the granule of release.
CCP The Common Closure Principle
The classes in a package should be closed together against the same kinds of changes. A change that affects a closed package affects all the classes in that package and no other packages.
CRP The Common Reuse Principle
The classes in a package are reused together. If you reuse one of the classes in a package, you reuse them all.
ADP The Acylcic Dependencies Principle
Allow no cycles in the dependency graph.
SDP The Stable Dependencies Principle
Depend in the direction of stability.
SAP The Stable Abstractions Principle
A package should be as abstract as it is stable.
Not sure about any rules. All these mentioned things are more like OO paradigms to me. There are few advices we follow like,
Separation of Concern
Single Responsibility per Class
Prefer Composition over Inheritance
Programming to Interface
Plus all mentioned by Billybob, already
These OO principles are straight from Head First Design Patterns:
Encapsulate what Varies
Program to an Interface, rather than an Implementation
Favour Composition over Inheritance
A Class should have only one reason to Change (Single Responsibility Principle)
Sub-Types must be substitutable for their Base (Liskov Substitition Principle)
Classes shoule be Open for extension, but Closed for Modification (Open-Closed Principle)
These are concepts, not rules. There are no rules really, just decisions to make, some designs are better than others, some much better than others :-)
There are plenty of guidelines though :-) Some are language specific (C++ is riddled with them) others are OO specific. Too many to list though :-)
Off the top of my head, important ones are:
Loose coupling, high cohesion
Write testable classes, which you test
Use inheritence sparingly and only where it makes sense (prefer composition)
Try stick to the open/close principle.
(most important) KISS
Plenty to expand upon and add :-)
EDIT: I should add, the rules which you listed are not unique to OO
According to the Pragmatic Programmers - the rules are:
Keep it DRY (Don't Repeat Yourself)
Keep it SHY (Ensure that your classes have high cohesion and low coupling)
and tell the other GUY (Separation of concerns)
http://media.pragprog.com/articles/may_04_oo1.pdf
There are no "Rules" to OOP.
There are 4 language properties that make a language object-oriented or not (these are the things you listed in your question).
The rest of the material out there are guidelines. The best/most helpful guidelines I've read are GRASP
Many of the suggestions are not readily understandable by laymen (non-CS majors). I thought GRASP was pragmatic and approachable.
I think GRASP is nice because it suggests the most critical part of OO in its name - Assignment of Responsibility (to objects not programmers).
The two most critical GRASP concepts from which everything else derives are coupling and cohesion. These two concepts/principals drive all other patterns and approaches.
BTW - did I just interview you? You transcribed the question incorrectly...
There's some object-oriented engineering principle that states something along the lines of "a class should only know about the contracts of the classes that it takes as arguments, or any internal ones it uses."
The counter-example, in C++, is:
Foo::bar( Baz* baz)
{
baz()->blargh()->pants()->soil(); // this is bad, Foo knows about blarghs and pants
}
Does this principle have a name? Also, the actual principle rather than my paraphrase above would be nice to see.
The law of demeter thanks to Jim Burger says:
The Law of Demeter (LoD), or Principle of Least Knowledge, is a design guideline for developing software, particularly object-oriented programs. The guideline was invented at Northeastern University towards the end of 1987, and can be succinctly summarized as “Only talk to your immediate friends.” The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).
That may or may not compile (due to the parentheses after the baz pointer), but your example breaks at least one principle that I can think of. It breaks the Law of Demeter (also called the Law of Parsimony, I believe). The main principles can be found here:
S.O.L.I.D. Principles
Aside from these, I'm not sure if there is a specific name for what you're describing. You can look up the Law of Demeter on wikipedia.
Look at Robert Martin's SOLID principles. Specifically, look at the Single responsibility Principle. The complex chain of dependencies in your example looks like it breaks the SRP.
Encapsulation -- itself -- isn't a principle. It's part of achieving the various principles. Along with inheritance, polymorphism and other more obscure OO features.
I would say here that good encapsulation helps to reduce coupling - - which is a good goal for any decent encapsulation apart from the obvious.
The Law of Demeter indicates that you should only speak to objects that you know about directly. That is, do not perform method chaining to talk to other objects. When you do so, you are establishing improper linkages with the intermediary objects, inappropriately coupling your code to other code.
That's bad.
The solution would be for the class you do know about to essentially expose simple wrappers that delegate the responsibility to the object it has the relationship with.
That's good.
But, that seems to result in the class having low cohesion. No longer is it simply responsible for precisely what it does, but it also has the delegates that in a sense, making the code less cohesive by duplicating portions of the interface of its related object.
That's bad.
Does it really result in lowering cohesion? Is it the lesser of two evils?
Is this one of those gray areas of development, where you can debate where the line is, or are there strong, principled ways of making a decision of where to draw the line and what criteria you can use to make that decision?
Grady Booch in "Object Oriented Analysis and Design":
"The idea of cohesion also comes from structured design. Simply stated, cohesion
measures the degree of connectivity among the elements of a single module (and
for object-oriented design, a single class or object). The least desirable form of
cohesion is coincidental cohesion, in which entirely unrelated abstractions are
thrown into the same class or module. For example, consider a class comprising
the abstractions of dogs and spacecraft, whose behaviors are quite unrelated. The
most desirable form of cohesion is functional cohesion, in which the elements of
a class or module all work together to provide some well-bounded behavior.
Thus, the class Dog is functionally cohesive if its semantics embrace the behavior
of a dog, the whole dog, and nothing but the dog."
Subsitute Dog with Customer in the above and it might be a bit clearer. So the goal is really just to aim for functional cohesion and to move away from coincidental cohesion as much as possible. Depending on your abstractions, this may be simple or could require some refactoring.
Note cohesion applies just as much to a "module" than to a single class, ie a group of classes working together. So in this case the Customer and Order classes still have decent cohesion because they have this strong relationshhip, customers create orders, orders belong to customers.
Martin Fowler says he'd be more comfortable calling it the "Suggestion of Demeter" (see the article Mocks aren't stubs):
"Mockist testers do talk more about avoiding 'train wrecks' - method chains of style of getThis().getThat().getTheOther(). Avoiding method chains is also known as following the Law of Demeter. While method chains are a smell, the opposite problem of middle men objects bloated with forwarding methods is also a smell. (I've always felt I'd be more comfortable with the Law of Demeter if it were called the Suggestion of Demeter .)"
That sums up nicely where I'm coming from: it is perfectly acceptable and often necessary to have a lower level of cohesion than the strict adherence to the "law" might require. Avoid coincidental cohesion and aim for functional cohesion, but don't get hung up on tweaking where needed to fit in more naturally with your design abstraction.
If you are violating the Law of Demeter by having
int price = customer.getOrder().getPrice();
the solution is not to create a getOrderPrice() and transform the code into
int price = customer.getOrderPrice();
but instead to note that this is a code smell and make the relevant changes that hopefully both increase cohesion and lower coupling. Unfortunately there is no simple refactoring here that always applies, but you should probably apply tell don't ask
I think you may have misunderstood what cohesion means. A class that is implemented in terms of several other classes does not necessarily have low cohesion, as long as it represents a clear concept, and has a clear purpose. For example, you may have a class Person, which is implemented in terms of classes Date (for date of birth), Address, and Education (a list of schools the person went to). You may provide wrappers in Person for getting the year of birth, the last school the person went to, or the state where he lives, to avoid exposing the fact that Person is implemented in terms of those other classes. This would reduce coupling, but it would make Person no less cohesive.
It’s a grey area.
These principals are meant to help you in your work, if you find you’re working for them (i.e. they’re getting in your way and/or you find it over complicates your code) then you’re conforming too hard and you need to back off.
Make it work for you, don’t work for it.
I don't know if this actually lowers cohesion.
Aggregation/composition are all about a class utilising other classes to meet the contract it exposes through its public methods.
The class does not need to duplicate the interface of it's related objects. It's actually hiding any knwowledge about these aggregated classes from the method caller.
To obey the law of Demeter in the case of multiple levels of class dependency, you just need to apply aggregation/composition and good encapsulation at each level.
In other words each class has one or more dependencies on other classes, however these are only ever dependencies on the referenced class and not on any objects returned from properies/methods.
In the situations where there seems to be a tradeoff between coupling and cohesion, I'd probably ask myself "if somebody else had already written this logic, and I were looking for a bug in it, where would I look first?", and write the code that way.
What is the difference between Object-Oriented Modeling and Object-Oriented Programming? I overheard a conversation on my subway train this morning and it seems that these things are different. Aren't they?
Object-Oriented Modeling refers to the process where you are designing how the code will look like. You will use a modeling language like UML to do Object-Oriented Modeling. Object-Oriented Programming refers to a programming paradigm where you use objects. These objects have been designed during the desing phase using Object-Oriented Modeling techniques, and they are implemented during the construction (programming phase) using a language that supports Object-Oriented programming and based on the model.
Modeling is creating an abstraction of a problem, where as programming is the implementation of such an abstraction.
Modeling can be done in many ways: textual, formulas, diagrams... UML is one standard of modeling object oriented concepts.
Programming can be done in different ways too, depending on the tool, language etc. There are ways to generate the program right out of the modeling tool, typically out of UML models. This goes even a step further, where UML models are "executed" directly.
Other common confusions about object-oriented programming exist too - starting from "it's the thing where your drag and click", over hybrid 3rd generation concepts I refer to as "processing Objects" to practical patterns and ending with pure OOP.
I'd say the modeling precludes the programing, where the modeling is the physical design, before the programming is implemented.
http://en.wikipedia.org/wiki/Object-Oriented_Modeling
http://en.wikipedia.org/wiki/Object_oriented_programming
I just found this:
Object-oriented modeling is a formal
way of representing something in the
real world. It draws from traditional
set theory and classification theory.
object-oriented modeling is not
limited to computer-related elements.
One may use object-oriented modeling
to represent many different types of
things, from organizational
structures, to organic materials, to
physical buildings.
Object-Oriented Modeling is used to define, usually without any actual code, the classes, methods, and variables. There are many tools out there to help with such modelling. Netbeans is one such package. Netbeans can help you model your code and will even attempt to help you get started after you make your class diagrams.
I found this extraction is from the DTMF website about Key concepts of object oriented modeling.
Abstraction: DENotes the essential
characteristics of an object that
distinguish it from all other kinds of
objects and thus provide crisply
defined conceptual boundaries.
Example: A Cheesburger - is good to
eat and fun to cook.
Modularity: Decomposition of
abstractions into discrete units.
Example: The various "layers" of a
cheesburger - the bun, the lettuce,
the ketchup, the mayonnaise, the
burger, the cheese, onions, pickels,
etc.
Encapsulation: Process of
compartmentalizing the elements of an
abstraction that constitute its
structure and behavior; encapsulation
serves to separate the interface of an
abstraction and its implementation.
Example: • To cook the cheeseburger:
- Is the stove available? Are the burners working? Are the ingredients
available? • To eat the
cheeseburger: - Is it made correctly?
Is my plate clean or disgusting?
Hierarchy: A ranking or ordering of
abstractions. Example: A
cheeseburger is really a subclass of a
hamburger with cheese added which is a
sub class of sandwich which is a
subclass of the Hierarchal superclass
food.
Key Elements: Classes – A collection
of definitions of state, behavior,
and/or identity • Properties •
Methods
Objects: Instances of a class
Associations: Relationships •
Dependency • Identity •
Aggregation • Composition • And
others
Well, given that code is a means of communicating, object-oriented programming in an object-oriented programming language is a form of modelling.
One can however model at a more abstract level using modelling languages that are less expressive, but perhaps more useful for other purposes. For the purposes of developing software, modelling not relatively closely tied to programmes is mainly an exercise for a certain class of person who thinks it is terribly important, and is paid as if it were, but it is not.