I have a question regarding the design of my program. I have a class A that stores public constant so that i can use these constants in another class.
public static final String error_code1 = "Fatal Error";
public static final String error_code2 = "XXXX";
...
...
Between Composition vs Interface, i dont know which 1 is more suitable. From what i think, since i only need the constants for value-comparing in my program, so i think composition is enough (low coupling).
But can you guys give me some advice/arguments from software deign point of view? (cohesion, coupling, difficulties of maintenance, etc )
First of all I'd recommend you to use an enum for this case.
public enum ErrorCode {
FATAL_ERROR("Fatal Error"),
X_ERROR("XXXX");
public final String msg;
private ErrorCode(String msg) {
this.msg = msg;
}
}
If this doesn't suit you for some reason, I'd go with a final utility class with private (unused) constructor.
Regardless, since the fields are static and final, I would not consider having a reference to A or implement A to get hold of the constants.
Adding constants to interfaces is considered an anti-pattern since the primary purpose of an interface is to define behavior contracts. Use either an enum or access them directly since they are public.
I wouldn't use interface to store constant as having static members into an interface (and implementing that interface) is a bad practice and there is even a name for it, the Constant Interface Antipattern, see [Effective Java][1], Item 17:
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
I would personally go for enum and if needed i could even use it to have error code or add relevant field/method as well.
String/int/... constants in another class have one problem: they are copied into the using class' constant pool, and after that no import to the original class exists. Should you then alter a constant's value, the using class is not forced to be recompiled.
The solution would be to use an interface, and "implement" that interface; ugly maybe.
Better is to use an enum.
For open ended value domains one would not use an enumeration, but an object oriented approach:
abstract class ParseError extends RuntimeException
class ExpressionExpectedError extends ParseError
class DigitsMayNotFollowLeadingZeroError extends ParseError
..
In the javadoc one might see all child classes of ParseError. Here the classes themselves form the domain values, and an instantiation bears the actual context information. That is more OOP. Calling several methods on an object is better than having several switches on constants. An enum however may be used with categorical method too: boolean errorHandledBySkippingToNextExpr().
Related
I am reading a book about Java and it says that you can declare the whole class as final. I cannot think of anything where I'd use this.
I am just new to programming and I am wondering if programmers actually use this on their programs. If they do, when do they use it so I can understand it better and know when to use it.
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
First of all, I recommend this article: Java: When to create a final class
If they do, when do they use it so I can understand it better and know when to use it.
A final class is simply a class that can't be extended.
(It does not mean that all references to objects of the class would act as if they were declared as final.)
When it's useful to declare a class as final is covered in the answers of this question:
Good reasons to prohibit inheritance in Java?
If Java is object oriented, and you declare a class final, doesn't it stop the idea of class having the characteristics of objects?
In some sense yes.
By marking a class as final you disable a powerful and flexible feature of the language for that part of the code. Some classes however, should not (and in certain cases can not) be designed to take subclassing into account in a good way. In these cases it makes sense to mark the class as final, even though it limits OOP. (Remember however that a final class can still extend another non-final class.)
In Java, items with the final modifier cannot be changed!
This includes final classes, final variables, and final methods:
A final class cannot be extended by any other class
A final variable cannot be reassigned another value
A final method cannot be overridden
One scenario where final is important, when you want to prevent inheritance of a class, for security reasons. This allows you to make sure that code you are running cannot be overridden by someone.
Another scenario is for optimization: I seem to remember that the Java compiler inlines some function calls from final classes. So, if you call a.x() and a is declared final, we know at compile-time what the code will be and can inline into the calling function. I have no idea whether this is actually done, but with final it is a possibility.
The best example is
public final class String
which is an immutable class and cannot be extended.
Of course, there is more than just making the class final to be immutable.
If you imagine the class hierarchy as a tree (as it is in Java), abstract classes can only be branches and final classes are those that can only be leafs. Classes that fall into neither of those categories can be both branches and leafs.
There's no violation of OO principles here, final is simply providing a nice symmetry.
In practice you want to use final if you want your objects to be immutable or if you're writing an API, to signal to the users of the API that the class is just not intended for extension.
Relevant reading: The Open-Closed Principle by Bob Martin.
Key quote:
Software Entities (Classes, Modules,
Functions, etc.) should be open for
Extension, but closed for
Modification.
The final keyword is the means to enforce this in Java, whether it's used on methods or on classes.
The keyword final itself means something is final and is not supposed to be modified in any way. If a class if marked final then it can not be extended or sub-classed. But the question is why do we mark a class final? IMO there are various reasons:
Standardization: Some classes perform standard functions and they are not meant to be modified e.g. classes performing various functions related to string manipulations or mathematical functions etc.
Security reasons: Sometimes we write classes which perform various authentication and password related functions and we do not want them to be altered by anyone else.
I have heard that marking class final improves efficiency but frankly I could not find this argument to carry much weight.
If Java is object oriented, and you declare a class final, doesn't it
stop the idea of class having the characteristics of objects?
Perhaps yes, but sometimes that is the intended purpose. Sometimes we do that to achieve bigger benefits of security etc. by sacrificing the ability of this class to be extended. But a final class can still extend one class if it needs to.
On a side note we should prefer composition over inheritance and final keyword actually helps in enforcing this principle.
final class can avoid breaking the public API when you add new methods
Suppose that on version 1 of your Base class you do:
public class Base {}
and a client does:
class Derived extends Base {
public int method() { return 1; }
}
Then if in version 2 you want to add a method method to Base:
class Base {
public String method() { return null; }
}
it would break the client code.
If we had used final class Base instead, the client wouldn't have been able to inherit, and the method addition wouldn't break the API.
A final class is a class that can't be extended. Also methods could be declared as final to indicate that cannot be overridden by subclasses.
Preventing the class from being subclassed could be particularly useful if you write APIs or libraries and want to avoid being extended to alter base behaviour.
In java final keyword uses for below occasions.
Final Variables
Final Methods
Final Classes
In java final variables can't reassign, final classes can't extends and final methods can't override.
Be careful when you make a class "final". Because if you want to write an unit test for a final class, you cannot subclass this final class in order to use the dependency-breaking technique "Subclass and Override Method" described in Michael C. Feathers' book "Working Effectively with Legacy Code". In this book, Feathers said, "Seriously, it is easy to believe that sealed and final are a wrong-headed mistake, that they should never have been added to programming languages. But the real fault lies with us. When we depend directly on libraries that are out of our control, we are just asking for trouble."
If the class is marked final, it means that the class' structure can't be modified by anything external. Where this is the most visible is when you're doing traditional polymorphic inheritance, basically class B extends A just won't work. It's basically a way to protect some parts of your code (to extent).
To clarify, marking class final doesn't mark its fields as final and as such doesn't protect the object properties but the actual class structure instead.
TO ADDRESS THE FINAL CLASS PROBLEM:
There are two ways to make a class final. The first is to use the keyword final in the class declaration:
public final class SomeClass {
// . . . Class contents
}
The second way to make a class final is to declare all of its constructors as private:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marking it final saves you the trouble if finding out that it is actual a final, to demonstrate look at this Test class. looks public at first glance.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Unfortunately, since the only constructor of the class is private, it is impossible to extend this class. In the case of the Test class, there is no reason that the class should be final. The Test class is a good example of how implicit final classes can cause problems.
So you should mark it final when you implicitly make a class final by making it's constructor private.
One advantage of keeping a class as final :-
String class is kept final so that no one can override its methods and change the functionality. e.g no one can change functionality of length() method. It will always return length of a string.
Developer of this class wanted no one to change functionality of this class, so he kept it as final.
The other answers have focused on what final class tells the compiler: do not allow another class to declare it extends this class, and why that is desirable.
But the compiler is not the only reader of the phrase final class. Every programmer who reads the source code also reads that. It can aid rapid program comprehension.
In general, if a programmer sees Thing thing = that.someMethod(...); and the programmer wants to understand the subsequent behaviour of the object accessed through the thing object-reference, the programmer must consider the Thing class hierarchy: potentially many types, scattered over many packages. But if the programmer knows, or reads, final class Thing, they instantly know that they do not need to search for and study so many Java files, because there are no derived classes: they need study only Thing.java and, perhaps, it's base classes.
Yes, sometimes you may want this though, either for security or speed reasons. It's done also in C++. It may not be that applicable for programs, but moreso for frameworks.
http://www.glenmccl.com/perfj_025.htm
think of FINAL as the "End of the line" - that guy cannot produce offspring anymore. So when you see it this way, there are ton of real world scenarios that you will come across that requires you to flag an 'end of line' marker to the class. It is Domain Driven Design - if your domain demands that a given ENTITY (class) cannot create sub-classes, then mark it as FINAL.
I should note that there is nothing stopping you from inheriting a "should be tagged as final" class. But that is generally classified as "abuse of inheritance", and done because most often you would like to inherit some function from the base class in your class.
The best approach is to look at the domain and let it dictate your design decisions.
As above told, if you want no one can change the functionality of the method then you can declare it as final.
Example: Application server file path for download/upload, splitting string based on offset, such methods you can declare it Final so that these method functions will not be altered. And if you want such final methods in a separate class, then define that class as Final class. So Final class will have all final methods, where as Final method can be declared and defined in non-final class.
Let's say you have an Employee class that has a method greet. When the greet method is called it simply prints Hello everyone!. So that is the expected behavior of greet method
public class Employee {
void greet() {
System.out.println("Hello everyone!");
}
}
Now, let GrumpyEmployee subclass Employee and override greet method as shown below.
public class GrumpyEmployee extends Employee {
#Override
void greet() {
System.out.println("Get lost!");
}
}
Now in the below code have a look at the sayHello method. It takes Employee instance as a parameter and calls the greet method hoping that it would say Hello everyone! But what we get is Get lost!. This change in behavior is because of Employee grumpyEmployee = new GrumpyEmployee();
public class TestFinal {
static Employee grumpyEmployee = new GrumpyEmployee();
public static void main(String[] args) {
TestFinal testFinal = new TestFinal();
testFinal.sayHello(grumpyEmployee);
}
private void sayHello(Employee employee) {
employee.greet(); //Here you would expect a warm greeting, but what you get is "Get lost!"
}
}
This situation can be avoided if the Employee class was made final. Just imagine the amount of chaos a cheeky programmer could cause if String Class was not declared as final.
Final class cannot be extended further. If we do not need to make a class inheritable in java,we can use this approach.
If we just need to make particular methods in a class not to be overridden, we just can put final keyword in front of them. There the class is still inheritable.
Final classes cannot be extended. So if you want a class to behave a certain way and don't someone to override the methods (with possibly less efficient and more malicious code), you can declare the whole class as final or specific methods which you don't want to be changed.
Since declaring a class does not prevent a class from being instantiated, it does not mean it will stop the class from having the characteristics of an object. It's just that you will have to stick to the methods just the way they are declared in the class.
Android Looper class is a good practical example of this.
http://developer.android.com/reference/android/os/Looper.html
The Looper class provides certain functionality which is NOT intended to be overridden by any other class. Hence, no sub-class here.
I know only one actual use case: generated classes
Among the use cases of generated classes, I know one: dependency inject e.g. https://github.com/google/dagger
Object Orientation is not about inheritance, it is about encapsulation. And inheritance breaks encapsulation.
Declaring a class final makes perfect sense in a lot of cases. Any object representing a “value” like a color or an amount of money could be final. They stand on their own.
If you are writing libraries, make your classes final unless you explicitly indent them to be derived. Otherwise, people may derive your classes and override methods, breaking your assumptions / invariants. This may have security implications as well.
Joshua Bloch in “Effective Java” recommends designing explicitly for inheritance or prohibiting it and he notes that designing for inheritance is not that easy.
JLS 2.13.1 Interface Modifiers
An interface cannot be final, because the implementation of such a class could never be completed.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
interface Type {
// Normal
class Value {
private Value() {
}
public void print() {
System.out.println("Test");
}
}
public final Value value = new Value();
}
Well in Interfaces you cannot provide any form of implementation at all: Not even static methods. It doesn't make sense to make any method final because they're yet to be implemented.
Code Examples:
If let say I have an interface named IExample and its concrete implementation Example:
interface IExample{
public final void run();
}
class Example implements IExample{
// wait! I can't override because it's final! but it's yet to be implemented?!
public void run(){
}
}
BTW: nested classes were not available when this restriction was first defined, so really the question might be why this restriction was not lifted.
A final class cannot have any sub-classes. It is considered best practice to only use interfaces for defining method(s) of sub-classes, so the two are contradictory.
You can use interfaces for other things
annotations
javadocs
constants
defining nested classes only.
but these are incidental to the purpose of an interface.
"When the final keyword appears in a class declaration, it means that the class may never be subclassed or overridden. This prevents over-specialization of a particular class. In some sense, the person who created the class considered any further changes to be tangential to its primary purpose."
Reference: Final
Interface represent behaviour, rather than implementation, therefore it makes no sense for it to be final.
If I can write create static inner classes in interface I can provide implementation in it so why is such restriction
Yes, you can declare an inner class there, but point remains that a final interface would be an interface that it is impossible to implement. Any class that implemented it would be violating the final restriction. The Java designers concluded that this didn't make much sense, and since there are no convincing use-cases for final interfaces with nested classes*, there is no justification for relaxing this restriction.
* - I won't claim that one could not invent a use-case. However, I've never heard of people writing interfaces with inner classes, with the intention was that the interface should not be implemented.
I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?
The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...
Am I missing something?
All fields in interface are public static final, i.e. they are constants.
It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.
First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.
In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.
Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.
But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.
Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.
(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).
What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?
interface IdFinder {
Serializable UNSAVED = new Serializable() {};
/** #returns the given entity's persistent identity,
or {#link UNSAVED} if it hasn't been saved yet,
or null if o is a value object that hasn't a
persistent identity of its own.
*/
Serializable getId(Object o);
}
Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:
public class Constants {
private Constants() { }
public static final int ZERO = 0;
public static final int SOME_COMPLEX_NUM = 2124132L;
...
}
You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)
In his book Effective Java, Joshua Bloch recommends against using Interfaces to hold constants,
The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the con-stants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
His reasoning makes sense to me and it seems to be the prevailing logic whenever the question is brought up but it overlooks storing constants in interfaces and then NOT implementing them.
For instance,
public interface SomeInterface {
public static final String FOO = "example";
}
public class SomeOtherClass {
//notice that this class does not implement anything
public void foo() {
thisIsJustAnExample("Designed to be short", SomeInteface.FOO);
}
}
I work with someone who uses this method all the time. I tend to use class with private constructors to hold my constants, but I've started using interfaces in this manner to keep our code a consistent style. Are there any reasons to not use interfaces in the way I've outlined above?
Essentially it's a short hand that prevents you from having to make a class private, since an interface can not be initialized.
I guess it does the job, but as a friend once said: "You can try mopping a floor with an octopus; it might get the job done, but it's not the right tool".
Interfaces exist to specify contracts, which are then implemented by classes. When I see an interface, I assume that there are some classes out there that implement it. So I'd lean towards saying that this is an example of abusing interfaces rather than using them, simply because I don't think that's the way interfaces were meant to be used.
I guess I don't understand why these values are public in the first place if they're simply going to be used privately in a class. Why not just move them into the class? Now if these values are going to be used by a bunch of classes, then why not create an enum? Another pattern that I've seen is a class that just holds public constants. This is similar to the pattern you've described. However, the class can be made final so that it cannot be extended; there is nothing that stops a developer from implementing your interface. In these situations, I just tend to use enum.
UPDATE
This was going to be a response to a comment, but then it got long. Creating an interface to hold just one value is even more wasteful! :) You should use a private constant for that. While putting unrelated values into a single enum is bad, you could group them into separate enums, or simply use private constants for the class.
Also, if it appears that all these classes are sharing these unrelated constants (but which make sense in the context of the class), why not create an abstract class where you define these constants as protected? All you have to do then is extend this class and your derived classes will have access to the constants.
I don't think a class with a private constructor is any better than using an interface.
What the quote says is that using implements ConstantInterface is not best pratice because this interface becomes part of the API.
However, you can use static import or qualified names like SomeInteface.FOO of the values from the interface instead to avoid this issue.
Constants are a bad thing anyway. Stuffing a bunch of strings in a single location is a sign that your application has design problems from the get go. Its not object oriented and (especially for String Constants) can lead to the development of fragile API's
If a class needs some static values then they should be local to that class. If more classes need access to those values they should be promoted to an enumeration and modeled as such. If you really insist on having a class full of constants then you create a final class with a private no args constructor. With this approach you can at least ensure that the buck stops there. There are no instantiations allowed and you can only access state in a static manner.
This particular anti-pattern has one serious problem. There is no mechanism to stop someone from using your class that implements this rouge constants interface.Its really about addressing a limitation of java that allows you to do non-sensical things.
The net out is that it reduces the meaningfulness of the application's design because the grasp on the principles of the language aren't there. When I inherit code with constants interfaces, I immediately second guess everything because who knows what other interesting hacks I'll find.
Creating a separate class for constants seems silly. It's more work than making an enum, and the only reason would be to do it would be to keep unrelated constants all in one place just because presumably they all happen to be referenced by the same chunks of code. Hopefully your Bad Smell alarm goes of when you think about slapping a bunch of unrelated stuff together and calling it a class.
As for interfaces, as long as you're not implementing the interface it's not the end of the world (and the JDK has a number of classes implementing SwingConstants for example), but there may be better ways depending on what exactly you're doing.
You can use enums to group related constants together, and even add methods to them
you can use Resource Bundles for UI text
use a Map<String,String> passed through Collections.unmodifiableMap for more general needs
you could also read constants from a file using java.util.Properties and wrap or subclass it to prevent changes
Also, with static imports there's no reason for lazy people to implement an interface to get its constants when you can be lazy by doing import static SomeInterface.*; instead.
I faced with a sample code in Java and it brought me a question.
Java sample code is:
...
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
void printf(String format, Object... args);
}
public static void main(String[] args) throws IOException {
CLibrary.INSTANCE.printf("Hello, World\n");
}
But in C# we cannot write like that:
public interface IMyInterface {
static readonly int staticInt = 5; // compile error
static readonly SomeClass staticInstance = new SomeClass(); // compile error
}
What is the difference between these two languages/frameworks?
What design policy permit java to have const fields in an interface or what prevents .NET from having that?
The use of interfaces to hold constants is usually frowned on these days in Java too. (I'd say that storing non-compile-time-constant fields like your example is even more frowned upon.)
Fundamentally, it's at odd with the idea of an interface: a contract that the implementation will uphold. The implementation isn't going to provide the field, so what's it doing there?
I suspect the C# team decided that it was sufficiently at odds with the concept behind interfaces to not include it in the language. I don't know whether it's just a C# restriction or a CLR restriction too. For example, I know that the CLR allows interfaces to declare nested types, but C# doesn't currently allow this.
In C#:
Interfaces consist of methods,
properties, events, indexers, or any
combination of those four member
types. An interface cannot contain
constants, fields, operators, instance
constructors, destructors, or types.
It cannot contain static members.
Interfaces members are automatically
public, and they cannot include any
access modifiers.
In Java:
Every field declaration in the body of
an interface is implicitly public,
static, and final.
Every field in the body of an
interface must have an initialization
expression, which need not be a
constant expression. The variable
initializer is evaluated and the
assignment performed exactly once,
when the interface is initialized.
In Java, all fields in an interface are implicitly static and final.
But its considered bad practice. To qoute Joshua Bloch from Effective Java:
The constant interface pattern is a
poor use of interfaces. That a class
uses some constants internally is an
implementation detail. Implementing a
constant interface causes this
implementation detail to leak into the
class's exported API. It is of no
consequence to the users of a class
that the class implements a constant
interface. In fact, it may even
confuse them. Worse, it represents a
commitment: if in a future release the
class is modified so that it no longer
needs to use the constants, it still
must implement the interface to ensure
binary compatibility. If a nonfinal
class implements a constant interface,
all of its subclasses will have their
namespaces polluted by the constants
in the interface.
As to why it is considered bad practice, I think a class implementing an interface with constant fields is exposing these in the interface to outside code which consumes this class which in most cases is not what is required.
I guess COM's Microsoft Interface Description Language does not allow it. So it's just an adaptation for the Windows environment, much like prefixing interface names with I.
Like most questions of this form, the question is basically pointless. It's not like the designers of Java and C# had a meeting about it. Historically Java came first so you would really have to ask the designers of C#, not that the question would necessarily make sense to them either. It's just how they saw it at the time.
I think it's weird that Java chose to allow this.
An interface is a contract for a Role. That is, it's an spec that all objects must implement in order to be considered as suitable/swappable candidates for that Role. It should contain the messages/methods that the Role responds to and the notifications that it triggers for interested listeners.
Fields are an implementation detail (and your example contains actual implementation dictating the return value for the INSTANCE field too) and do not belong within the contract. If you wanted to map this to C#, you should probably move it to an abstract base class, which allows default implementation to be specified in addition to specifying some members that derived classes must also implement.