The Open-Closed Principle for Languages with Open Classes 127
We’ve been having a discussion inside Object Mentor World Design Headquarters about the meaning of the OCP for dynamic languages, like Ruby, with open classes.
For example, in Ruby it’s normal to define a class or module, e.g.,
# foo.rb
class Foo
def method1 *args
...
end
end
and later re-open the class and add (or redefine) methods,
# foo2.rb
class Foo
def method2 *args
...
end
end
Users of Foo
see all the methods, as if Foo
had one definition.
foo = Foo.new
foo.method1 :arg1, :arg2
foo.method2 :arg1, :arg2
Do open classes violate the Open-Closed Principle? Bertrand Meyer articulated OCP. Here is his definition1.
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
He elaborated on it here.
... This is the open-closed principle, which in my opinion is one of the central innovations of object technology: the ability to use a software component as it is, while retaining the possibility of adding to it later through inheritance. Unlike the records or structures of other approaches, a class of object technology is both closed and open: closed because we can start using it for other components (its clients); open because we can at any time add new properties without invalidating its existing clients.
Tell Less, Say More: The Power of Implicitness
So, if one client require
’s only foo.rb
and only uses method1
, that client doesn’t care what foo2.rb
does. However, if the client also require
’s foo2.rb
, perhaps indirectly through another require
, problems will ensue unless the client is unaffected by what foo2.rb
does. This looks a lot like the way “good” inheritance should behave.
So, the answer is no, we aren’t violating OCP, as long as we extend a re-opened class following the same rules we would use when inheriting from it.
If we use inheritance instead:
# foo.rb
class Foo
def method1 *args
...
end
end
...
class DerivedFoo < Foo
def method2 *args
...
end
end
...
foo = SubFoo.new # Instantiate different class...
foo.method1 :arg1, :arg2
foo.method2 :arg1, :arg2
One notable difference is that we have to instantiate a different class. This is an important difference. While you can often just use inheritance, and maybe you should prefer it, inheritance only works if you have full control over what types get instantiated and it’s easy to change which types you use. Of course, inheritance is also the best approach when you need all behavioral variants simulateneously, i.e., each variant in one or more objects.
Sometimes you want to affect the behavior of all instances transparently, without changing the types that are instantiated. A slightly better example, logging method calls, illustrates the point. Here we use the “famous” alias_method
in Ruby.
# foo.rb
class Foo
def method1 *args
...
end
end
# logging_foo.rb
class Foo
alias_method :old_method1, :method1
def method1 *args
p "Inside method1(#{args.inspect})"
old_method1 *args
end
end
...
foo = Foo.new
foo.method1 :arg1, :arg2
Foo.method1
behaves like a subclass override, with extended behavior that still obeys the Liskov-Substitution Principle (LSP).
So, I think the OCP can be reworded slightly.
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for source modification.
We should not re-open the original source, but adding functionality through a separate source file is okay.
Actually, I prefer a slightly different wording.
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for source and contract modification.
The extra and contract is redundant with LSP. I don’t think this kind of redundancy is necessarily bad. ;) The contract is the set of behavioral expectations between the “entity” and its client(s). Just as it is bad to break the contract with inheritance, it is also bad to break it through open classes.
OCP and LSP together are our most important design principles for effective organization of similar vs. variant behaviors. Inheritance is one way we do this. Open classes provide another way. Aspects provide a third way and are subject to the same design issues.
1 Meyer, Bertrand (1988). Object-Oriented Software Construction. Prentice Hall. ISBN 0136290493.
I wouldn’t say it’s normal in Ruby to define a class in foo.rb and then re-open it in foo2.rb later. It’s certainly possible, but it’s more common to re-open someone else’s class, such as String. If you own the class, then the normal thing to do is just edit the source, or if you want to adhere to OCP, then sub-class or decorate.
I’m still intrigued by the design implication of open classes. I agree that opening classes does not necessarily violate OCP. But contrary to Dave Hoover’s comment, I frequently want to reopen my own classes to avoid violating the ISP, Interface Segregation Principle.
For example, I have class Dog. One client of Dog uses it to bark(). Another client uses Dog to bite(). The barking client doesn’t care about biting and the biting client doesn’t care about barking. So in each client I’ll open the Dog class and add the desired behavior.
But I wonder…. is this bad design? Reading the code becomes more challenging since the behavior of Dog is in many locations.
“Object Mentor World Design Headquarters.”
WOOOAAAAHHH!!!
@Micah,
That’s an interesting spin on class definitions and would indeed be confusing. If we weren’t talking Ruby, I would suggest defining two different interfaces for the Dog class that your clients can use and leave the two methods in the same class definition – ILoudDog and IAggressiveDog.
I am impressed, too, with “World Design Headquarters”.
This creates the impression that there are several design locations around the world. It also suggests that there are other non-design locations, maybe a training headquarters, a development headquarters, a QA headquarters, etc.
Would not such divisions of software construction go against the Agile philosophy?
Good post! =) I would like to see more posts about Object Oriented Design inside the dynamic languages world, mainly the Ruby world.
I have a couple of problems with seeing OCP as a source level thing. The first is that if we do, OCP doesn’t really offer much guidance. In a language as dynamic as Ruby, you can replace anything you like without touching the original source. If the source of a class can always remain closed (i.e., it doesn’t have to change) we could legitimately say that dynamic languages give you OCP trivially so it’s probably not worth talking about OCP at all.
The second problem I have with seeing OCP as a source level thing is that open classes present problems of their own that, ideally, OCP should say something about. OCP adherence often triggers the creation of orthogonal abstractions: you split the class and then you know that mucking with one responsibility isn’t going to muck with the other. With open classes, you could easily make a change to a class in one file which accidentally clobbers functionality in another file. In a behavioral sense, the original file was never really closed then, was it? Other clients could be affected.
Languages which allow self-modifying code are a bit of a different animal than what Meyer was considering.
Concerning World Design Headquarters, I was of course inspired by the Daily Show ;)
@Hugo, thanks. I’m sure we can add more blogs on “dynamic design”!
Here’s another perspective; what we really care about is feature modularity. I’d like to be able to reason about how a feature behaves (for any appropriate definition of “feature”). Think about OOP for a second; we allow the definition of a class to be spread over several “physical artifacts”, i.e., a base class + mixins/interfaces + subclasses, sometimes in separate files. If I want to reason about the behavior of a
FileInputStream
, I have to look in several places, for example.I remember when OOP went viral. Lots of C programmers complained that they couldn’t figure out what their code was doing anymore, because the flow of control hoped around. With better tools (and drugs?) we got used to it.
The challenge of open classes is similar; we need modular reasoning over a set of artifacts. Tooling will help, so will programming conventions, practice, etc.
I agree to a point with Michael that I don’t think Meyer intended OCP to be just a source thing. It really is a statement of the power of extension through inheritance. He probably didn’t have open types in mind. (IIRC, Eiffel doesn’t support them.) That’s partly why I added the “contract” bit, so that our “non-local” extensions are done in a principled way.
One of the guiding principles of dynamic languages like Ruby is that there should be rules, but nearly always with escape hatches.
I think open classes (or at least some uses of them) are definitely violations of OCP, in the same way that #instance_variable_get violates encapsulation. That doesn’t mean it’s bad; it just means it’s worse than other alternatives.
Face it … it’s pretty hard to design a class that gets it exactly right with respect to OCP, and is extensible in all the right ways. And we have to work with classes that aren’t ideally designed. In the face of that, those escape hatches are invaluable.
The danger, of course, is that when designing classes we will just rely on the escape hatches and not try to design our classes for extension.
@Glenn I agree. I keep thinking that there’s a principle below all of this which is something like: Never write code that nullifies the behavior of existing code.
We should be able to understand the system from the sources. If we see a method, we should know that its behavior is there in the system, and although people may add to that behavior in various ways, they won’t nullify it through other code.
Ruby’s dynamic nature allows you to make the kind of changes you proposed (adding a method) without violating OCP. You can even modify the original source without violating OCP. Consider the basic Ruby class:
class Dog def bark; “woof!” end end
and its equivalent-ish Java class:
public class Dog { public String bark() { return “woof!”; } }
Now we add another method to Ruby.Dog:
class Dog def bark; “woof!” end def snarl; “gnashing of teeth” end end
and we go on with business as usual.
Now we add another method to Java.Dog:
public class Dog { public String bark() { return “woof!”; } public String snarl() { return “gnashing of teeth”; } }
and now we have to recompile every client of Dog.
To me, OCP is all about avoiding changes that screw up clients of a given class. You can really screw them up by changing the implementation in such a way that violates the original contract, or you can simply cause a nuisance by forcing them to be recompiled. In Ruby and other dynamic languages, you still have to think about the first part, but at least the second class of problems has gone away.
@PatMaddox: “and now we have to recompile every client of Dog.”
No we don’t. Try it.
@Glenn and @MichaelFeathers, agreed that “nullification” or “throw-a-curve-ball-ification” are no no’s.
One of the problems I’ve thought a lot about lately is how an “optimal” domain model is only optimal in a narrow context. In the large enterprises I work with, different subsystems and parts of the business need the same type to have different attributes and behaviors. It’s something of a lose-lose for the designer. If the type has the superset of stuff, that’s bad. If we have lots of variants of the type (with boilerplate copying back and forth), that’s bad for different reasons.
I want a way to keep a consistent, universal domain model, yet provide context-dependent extensions, even to shared instances. That and world peace….
By the way, the aspect-oriented programming community has wrestled a lot with ways to specify allowed extension points to a type without assuming anything (or much) about the actual extensions.
What happens if the class itself performs the extensions? For example, using some kind of rule (e.g. naming convention), it finds all of its extensions and “loads” them once and for all?
The class is closed – source not changing.
The opening up of the class is defined in one place (the class itself) but the extension of the class can be determined by the source code (to Feathers point).
I’ve got such an example I’m working with (a simple one sure).
About the only thing I’d want to add is that the extension point verifies that the other “openings” don’t step on each other.
come to have a look
You have to reverse the extensions back to default at that point. This avoids each command stepping over one another. Please correct if I’m wrong.
“Unlike the records or structures of other approaches, a class of object technology is both closed and open.”
What exactly does this mean?
i like your blog .i hope you are happy
come to have a look
the aspect-oriented programming community has wrestled a lot with ways to specify allowed extension points to a type without assuming anything (or much) about the actual extensions.
thank you for sharing with us
what it is making the site tick all without limiting content and effectiveness.I have spent some time to eventually stumble on your blog post about this topic. Great work.
I am impressed with all this useful information. Was WAY more than I expected.actualy you hold a few useful facts there in your article Greeting from chirurgie esthetiqe france
cheap VPS
tourism and other light industries. A number of projects in these fields are scheduled to undergo technical transformation during the Seventh Five-Year Plan period.
Interesting open closed object technology… I am surprised to see this information on your blog.. This is amazing blog… This is a technology that enables us to use the software components as it is,,, http://yourlistings.org
In OOP,i like Open/Closed Principal.The reason behind this is, that it allows software entities to be open for extensions, but they are close for moderation.The benefit is no alteration in the source code.Good post about it.Thanks for sharing it with all of us.
What exactly does this mean?
Good post,I think so! Dear Admin, I thank you for this informative article.
i like your blog .i hope you are happy
In my understanding, the principle is all about not allowing direct changes to code that has been put into production, and the way to achieve that while still permitting modifications to functionality is to use implementation inheritance. Garsoniere de Inchirat Bucuresti
Buy the cheap North Face online in The North Face Shop for free shopping and save 50~70% OFF. north face outlet , Northface shop.
This is the best way to get knowledge. I bookmarked this site for future assistance.
PowerPoint en PDF Convertisseur possède encore plusieurs fonctions, par exemple : fusionner des documents en un seul, ajouter des filigranes, adjuster la résolution ou la taille du fichier, protéger les documents PDF par mot de passe, etc et sa fonction de sécurité ne vous inquiète pas.En un mot, avec PowerPoint en PDF Convertisseur votre travail sera plus facile ! Télécharger gratuitement PowerPoint en PDF Convertisseur et expérimenter ce logiciel.
Interesting open closed object technology… I am surprised to see this information on your blg.. This is amazing blog… This is a technology that enables us to use the software components as it is,,, http://yourlistings.org
Nice post. I like visiting your website very often.
This looks a lot like the way “good” inheritance should behave.
We should not re-open the original source, but adding functionality through a separate source file is okay.
The tips above really work wonders. Iran
We, how can we to be a good programmer, we should study alll the time, never lose our heart, keep good habit, learn from other people. that’s it.
Your post will be rather good, and I’m sure some will find it interesting because it’s about a topic that’s as widely discussed as others. Some may even find it useful. I have learned a significant amount of useful information from your post. Thanks so much for your post. Keep sharing. Medical Technicians
Many thanks for making the truthful effort to explain this. I feel very strong about it and would like to read more. If you can, as you find out more in depth knowledge, would you mind posting more posts similar to this one with more information?
Do all we can to understand the program. and to be a good programmer.
it looks good, but how to do that.
Can you do a Ruby on Rails code sample too?
We are one of the Leading Insurance Agency In San Diego and California ,Our insurance services are health insurance, Kaiser health insurance, family insurance, group insurance, blue cross insurance, blue shield insurance, affordable health insurance in San Diego.please add my website into your blogger,it is very useful for us.
No wonder, with white iphone 4 in your hand will make you be the focus of the crowd! You won’t miss it!
With the right tool, you can easily burn mp4 to dvd and itunes to dvd. Also, you can use drm removal tool to remove drm protection from itunes, zune, amazon legally. wmv to dvd, mov to dvd, mp4 to dvd, itunes to dvd
I thank you for this informative article.
Risk almadan Sermayesiz Evinizden yönetebilece?iniz Kendi i?inizin sahibi olmak istermisiniz ?
In the third part of the test I’m shooting an object from a pretty close distance (15 cm). Here you can really see a big difference between the different cameras and if you compare the 3G with the white iPhone 4 side by side you can see that they are miles apart.
Can you do a Ruby on Rails code sample too? reseller business
Outsource services and solutions from oneoutsource. It provides best outsourcing services in india .
Wonderful blog! Do you have any tips and hints for aspiring writers? I’m hoping to start my own blog soon but I’m a little lost on everything. Would you propose starting with a free platform like Wordpress or go for a paid option? There are so many options out there that I’m totally confused .. Any ideas? Thanks a lot!
Good post! Thanks for this nice topic to read on.
OCP and LSP together are our most important design principles for effective organization of similar vs. variant behaviors.
nice blog
visit
lago di caldonazzo
vendita computer
Have to read a second time but seems interresting . JF
LV belt, LV belts, LV belts for men, LV Mens belts, louis vuitton mens wallets,gucci mens wallets,hermes mens wallets,prada mens wallets.
Hermes belt, Hermes belts, Hermes Mens belts, Hermes belts for men.
Men’s belts, LV men’s belts, Gucci men’s belts, Hermes men’s belts.
replica gucci belts, replica gucci belt, replica gucci belts for men, replica gucci mens belt.
replica gucci belts, replica belts, replica louis vuitton belts, replica hermes belts.
This is an important difference. While you can often just use inheritance, and maybe you should prefer it, inheritance only works if you have full control over what types get instantiated and it’s easy to change which types you use.
With the right tool, you can easily burn mp4 to dvd and itunes to dvd. Also, you can use drm removal tool to remove drm protection from itunes, zune, amazon legally. wmv to dvd, mov to dvd, convert mp4 to dvd, itunes to dvd
I think you should not let the Game class handle IO. this way, the (blocking) TakeTurn method will hide from the game board the means of implementation. it can use other objects to communicate with the user.
We should not re-open the original source, but adding functionality through a separate source file is okay.
I think you should not let the Game class handle IO. this way, the (blocking) TakeTurn method will hide from the game board the means of implementation. it can use other objects to communicate with the user.
11
13
During the 1990s, the Open/Closed Principle became popularly redefined to refer to the use of abstracted interfaces, where the implementations can be changed and multiple implementations could be created and polymorphically substituted for each other.
together are our most important design principles for effective organization of similar vs. variant behaviors.
important discussion up in here.
Those successfully completing the primary school teacher training course are equipped with advanced teaching methodologies. These teachers will be eligible to teach students in the preschool, kindergarten as well as in the primary classes.
Thanks for your post, very informative.
We are the professional coats manufacturer, coats supplier, coats factory, custom coats.
Designer Sunglasses with 3-day FREE SHIPPING
Thanks for this article.I like its.As to me it’s good job.
Hermes belt store offers high quality and cheap designer belts, please have a look.
Hermes belt store offers high quality and cheap designer belts, please have a look.
There are various kinds of Hermes belts available to match your needs.
great article, very useful information, thank you. Social Network
A bad beginning makes a bad ending. A bird in the hand is worth than two in the bush. A year’s plan starts with
spring. Bad news has wings. Better to ask the way than go astray. By reading we enrich the mind, by conversation we
polish it. Custom makes all things easy. He is not fit to command others that cannot command himself. He laughs best
who laughs last. tiffany and co outlet
it’s good job.
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
Strongly recommended for shopping at Hermes belts store.
Hermes belt store offers high quality and cheap designer belts, please have a look.
I love reading your article and I hope I can read more. Thanks :-)
Terrific blogs its very useful thanks :-)
I love reading your article and I hope I can read more. Thanks :-)
I love reading your article and I hope I can read more. Thanks :-)
Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with, Online UK costume and fashion jewellery shop with,
I attempted these beats by dr dre studio out in several genres thinking about which i listen to an eclectic mix Beats By Dr Dre. a washing cloth as well as the manual. Do not purchase any beats by dr dre solo purple products inside the internet unless you’re getting from an Authorized internet DealerBeats By Dre Just Solo. We are reliable provide good beats by dr dre pro black by reduced price.
where can i read more about Oriented Design inside the dynamic languages world, mainly the Ruby world.
What a wonderful article! And are doing well on the whole, but their work also has shortcomings.
thanks its nice great site and i have added in my favorites list
you have posted such a effectful article that it will certainly help me.
good post, i think so.Thank you!
Good Information Very nice post
This kind of post are always inspiring and i prefer to read this quality content.Its very Interesting open closed object technology… I am surprised to see this information on your blog.. This is amazing blog…thank u…
Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything about the different colors of gold
Very useful! I was actually looking for something like this. Very efficient! thank you!
I really like your article. Please keep on writing excellent posts. To find out more please go to http://baratasfutbolcamiseta.es/ http://baratasfutbolcamiseta.es/category.php?id=9 http://baratasfutbolcamiseta.es/goods.php?id=76 http://www.camisetas-de-futbol.es/ http://www.camisetas-de-futbol.es/category-66-b0-FIFA+del+Copa+del+Mundo.html http://www.camisetas-de-futbol.es/goods-4080-10+11+Holland+Tercel+Blanco+camiseta+del+futbol.html http://www.camisetasfutbolchina.es/ http://www.camisetasfutbolchina.es/category-122-b0-Real+Madrid.html http://www.camisetasfutbolchina.es/goods-4605-11+12+England+Titular+Blando+camiseta+del+futbol.html
hmm ,i’m not sure if this is what i’m looking for but anyway this is interresting and could be useful some day,thanks for taking time to write such cool stuff
Thank you for sharing them with us , I think it’s worth reading
When the western sky is especially clear, there is often a red sunset.
Slewing ring is also called slewing bearing, some people called: rotary support, swing support. English Name: slewing bearing or slewing ring bearing or turn table bearing, slewing ring in the real industrial applications is very wide.
Thank you for sharing, I’ll definitely dig deeper into it.
Good artical,I learn something!
Om canada goose jakke spørgsmål vedrørende fødevaresikkerhed, canada goose Gruppen af otte forventes canada goose outlet at lancere “Aquila fødevarer belstaff outlet security initiative”, vil være os $ 10-15 milliarderi belstaff støtte begået for landbrugs udvikling i fattigere Canada Goose Ungdom Freestyle lande.Med hensyn til finansforordningen forventes gruppen af otte ledere at være “Lecce rammen” Hot Salg på grundlag af vedtagelsen canada goose jakke af en politikfil, cross-domæne Canada Goose Banff Parka for at styrke tilsynet med banker, institutioner og virksomhedsledelse, og I am legend og har Hot Salg for nylig udgivet selvmord.I dag, efteråret Canada Goose Handsker på ny hylden, ikke kun mode, men vil holde dig tilsluttet på legender af læder.
Great article, I was just sitting in some outdoor chairs in my university and found this. Thank you! Just what I was looking for.
thank you once more! great job!
Take effect to save the file and you can retrieve them when necessary.
Good Information Very nice post
Good artical,I learn something!)) very cool!
Fantastic walk-through. I appreciate this post.Thanks
I will try to spread the word. Many of my twitter friends will love this.
Read many articles, but found your article very thoughtful, very unique insights
So, first, I would like to say thanks for your post. It is always necessary for us to have a copy of the text file to computer and keep it safe.
Very useful,thanks for sharing.
Thanks for theNice post, I’ve really enjoyed reading your articles. You obviously know what you are talking about!
The Open Close Principle states that the design and writing of the code should be done in a way that new functionality should be added with minimum changes in the existing code… The design should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged… medical billing maine
Thanks for the information, I’ll visit the site again to get update information Toys
interesting topic, i love your idea.
:) I would like to say thanks for your post. It is always necessary for us to have a copy of the text file to computer and keep it safe.
Read many articles, but found your article very thoughtful, very unique insights. convert swf to flv on mac os x
The Open-Closed Principle for Languages with Open Classes 124 good post78
The Open-Closed Principle for Languages with Open Classes 125 hoo,good article!!I like the post!83
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.