Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
In java, If we are using an enum and eventually we want to add/remove an attribute to/from that enum, hence its usages, we are violating open/closed principle in solid principles.
If so, what is the better usage of enums?
The answer is no as OCP doesn't apply (and cannot apply) to Enums. Enums should be complete (contain all possible values) and static (static = final, non-mutable). You can see them as a small, finite set of Value Objects.
If you want something that can be extended, you can always use a class or build your own "type-safe enumeration" that can be extended.
About the language. I choose to use the term apply rather than violate, as principles, as many good practices, have a context where it makes sense to apply them. A violation (for me) means that a situation calls to use a principle, but it's not used or it's not implemented properly. It doesn't apply means what it says on the tin, that the principle brings no use in the current context or that it cannot be applied, as otherwise would go against other principles which have stronger forces ... in the context :).
Edit
Another reason why I think Enums don't violate OCP (now I use the word violate :D), is because OCP doesn't mean that all of the classes and methods can be extended, but rather that a conscientious developer makes informed decisions about where to put those extension points. In the case of an Enum a developer understands that there's no need to extend the possible values and further that it would be damaging to add new values, as existing code wouldn't know what to do with the new value. So he/she decides to completely close the class and not provide extension points. The same applies to any other class that is final. A final class doesn't violate OCP, but rather (or ideally) a developer made a decision of not allowing to extend it.
This is similar to what I mentioned before, that Enums are like a small, finite set of Value Objects. VOs are immutable and closed, and as such they don't violate OCP.
And to add something more, I've seen some libraries not implementing OCP correctly (Tapestry 5) and making more than needed final, which made them a PITA to use. Or just not closing anything, which made some devs make mistakes because they didn't understand the finer details of the library, and messed up the invariants.
The answer is yes. All Java enums violate the Open/Closed Principle, because they cannot be extended without modification.
The "better usage of enums" in Java is to have them implement an interface, and have clients depend on that interface rather than the enum implementation, because the interface does not violate the Open/Closed Principle.
Don't jump to the conclusion that if enums violate the OCP, then we shouldn't be allowed to use them. I want to clarify this answer with a reminder that the OCP, by definition, applies only to client-facing code, i.e. code that is public/exposed. The OCP is not a restriction on implementation details.
A module is said to be closed if it is available for use by other modules... At the implementation level, closure for a module also implies that you may compile it, perhaps store it in a library, and make it available for others (its clients) to use.
--Bertrand Meyer, Object-Oriented Software Construction 2nd ed. page 57
So, utilizing enums as part of an application's internal API avoids the OCP altogether. It is only as part of the external API where enums should be abstracted through an interface.
Consider that since an enum is a concrete implementation, exposing it only though an interface serves as much to satisfy the Dependency Inversion Principle as it does the OCP. Even if you believe that directly exposing enums somehow sidesteps the OCP, it still creates a concrete dependency, which violates the DIP.
Also consider the comment from #MarkRotteveel, "Open/closed is a principle, not a dogma that needs to be followed at all times."
Open/Closed as well as all SOLID principles were designed to make easy refactor and understand the code. You should use it based on the context.
As long as Enum Types must be a a well-known set of values, you shouldn't write something like this:
enum Fruits {apple, pear, banana}
enum Food extends Fruits {chicken}
For three reasons:
1) Java doesn't allow it.
2) By no means a chicken is a Fruit
3) Fruit is no more a well-known and complete set of values
If you use Enum to define, for example, the planets of the Solar System and a new planet is discovered or an old one loses its status (or is destroyed by aliens) it's Ok to modify your class to adjust the new requirements.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've seen some legacy code that uses lengthproperty on some objects and others that uses length() method. Currently I'm working with a NodeList from the org.w3c.dom package and I found that it have the getLength() method to get the numbers of elements.
My Question is how as Java developer I can know how to determine when to use length, length(), size(), getLength()? obviously it depends of the object type and the API is there for read... but the point is how the Java Development select which of that implements in their classes.
Note: In the Question When to use .length vs .length() Makoto answer's indicates that .length is a property on arrays. That isn't a method call, and length() is a method call on String. But, why is the reason? why not use ever a method or ever a property for maintain the consistency around all the API.
how would Java developers select which of [the methods] to implement in their classes?
When you implement classes that contain other objects, it's almost always going to be size(), the method provided by theCollection interface.
As far as other choices go, you should avoid exposing member variables, even final ones, because they cannot be accessed through an interface. Java gets away with it for arrays because of some JVM trickery, but you cannot do the same. Hence, length should be out: it remains in Java because it's not possible to change something that fundamental that has been in the language from day one, but it's definitely not something one should consider when designing new classes.
When you implement your own type that has length (say, a rectangle or a line segment) you should prefer getLength() to length() because of Java Beans naming conventions.
obviously it depends of the object type and the API is there for read...
You already have answered your question yourself: look in the API documentation of whatever class you are using.
but the point is how the Java Development select which of that implements in their classes.
The classes in Java's standard library have been developed over a long period of time by different people, which do not always make the same choice for the name of methods, so there are inconsistencies and unfortunately you'll just have to live with that.
There is no clear rule, otherwise we wouldn't see such a mixup in the jdk itself. But here are some things to consider when making such a design decision.
Don't worry to much. It is a minor thing and won't make to much of a difference. So when you think longer then 5 minutes about this, you are probably wasting money already.
Use getters when a frameworks need them. Many frameworks depend on the getter style. If you need or want such frameworks to work nicely with your class it might be beneficial to use that style.
Shorter is better. the 'get' part doesn't increase clarity. It just generates to characters of noise to the source code, so if you don't need it for some reason, don't use it.
Methods are easier to evolve. Length is often a quantity that is not set directly but somehow computed. If you hide that behind a method it gives you the flexibility to change that implementation later on, without changing the API.
Direct field accesses should be a tiny bit faster, but if you aren't working on high volume online trading or something, the difference isn't even worth thinking about. And if you do you should do your own measurements before making a decision. The hotspot compiler will almost for sure inline the method call anyways.
So if there aren't any external forces driving you in a different direction I would go with 'length()'
According to OOPS principles, length should be attribute and getLength() should be method. Also length attribute should be encapsulated should be exposed through methods, so getLength() sounds more appropriate.
Unfortunately not all Java library classes follow standards. There are some exceptions and this is one among them.
In a pure OO language it should be probably always a method like length(). So in a class hierarchy you can override the attribute length.
But Java is not pure OO. And the main reason for fields (.length) vs method (length()) is/was performance issues.
And even Sun/Oracle programmers did some bad class design.
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 8 years ago.
Improve this question
I have been studying a bit of Java and C++ more or less at the same time and I noticed that Java has a more friendly and intuitive way of interpreting the OOP than the C++ way.
Yes, Java is completely OO and, on the other hand, C++ supports many paradigms, but this doesn't mean that C++ couldn't improve its way of implementing the OO paradigm.
C++ supports multiple inheritance and Java translated it with multiple implementation (interfaces), which I find really intuitive and simple (I don't think that this is just an opinion).
My first question is in the title. I think that C++ would be more friendly, without losing practically a bit of its power. It's a question of improving a extraordinary programming language, which however is not perfect.
My second question is: what are the advantages of multiple inheritance compared to the interfaces of Java programming language (if any)?
Multiple inheritance can be dangerous, but it's sometimes the most appropriate solution to a problem, and there's lots of software already written that uses it. Removing multiple inheritance from C++ would break all that software, in a way that's not simple to fix. Being compatible with existing code is more important than being "friendly".
If you want the effect of a Java interface in C++, just write a class that contains nothing but pure-virtual member functions, and derive from it using virtual inheritance to "implement" it in another class.
Java was designed as a higher-level and simpler language than C++, and the tradeoffs between them are the same as between any high-level and lower-level language. Java provides a bit less flexibility (e.g. single inheritance, little control over memory allocation) in exchange for being a bit easier to work with; C++ provides more power and flexibility at the cost of having to "know what you're doing" a bit more. These differences are OK; there's no need to turn one language into the other.
C++ is becoming more and more user-friendly with the updates, becoming bit by bit more like java, but it needs not to change too much not to wreck legacy code. The Boost library is more or less the pioneer of the c++ language, being the (probably) most used library of all times and taking an easier and more intuitive OO approach to c++. Features from the Boost libraries often get to the STD eventually.
Let's take this easy example : class man and class parent have respective functions work and cry. class dad inherits from both man and parent. Now you don't have to write cry twice when you write class mom which inherits from class woman as well as from parent.
1.Having multiple inheritance in a explicit way is seems to be more user friendly but actually it is not. There are lot of problem will be coming in the future if you do that i mean in your project for an instance knowingly unknowingly you will be adding the same code again and again to your final Class which makes your project more complicated and confuses the interpreter which method should be executed at the appropriate time.
Just consider in C++ you have
Class A
{
void display_a(){}
}
Class B A
{
void display_b(){}//this class contains 'display_a()' too
}
Class C A,B //multiple inheritance.
{
display_c(){} //this class contains two times 'display_a()' and one time 'display_b()'
}
so class a contains two times 'display_a()' this is the problem we have in multiple inheritance in C++ so that we go for Interface in Java,which solve that problem.
I know this is a question that has been asked a 100 times over but I would like to provide some of my own definitions to see if I understand an interface correctly.
Questions:
What is an interface?
An interface defines the structure for code design. An interface lays the foundation for your design and is made up of a collection of abstract methods and contains behaviors that a class must implement.
When to use an interface?
When similar methods of a design are to be reused across a project. This creates the structure of the behavior within a a project.
Why use an interface?
You use an interface in a project to create the foundation much like the construction of a new home. When a new home is built the frame is built, then the walls and doors and so on are added.
My above answers are what I describe as an interface and would like to know whether I am correct or not? If not, then please explain?
Thanks
You use an interface so that any class can make use of it as long as they implement it. That is why List is so cool and we use it in everyday programming.
Cows and Goats are both animals and they eat, walk, sleep, etc. You do not want to declare the same behaviors separately. If you now have a new animal, you will have to define the similar behaviors again. An interface forces you to implement the required behaviors.
I would argue that an interface is more like a an optional contract -- you specify the method names, parameters, and return type, and if a class chooses to implement the interface, it must then conform to the terms of that contract. It's more like an API spec than a design foundation, as interfaces are relatively flexible.
Note that this flexibility gives you considerable leeway in how you choose to use interfaces. As long as the implementing class provides the agreed-upon methods, the implementation is entirely up to you. There are interfaces (e.g. Serializable) that require no methods, and simply act as markers for the programmer's intent regarding a certain class.
Another use of interfaces is to mitigate the disadvantages of the fact that Java doesn't support multiple inheritance. Though each implementing class must contain the actual code, you might use an interface in an 'inheritance-like' way, to indicate that a certain set of classes derives behavior (in name, if not necessarily in implementation) from some common, more abstract pattern.
I would definitely suggest looking through the javadocs (perhaps the Collections framework) for more examples of interfaces. To continue with the contract analogy, the main use of interfaces is as a sort of API that specifies behavior you can count on, without having to know the implementation details.
The problem with the home analogy is that it's too restrictive-- interfaces don't restrict the design of a class as much as a foundation prescribes a certain structure for a building. Additionally, a building can only have one foundation, and in Java, there is no limit to the number of interfaces a class may implement.
Think of a TV remote analogy.
What
Its a standard way of using a Television(any television...flat screen, CRT, LED, LCD, Plasma etc).
So its basically an interface to a Television. Now, all TV remotes must have some basic common buttons (On, Off, Vol+, Vol-, Ch+, Ch-), these are the methods which should be present in the interface. Different brands implement these using different techs.
When
Now all Television brands want to share this standard way of controlling a Television (which is a big complicated machine).
Why
Think about it. It helps the consumer. As far as the consumer is concerned, he/she does not need to know how to manually operate the Television or from inside(you can do that from the circuit board!)
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I’m having trouble understanding how classes relate to their methods. Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?
Specifically, in a library’s software system, should the borrow() method belong to the class representing the library patron, or the class representing the item that the patron is borrowing? My intuition is that it should read like patron.borrow(copy), like English sentence structure, subject.verb(object); but my instructor says that’s Wrong, and I don’t understand why he would have borrow() belong to the Copy class (and he doesn’t really explain things too well). I’m not looking for justification, but can someone just explain the proper relationship?
Edit: This question was closed as “off topic”. I don’t understand. Are software design questions not appropriate for this site?
subjective :) but honestly, I'd go with the Information Expert Pattern and say something like
library.lend(item, patron)
The library contains the information about the items it has (perhaps in its catalog).
The library lends the item to the patron (which it knows because it registers them)
Not sure how your instructor sees this, but this is the level of 'abstraction' (software objects mimicking real world entities) that would make sense for your scenario.
You should not confuse the idea of OOP with one specific incarnation like Java or C++.
This limit "methods are a property of the object" is not part of the OOP idea, but just of some implementations and as you discovered it doesn't scale well.
How many methods sould an "integer number" object have? What is more logical... myfile.write(myint) or myint.write(myfile)? There is really no good general answer to this. The idea of a method being part of a single object is a special case and sometimes the bending needed to fit the problem to this solution can become noticeable or even close to a showstopper. The answer is really totally acceptable only when a method has no parameters except the object being processed: single dispatch is a perfect answer only when there is a single type involved.
In other languages you have a separation between objects and methods, so for example you have the file object, the integer object and a method write(myfile, myint) that describes what to do when the operation is needed... and this method is neither part of the file nor of the integer.
Some generic words first.
Software construction is not something which should be governed by English language rules or "beauty" or whatever, it's engineering discipline. Think of whether your design solves the problem, whether it will be maintainable, whether it will be testable, whether it will be possible to parallelize development and so on. If you want something more formalized take a look at the "On the Criteria To Be Used in Decomposing Systems into Modules" by D. L. Parnas.
As for your library example. Imagine you have a Copy outside of library, shoult it have borrow method then? How the borrowing is registered? Are you ok with either Copy or Patron classes responsible for data storage? It looks more appropriate to put borrow into a Library class. Responsibilities will be clearly divided, you wouldn't need to know much about borrowing to implement Copy and Patron and you wouldn't need much details about them to implement Library.
Public methods exposed from a class are the tasks that can be performed on the entity.
That way the class would only encapsulate its behavior.
For example:
if i say
Computer.TurnOn()
The method will only work on the computer system.
instead if i say,
SomeOne.TurnonComputer()
The someone will now have the responsibility to turn on the computer(set related properties of computer), that means we are not meeting the concept of encapsulation and scattering the class's properties all over the place.
As #Ryan Fernandes said, the lend/borrow operation cannot be with either patron or book. It has to be with some class that knows about the status of all the books and patrons of the library. For e.g., are there pending reservations against a book? How many copies are available? Has this patron paid all the fees? Is he eligible for this book? So typically this should be in Library or a LibraryService class.
The point of OOP is to create polymorphic functions that, in each implementation, deal with a defined set of data which obey specific invariants.
It follows that a method which alters an object should be defined in the class of that object. It matters less where code that is purely functional lives, but it should probably live on the type of its input (if it takes a single input) or on its output.
In your example, if borrow alters data in copy, then it should live there. If, however, you model the loan status of a book by it being held in a particular collection (either in a patron, or in a collection for the library), it would make more sense to put borrow on the holder classes. That latter design, however, runs the risk that a copy could be in more than one collection, so you would want to put some information (and a corresponding method) on the copy as well.
Not pretty sure for the exact justification , but you can think it this way, IF multiple patients go and visit a doctor, its only the doctor who know when to call in the next patient, so the next method would be a part of Doctor's Responsibility, though its tempting to think that next should be the part of Patient's responsibility as he has to go next, someways when the library book is to be issued, it should be the responsibility of book genre rather patron as book(RESOURCE) knows when it will be free .
Is a method something that the object does, or something that’s done to it? Or is this a different concept entirely?
Let me clear something about class and objects first. Class are generally used to a denote particular category. Like
Cars not Ferrari, or Porsche
Fruits not Banana, or Apple
So, it's Ferrari that is driven, and a banana that is eaten. Not their class
Its always an object that has properties and has behavior.
Even going to your case specifically.
borrow() method is an action/behavior done by a object of a person on an object of book whose records is kept by another object of the library system itself.
A good way to represent this in OO way for me would be like
libray.borrow(new book('book title'), new person('starx'));
Just for fun, What do you think about this
person starx = new person('starx');
book title1 = new book('title1');
library libraryname = new library('libraryname');
libraryname.addBook(title1);
if(starx.request(title1, libraryname)) {
starx.take(library.lend(title1, starx));
}
I guess it can go either way. There is no hard and fast rule for it. The idea is the group functions logically that makes sense. To me, Patron#borrow(BookCopy) make same sense as BookCopy#borrow(Patron). Or you may have a class LibManager.borrow(BookCopy, Patron).
Your instructor's right. Well, actually, he's wrong. I don't know.
My point is, for questions such as this, there are often no firm general answers one way or another. It largely comes down to what works best in your particular case. Go with whatever's easiest to code - it'll be the easiest to maintain. And, by "easiest to code", I suggest also taking into account the intended users of the classes (beyond just your Library, Copy and Person classes).
I was thinking about precisely that today. I came to this conclusion:
Whichever makes more sense in the appropriate context.
The open-closed principle states that "Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification".
However, Joshua Bloch in his famous book "Effective Java" gives the following advice: "Design and document for inheritance, or else prohibit it", and encourages programmers to use the "final" modifier to prohibit subclassing.
I think these two principles clearly contradict each other (am I wrong?). Which principle do you follow when writing your code, and why? Do you leave your classes open, disallow inheritance on some of them (which ones?), or use the final modifier whenever possible?
Frankly I think the open/closed principle is more an anachronism than not. It sems from the 80s and 90s when OO frameworks were built on the principle that everything must inherit from something else and that everything should be subclassable.
This was most typified in UI frameworks of the era like MFC and Java Swing. In Swing, you have ridiculous inheritance where (iirc) button extends checkbox (or the other way around) giving one of them behaviour that isn't used (I think it's its the setDisabled() call on checkbox). Why do they share an ancestry? No reason other than, well, they had some methods in common.
These days composition is favoured over inheritance. Whereas Java allowed inheritance by default, .Net took the (more modern) approach of disallowing it by default, which I think is more correct (and more consistent with Josh Bloch's principles).
DI/IoC have also further made the case for composition.
Josh Bloch also points out that inheritance breaks encapsulation and gives some good examples of why. It's also been demonstrated that changing the behaviour of Java collections is more consistent if done by delegation rather than extending the classes.
Personally I largely view inheritance as little more than an implemntation detail these days.
I don't think the two statements contradict each other. A type can be open for extension and still be closed for inheritance.
One way to do this is to employ dependency injection. Instead of creating instances of its own helper types, a type can have these supplied upon creation. This allows you to change the parts (i.e. open for extension) of the type without changing the type itself (i.e. close for modification).
In open-closed principle (open for extension, closed for modification) you can still use the final modifier. Here is one example:
public final class ClosedClass {
private IMyExtension myExtension;
public ClosedClass(IMyExtension myExtension)
{
this.myExtension = myExtension;
}
// methods that use the IMyExtension object
}
public interface IMyExtension {
public void doStuff();
}
The ClosedClass is closed for modification inside the class, but open for extension through another one. In this case it can be of anything that implements the IMyExtension interface. This trick is a variation of dependency injection since we're feeding the closed class with another, in this case through the constructor. Since the extension is an interface it can't be final but its implementing class can be.
Using final on classes to close them in java is similar to using sealed in C#. There are similar discussions about it on the .NET side.
I respect Joshua Bloch a great deal, and I consider Effective Java to pretty much be the Java bible. But I think that automatically defaulting to private access is often a mistake. I tend to make things protected by default so that they can at least be accessed by extending the class. This mostly grew out of a need to unit test components, but I also find it handy for overriding the default behavior of classes. I find it very annoying when I'm working in my own company's codebase and end up having to copy & modify the source because the author chose to "hide" everything. If it's at all in my power, I lobby to have the access changed to protected to avoid the duplication, which is far worse IMHO.
Also keep in mind that Bloch's background is in designing very public bedrock API libraries; the bar for getting such code "correct" must be set very high, so chances are it's not really the same situation as most code you'll be writing. Important libraries such as the JRE itself tend to be more restrictive in order to ensure that the language is not abused. See all the deprecated APIs in the JRE? It's almost impossible to change or remove them. Your codebase is probably not set in stone, so you do have the opportunity to fix things if it turns out you made a mistake initially.
Nowadays I use the final modifier by default, almost reflexively as part of the boilerplate. It makes things easier to reason about, when you know that a given method will always function as seen in the code you're looking at right now.
Of course, sometimes there are situations where a class hierarchy is exactly what you want, and it would be silly not to use one then. But be scared of hierarchies of more than two levels, or ones where non-abstract classes are further subclassed. A class should be either abstract or final.
Most of the time, using composition is the way to go. Put all the common machinery into one class, put the the different cases into different classes, then composit instances to have working whole.
You can call this "dependency injection", or "strategy pattern" or "visitor pattern" or whatever, but what it boils down to is using composition instead of inheritance to avoid repetition.
The two statements
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
and
Design and document for inheritance, or else prohibit it.
are not in direct contradiction with one another. You can follow the open-closed principle as long as you design and document for it (as per Bloch's advice).
I don't think that Bloch states that you should prefer to prohibit inheritance by using the final modifier, just that you should explicitly choose to allow or disallow inheritance in each class you create. His advice is that you should think about it and decide for yourself, instead of just accepting the default behavior of the compiler.
I don't think that the Open/closed principle as originally presented allows the interpretation that final classes can be extended through injection of dependencies.
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.
As pointed out in the first answer, this has historical roots. Decades ago, inheritance was in favor, developer testing was unheard of, and recompilation of the codebase often took too long.
Also, consider that in C++ the implementation details of a class (in particular, private fields) were commonly exposed in the ".h" header file, so if a programmer needed to change it, all clients would require recompilation. Notice this isn't the case with modern languages like Java or C#. Besides, I don't think developers back then could count on sophisticated IDEs capable of performing on-the-fly dependency analysis, avoiding the need for frequent full rebuilds.
In my own experience, I prefer to do the exact opposite: "classes should be closed for extension (final) by default, but open for modification". Think about it: today we favor practices like version control (makes it easy to recover/compare previous versions of a class), refactoring (which encourages us to modify code to improve design, or as a prelude to introducing new features), and developer testing, which provides a safety net when modifying existing code.