Ok, so I know the obvious example of modification, that is when we need to modify an existing behaviour to add a new one. But, when we just need to add code that doesn't change anything but just add new functionality, does this count as modification or extension?
Instance:
When we have a Walking class representing the behaviour of a walking player and we want to add a Jumping class, but need to add methods in the Walking class to create the transition between that two behaviour (for declaring how it will go from Walking to Jumping).
Does this count as modification? I mean, we wrote code in the Walking class, but those code doesn't change anything of the existing behaviour of it (other methods doesn't need to be modified). Or this is an extension(then, by extension, the Open close principle aren't referring to the class class A extends B, but any functionality we add in a class)?
If the Walking class is public and clients are already using it, then any editing of that class is a modification. Extension would obviously include creating a subclass of Walking but also other techniques like object composition, that do not involve editing the class.
Note that the OCP does not prohibit all modifications. The OCP was originally defined by Bertrand Meyer, in Object-Oriented Software Construction. From page 60,
If you have control over the original software and can rewrite it so that it will address the needs of several kinds of client at no extra complication, you should do so.
You could interpret this piece of advice from the book as permission to modify the Walking class (without breaking clients). On the other hand, the fact that Jumping cannot be added without an edit to Walking seems to strongly indicate the design is not open for extension.
Related
I am quite confused with the Single Responsibility Principle. The Principle states that there should only be one reason for the class to change.
The problem which I am facing is, any change to a method or any logic change in doing things would change the class. For example, consider the following class:
class Person{
public void eat(){ };
public void walk(){ };
public void breathe(){ };
public void run(){ };
public void driveCar(Car car){ };
}
Uncle Bob describes it as there should ONLY be a single person/Actor responsible for the change. I have the following two questions:
For the above class who is the actor/Person who can be responsible for change?
Wouldn't any change in the logic of eating, breathing or walking change the class Person? So doesn't that mean that every method is a reason to change as it's logic to doing things might change?
What is a reason to change
For the above class who is the actor/Person who can be responsible for the change?
An Actor is a user (including clients, stakeholders, developers, organizations) or an external system. We can argue if people are systems, yet that is not here nor there.
See also: Use case.
Wouldn't any change in the logic of eating, breathing or walking change the class Person? So doesn't that mean that every method is a reason to change as its logic to doing things might change?
No, a method is not a reason to change. A method is something that can change... but why would it? What would trigger the developer to change it?
Part of the single responsibility principle is that code should interact at most with one external system. Remember that not all actors are external systems, however, some are. I think most people will find this part of the SRP easy to understand because interaction with an external system is something we can see in the code.
However, that is not enough. For example, if your code has to compute taxes, you can hardcode the tax rate in your code. That way, it is not interacting with any external system (it is just using a constant). However, one tax reform later, the government has been revealed as a reason to change your code.
Something you should be able to do is interchange external systems (perhaps with some additional coding effort). For example, changing from one database engine to another. However, we do not want one of these changes to translate into a total rewrite of the code. Changes should not propagate, and making a change should not break something else. To ensure that, we want all the code that deals with the database engine (in this example) to be isolated.
Things that change for the same reasons should be grouped together, things that change for different reasons should be separated.
-- Robert C Martin
We can do something similar with the government example above. We probably do not want the software reading the minute of the congress, instead, we can have it reading a configuration file. Now the external system is the file system, and there would be code to interact with it, and that code should not interact with anything else.
How do we identify those reasons to change?
Your code is defined by a set of requirements. Some are functional, others not. If any of those requirements change, your code has to change. A reason to change requirements is a reason to change your code.
Note: It is possible that you do not have all your requirement documented, however, an undocumented requirement is still a requirement.
Then, you need to know from where do those requirements come from. Who or what could change them? Those are your reasons for change. It could be a change in the politics of the company, it could be a feature we are adding, it could be a new law, it could be that we are migrating to a different database engine, or different operating system, translating to another language, adapting to another country, etc.
Some of those things are externals systems with which your code interacts (e.g. the database engine), some are not (the politics of the company).
What to do with responsibilities
You want to isolate them. So you will have code that interacts with the database, and nothing else. And you will have code that implements business rules, and nothing else. And so on.
Realize that even though the implementation of each part of your code will depend on something external, their interface does not have to. Thus, define interfaces and inject dependencies, so that you can change the implementation of each part without having to change the others… that is, the implementation of parts of your code should not be a reason to change the implementation of other parts of your code.
Note: No part of your code should have multiple responsibilities. Have parts of your code deal with each responsibility, and have part of your code with the responsibility of bringing other parts together. Similarly, if a part of your code has no responsibility… there is no reason to keep it. Thus, every part of your code should have exactly one responsibility.
For your code, ask yourself, what are the requirements of the Person class. are they complete? From where do they come from? Why would they change?
Recommended viewing
For a more authoritative explanation of the single responsibility principle, see Robert C Martin - The Single Responsibility Principle (51 minutes, 8 seconds, English language) at the Norwegian Developers Conference, 2015.
Interesting question. The quote from "Uncle Bob" Martin is:
A class should have one, and only one, reason to change.
One could interpret this as saying that your Person class has five reasons to change: you might want to change the eat method, or change the walk method, or the breathe method, or the run method, or the driveTheCar method. But this is too narrow, and doesn't really capture what Martin meant by a "reason to change".
A reason to change a class means a human programmer's motivation for changing it. You would not change the eat method simply because you were motivated to change the eat method; you would change it to achieve some goal regarding a desired behaviour of your program.
If the Person class models a person for some sort of simulation, then your motivation for changing it would be that you want "to change how people's actions are modelled in the simulation". Every change you make to the class would be motivated by that reason, whether you changed one method or more than one; so the Person class has only one "reason" to change, fulfilling the SRP.
If the Person class had some other methods such as for drawing the person on the screen, then you might also want "to change the graphical appearance of your simulated people". This would be a completely different motivation than the motivation to change the way your simulation models people's actions, so the class would have two responsibilities, violating SRP.
I was looking into the Single Responsibility Principle(SRP) and Open Closed Principle(OCP).
SRP states that a class must have only one reason to change.
OCP states that the class must be closed for modification but open to extension.
I find that to be contradicting. One principle states that the class must be simple enough, that you change for a single reason but the other principle states that a class must not be changed but only extended.
Does anyone have a better explanation?
The Single Responsipbiliy Principle deals with the fact that if a class has multiple responsibilities, these responsibilities will be tightly coupled if they're in a single class.
So if an interface or algorithm changes for one responsibility it will likely also effect the other responsibility, an undesired effect.
In the Open/Closed Principle a class should be able to extend its behaviour without the need to modify the class itself. The only need to modify the class should be because it has a bug/error in it, not because you would like to change or add functionality.
For example (OCP): a class that holds a list of hard-coded types of objects is not open for extension, because if you would to add a new type to the list, you would need to modify the class. Instead a better design is when the class has an add or remove functionality, or an interface which you can implement to hold different types per subclass.
Lets represent all the responsibilities and reasons for change as a 2D cicrle.
SRP -> asks us to chip at the edges (haha) of that circle so that what is left is very tightly coupled, and if it will change it will change all at the same time.
OCP -> asks us to poke holes in that circle, so that those parts that will change at different pace can be provided at a latter date.
In other words SRP compliant class may fail OCP and OCP compliant class can fail SRP. There is also significant overlay between the two, but my presentation also shows that there will be differences too.
I use the Scanner class for reading multiple similar files. I would like to extend it to make sure they all use the same delimiter and I can also add methods like skipUntilYouFind(String thisHere) that all valid for them all.
I can make a utility-class that contain them, or embed the Scanner Class as a variable inside another class but this is more cumbersome.
I have found some reasons to declare a class final, but why is it done here?
Probably because extending it and overwriting some of it's methods would probably break it. And making it easier to overwrite methods would expose to much of the inner workings, so if in the future they decide to change those (for performance or some other reasons), it would be harder for them to change the class without breaking all the classes that extend it.
For example, consider the following method in the class:
public boolean nextBoolean() {
clearCaches();
return Boolean.parseBoolean(next(boolPattern()));
}
Say you want to overwrite this because you want to make 'awesome' evaluate to a 'true' boolean (for whatever reason). If you overwrite it, you can't call super.nextBoolean(), since that would consume the next token using the default logic. But if you don't call super.nextBoolean(), clearCaches() won't be called, possibly breaking the other not overwritten methods. You can't call clearCaches() because it's private. If they made it protected, but then realized that it's causing a performance problem, and wanted a new implementation that doesn't clear caches anymore, then they might break your overwritten implementation which would still be calling that.
So basically it's so they can easily change the hidden parts inside the class, which are quite complex, and protecting you from making a broken child class (or a class that could be easily be broken).
I suppose it is due to security reasons. This class reads user input, so that someone with bad intentions could extend it, modify it's behavior and you'd be screwed. If it is final, it is not that easy for the bad guy, because if he makes his own type of Scanner (not java.util.Scanner), the principles of Polymorphism would be broken. See the bad guy can be smart enough to write a bot/script which does this automatically on remote servers... He can even do it by dynamic classloading in compiled application.
I think that the link you provided explains it all.
In your case it seems like you should prefer composition instead of inheritance anyway. You are creating a utility that has some predefined behavior, and that can hide some (or all) of the details of the Scanner class.
I've seen many implementations that used inheritance in order to change a behavior. The end result was usually a monolithic design, and in some cases, a broken contract, and/or broken behavior.
Why would anyone want to mark a class as final or sealed?
According to Wikipedia, "Sealed classes are primarily used to prevent derivation. They add another level of strictness during compile-time, improve memory usage, and trigger certain optimizations that improve run-time efficiency."
Also, from Patrick Smacchia's blog:
Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)
Those are all pretty good reasons - I actually wasn't aware of the performance benefit implications until I looked it up just now :)
The versioning and security points seem like a huge benefit in terms of code confidence, which is very well justified on any kind of large project. It's no drop-in for unit testing, of course, but it would help.
Because creating a type for inheritance is much harder work than most folks think. It is best to mark all types this way by default as this will prevent others from inheriting from a type that was never intended to be extended.
Whether or not a type should be extended is a decision of the developer who created it, not the developer who comes along later and wants to extend it.
Joshua Bloch in his book Effective Java talks about it. He says "document for inheritance or disallow it".
The point is that class is sort of a contract between author and client. Allowing client to inherit from base class makes this contract much more strict. If you are going to inherit from it, you most likely are going to override some methods, otherwise you can replace inheritance with composition. Which methods are allowed to be overridden, and what you have to do implementing them - should be documented, or your code can lead to unpredictable results. As far as I remember, he shows such example - here is a collection class with methods
public interface Collection<E> extends Iterable<E> {
...
boolean add(E e);
boolean addAll(Collection<? extends E> c);
...
}
There is some implementation, i.e. ArrayList. Now you want to inherit from it and override some methods, so it prints to console a message when element is added. Now, do you need to override both add and addAll, or only add? It depends on how addAll is implemented - does it work with internal state directly (as ArrayList does) or calls add (as AbstractCollection does). Or may be there is addInternal, which is called by both add and addAll. There were no such questions until you decided to inherit from this class. If you just use it - it does not bother you. So the author of the class has to document it, if he wants you to inherit from his class.
And what if he wants to change the implementation in the future? If his class is only used, never inherited from, nothing stops him from changing implementation to more efficient. Now, if you inherited from that class, looked at source and found that addAll calls add, you override only add. Later author changes implementation so addAll no longer calls add - your program is broken, message is not printed when addAll is called. Or you looked at source and found that addAll does not call add, so you override add and addAll. Now author changes implementation, so addAll calls add - your program is broken again, when addAll is called message is printed twice for each element.
So - if you want your class to be inherited from, you need to document how. If you think that you may need to change something in the future that may break some subclasses - you need to think how to avoid it. By letting your clients inherit from your class you expose much more of internal implementation details that you do when you just let them use your class - you expose internal workflow, that is often subject to changes in future versions.
If you expose some details and clients rely on them - you no longer can change them. If it is ok with you, or you documented what can and what can not be overriden - that's fine. Sometimes you just don't want it. Sometimes you just want to say - "just use this class, never inherit from it, because I want a freedom to change internal implementation details".
So basically comment "Because the class doesn't want to have any children and we should respect it's wishes" is correct.
So, someone wants to mark a class as final/sealed, when he thinks that possible implementation details changes are more valuable than inheritance. There are other ways to achieve results similar to inheritance.
What can be reasons to prevent a class from being inherited? (e.g. using sealed on a c# class)
Right now I can't think of any.
Because writing classes to be substitutably extended is damn hard and requires you to make accurate predictions of how future users will want to extend what you've written.
Sealing your class forces them to use composition, which is much more robust.
How about if you are not sure about the interface yet and don't want any other code depending on the present interface? [That's off the top of my head, but I'd be interested in other reasons as well!]
Edit:
A bit of googling gave the following:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx
Quoting:
There are three reasons why a sealed class is better than an unsealed class:
Versioning: When a class is originally sealed, it can change to unsealed in the future without breaking compatibility. (…)
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
Security and Predictability: A class must protect its own state and not allow itself to ever become corrupted. When a class is unsealed, a derived class can access and manipulate the base class’s state if any data fields or methods that internally manipulate fields are accessible and not private.(…)
I want to give you this message from "Code Complete":
Inheritance - subclasses - tends to
work against the primary technical
imperative you have as a programmer,
which is to manage complexity.For the sake of controlling complexity, you should maintain a heavy bias against inheritance.
The only legitimate use of inheritance is to define a particular case of a base class like, for example, when inherit from Shape to derive Circle. To check this look at the relation in opposite direction: is a Shape a generalization of Circle? If the answer is yes then it is ok to use inheritance.
So if you have a class for which there can not be any particular cases that specialize its behavior it should be sealed.
Also due to LSP (Liskov Substitution Principle) one can use derived class where base class is expected and this is actually imposes the greatest impact from use of inheritance: code using base class may be given an inherited class and it still has to work as expected. In order to protect external code when there is no obvious need for subclasses you seal the class and its clients can rely that its behavior will not be changed. Otherwise external code needs to be explicitly designed to expect possible changes in behavior in subclasses.
A more concrete example would be Singleton pattern. You need to seal singleton to ensure one can not break the "singletonness".
This may not apply to your code, but a lot of classes within the .NET framework are sealed purposely so that no one tries to create a sub-class.
There are certain situations where the internals are complex and require certain things to be controlled very specifically so the designer decided no one should inherit the class so that no one accidentally breaks functionality by using something in the wrong way.
#jjnguy
Another user may want to re-use your code by sub-classing your class. I don't see a reason to stop this.
If they want to use the functionality of my class they can achieve that with containment, and they will have much less brittle code as a result.
Composition seems to be often overlooked; all too often people want to jump on the inheritance bandwagon. They should not! Substitutability is difficult. Default to composition; you'll thank me in the long run.
I am in agreement with jjnguy... I think the reasons to seal a class are few and far between. Quite the contrary, I have been in the situation more than once where I want to extend a class, but couldn't because it was sealed.
As a perfect example, I was recently creating a small package (Java, not C#, but same principles) to wrap functionality around the memcached tool. I wanted an interface so in tests I could mock away the memcached client API I was using, and also so we could switch clients if the need arose (there are 2 clients listed on the memcached homepage). Additionally, I wanted to have the opportunity to replace the functionality altogether if the need or desire arose (such as if the memcached servers are down for some reason, we could potentially hot swap with a local cache implementation instead).
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
That said, I think there are potential times when you might want to make a class sealed... and the best thing I can think of is an API that you will invoke directly, but allow clients to implement. For example, a game where you can program against the game... if your classes were not sealed, then the players who are adding features could potentially exploit the API to their advantage. This is a very narrow case though, and I think any time you have full control over the codebase, there really is little if any reason to make a class sealed.
This is one reason I really like the Ruby programming language... even the core classes are open, not just to extend but to ADD AND CHANGE functionality dynamically, TO THE CLASS ITSELF! It's called monkeypatching and can be a nightmare if abused, but it's damn fun to play with!
From an object-oriented perspective, sealing a class clearly documents the author's intent without the need for comments. When I seal a class I am trying to say that this class was designed to encapsulate some specific piece of knowledge or some specific service. It was not meant to be enhanced or subclassed further.
This goes well with the Template Method design pattern. I have an interface that says "I perform this service." I then have a class that implements that interface. But, what if performing that service relies on context that the base class doesn't know about (and shouldn't know about)? What happens is that the base class provides virtual methods, which are either protected or private, and these virtual methods are the hooks for subclasses to provide the piece of information or action that the base class does not know and cannot know. Meanwhile, the base class can contain code that is common for all the child classes. These subclasses would be sealed because they are meant to accomplish that one and only one concrete implementation of the service.
Can you make the argument that these subclasses should be further subclassed to enhance them? I would say no because if that subclass couldn't get the job done in the first place then it should never have derived from the base class. If you don't like it then you have the original interface, go write your own implementation class.
Sealing these subclasses also discourages deep levels of inheritence, which works well for GUI frameworks but works poorly for business logic layers.
Because you always want to be handed a reference to the class and not to a derived one for various reasons:
i. invariants that you have in some other part of your code
ii. security
etc
Also, because it's a safe bet with regards to backward compatibility - you'll never be able to close that class for inheritance if it's release unsealed.
Or maybe you didn't have enough time to test the interface that the class exposes to be sure that you can allow others to inherit from it.
Or maybe there's no point (that you see now) in having a subclass.
Or you don't want bug reports when people try to subclass and don't manage to get all the nitty-gritty details - cut support costs.
Sometimes your class interface just isn't meant to be inheirited. The public interface just isn't virtual and while someone could override the functionality that's in place it would just be wrong. Yes in general they shouldn't override the public interface, but you can insure that they don't by making the class non-inheritable.
The example I can think of right now are customized contained classes with deep clones in .Net. If you inherit from them you lose the deep clone ability.[I'm kind of fuzzy on this example, it's been a while since I worked with IClonable] If you have a true singelton class, you probably don't want inherited forms of it around, and a data persistence layer is not normally place you want a lot of inheritance.
Not everything that's important in a class is asserted easily in code. There can be semantics and relationships present that are easily broken by inheriting and overriding methods. Overriding one method at a time is an easy way to do this. You design a class/object as a single meaningful entity and then someone comes along and thinks if a method or two were 'better' it would do no harm. That may or may not be true. Maybe you can correctly separate all methods between private and not private or virtual and not virtual but that still may not be enough. Demanding inheritance of all classes also puts a huge additional burden on the original developer to foresee all the ways an inheriting class could screw things up.
I don't know of a perfect solution. I'm sympathetic to preventing inheritance but that's also a problem because it hinders unit testing.
I exposed a minimal interface to interact with the client API, and it would have been awesome to extend the client API class and then just add an implements clause with my new interface. The methods that I had in the interface that matched the actual interface would then need no further details and so I wouldn't have to explicitly implement them. However, the class was sealed, so I had to instead proxy calls to an internal reference to this class. The result: more work and a lot more code for no real good reason.
Well, there is a reason: your code is now somewhat insulated from changes to the memcached interface.
Performance: (…) if the JIT compiler sees a call to a virtual method using a sealed types, the JIT compiler can produce more efficient code by calling the method non-virtually.(…)
That's a great reason indeed. Thus, for performance-critical classes, sealed and friends make sense.
All the other reasons I've seen mentioned so far boil down to "nobody touches my class!". If you're worried someone might misunderstand its internals, you did a poor job documenting it. You can't possibly know that there's nothing useful to add to your class, or that you already know every imaginable use case for it. Even if you're right and the other developer shouldn't have used your class to solve their problem, using a keyword isn't a great way of preventing such a mistake. Documentation is. If they ignore the documentation, their loss.
Most of answers (when abstracted) state that sealed/finalized classes are tool to protect other programmers against potential mistakes. There is a blurry line between meaningful protection and pointless restriction. But as long as programmer is the one who is expected to understand the program, I see no hardly any reasons to restrict him from reusing parts of a class. Most of you talk about classes. But it's all about objects!
In his first post, DrPizza claims that designing inheritable class means anticipating possible extensions. Do I get it right that you think that class should be inheritable only if it's likely to be extended well? Looks as if you were used to design software from the most abstract classes. Allow me a brief explanation of how do I think when designing:
Starting from the very concrete objects, I find characteristics and [thus] functionality that they have in common and I abstract it to superclass of those particular objects. This is a way to reduce code duplicity.
Unless developing some specific product such as a framework, I should care about my code, not others (virtual) code. The fact that others might find it useful to reuse my code is a nice bonus, not my primary goal. If they decide to do so, it's their responsibility to ensure validity of extensions. This applies team-wide. Up-front design is crucial to productivity.
Getting back to my idea: Your objects should primarily serve your purposes, not some possible shoulda/woulda/coulda functionality of their subtypes. Your goal is to solve given problem. Object oriented languages uses fact that many problems (or more likely their subproblems) are similar and therefore existing code can be used to accelerate further development.
Sealing a class forces people who could possibly take advantage of existing code WITHOUT ACTUALLY MODIFYING YOUR PRODUCT to reinvent the wheel. (This is a crucial idea of my thesis: Inheriting a class doesn't modify it! Which seems quite pedestrian and obvious, but it's being commonly ignored).
People are often scared that their "open" classes will be twisted to something that can not substitute its ascendants. So what? Why should you care? No tool can prevent bad programmer from creating bad software!
I'm not trying to denote inheritable classes as the ultimately correct way of designing, consider this more like an explanation of my inclination to inheritable classes. That's the beauty of programming - virtually infinite set of correct solutions, each with its own cons and pros. Your comments and arguments are welcome.
And finally, my answer to the original question: I'd finalize a class to let others know that I consider the class a leaf of the hierarchical class tree and I see absolutely no possibility that it could become a parent node. (And if anyone thinks that it actually could, then either I was wrong or they don't get me).