We have a huge projects based on an old jdk 1.4. We have migrated the web app to JDK 1.6 but still lot of inefficient practices and bad design exist in the code.
On of the major pain point huge java classes 2500+ lines of code in single java file. So many files like these.
In an attempt to refactor the classes I had started off by removing constants and putting constants in different Constants.java file. but since there are so many constants through-out the application, the constants file has the risk of growing to humongous proportions.
I would appreciate feedback on what strategy are developers adopting to keep code clean and maintainable.
Keep your constants in the class they are related to, don't feel obligated to extract them. It may clean up the code of the class, but mixing unrelated constants in a file is not an improvement.
Keep things related together.
And also you can convert them to Enums when possible/useful (but that can require some refactoring).
Putting all the Constants in a single file is a terrible idea! Especially the uber-Constant anti-pattern where all the Constants are in an Interface that every class has to implement. 10 ways to Sunday terrible! This was a bad idea when people started doing it back in the early 1990's before Java! It is definitely a bad idea in 2012!
It means you are mingling lots of un-related information and creating un-needed dependencies everytime you import this uber-Constants file. Things that go together should be together in an Enum or at least in the Class that uses them as arguments to its methods so that when they are changed you know how to do an impact analysis easily.
Imagine Color constants mixed in with DaysOfTheWeek constants mixed in with other business domain constants and there will be hundreds if not thousands of these things in a single file. How can that ever be considered a good idea? In every non-contrived case, an Enum that is a public inner member of a Class is a better solution.
It also means you have a single flat namespace to try and create names that don't conflict, then they aren't obvious what they belong to and how they should be used. This is never a positive exercise.
When designing and refactoring you should always:
Strive for high cohesion, this means keep related things as close together as possible.
Strive for loose coupling this means don't let un-related things leak into other un-related scopes.
Strive for self-documenting maintainable code, dozens or hundreds of private static final String/int declarations all mixed together doesn't fit this definition by anyone's standard!
In 2012 C-style constants are a poor solution when you now have Enum as a tool, you should be focused on converting as many of these groups of Constants to Enum wherever possible. Enum is type safe and can have other attributes and properties and behaviors attached to it to make them intelligent. That is the path to go down.
Just putting constants in a Constant.java file doesn't make sens in my opinion (it just move the problem away). But sometimes I use to regroup them to clear the things and use several files to regroup them : DatabaseConstants.java, GraphicConstants.java and so on...
and of course, using enums can be useful too (and best practice).
edit : to be precise, I actually work with Java ME application, so it's just a way to "mimic" the enums I can't have, with a "controlled vocabulary" in abstract classes (I miss all the Java EE features...)
For someone who is visiting this page.
If you don't want to maintain multiple constant files, below is the better way to organize.
public interface Constants {
public static final String CREATE_USER = "createUser";
// Nested Interface.
public interface ProjectConstants {
public static final String CREATE_PROJECT = "createProject";
public static final String INVALID_SESSION = "Invalid Session";
// As you know they are implicity public static final.
}
}// Accessed as:
Constants.ProjectConstants.CREATE_PROJECT
Updates:
As a best practice, its better to use Class.(See comments. . Thanks keplerian.)
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
I'd like to share a design pattern for constants i've seen a few years ago that maybe can help.
Start by creating a BaseConstant file. This will hold all your global constants that all packages could use.
Now in each subpackage of your app create a Constants file that will only be related to the subpackage . So if you had . a subpackage called Login only put constants related to login there. But the key is to extend off of BaseConstants. this way you get to see all the global constants in the IDE chooser but when you open the file you only see your package constants. that being said i think constant files can get really heavy and duplicate values and hard to read.
Here is what i mean ..
public class BaseConstants{
public static final String GLOBAL1= "GLOBAL string";
public static final String GLOBAL2= "another GLOBAL string";
}
Now in all your other packages create a files like this:
class MyPackageConstants extends BaseConstants{
public static final String LOCAL1 = "local String"
public static final String LOCAL2= "ANOTHER LOCAL string";
}
in your IDE when you type "MyPackageConstants." you should see all the constants for the entire application.
I've never heard of putting all of the constants to a single java file. The best way is to put the constants accossiated with the classes in themselves, but name them with capital letter and underscores like this one: EXAMPLE_CONSTANT
Have you tried using Enums for all of your constants? I've been told it is the preferred way since Java 1.5.
http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html
I think that if you have multiple java files over 2500 LOCs, the decision where to put the constants should be the least of your problems. You should form a clear picture of how the restructured system will look like.
This is probably much harder then deciding where to stick the constants and other syntactic considerations but needs to be done first nevertheless.
Related
Since it's regarded bad OO practice to have public variables in a class (instead, use getters and setters) then why not use private on all variables? Why does Java even permit using public if it's bad practice?
(This doesn't apply to functions, obviously)
A public static final variable is a good reason for example. Like a constant.
Having a public or private field is a design decision. The language itself is supposed to enable programmers to make their own design decisions, not enforce a design that the developer or team may not necessarily want to implement.
The more flexible the language, the more powerful it is. It's up to the project manager, the team, or the individual developer to determine the most appropriate way for a field to be accessed.
Access control of variable fields is not the only concern.
Consider simplicity. Java has a single default for access control of all types. This is easier to learn than having different access rules for different types.
Consider usability for new users. If everything were private by default, new users would be more likely confused about why something could not be accessed.
Finally, note that "getters and setters" are not always the appropriate alternative to public fields. Some fields should not be modified or even accessed outside the class.
[EDIT] There's also a historical reason behind the choice. The earliest versions of Java, then known as "Oak," had no private access. The default, and most-restricted access was package-protected. (Reference: this 2002 Java newsletter, citing the Oak 0.2 manual.)
I guess a good part of the reason is "C++ did it that way". Different languages disagree on this issue, so it's obviously not the only sensible choice. E.g. Python has everything public and trusts you to follow a library's documentation, while Ruby only has private fields.
It's about where you want to publish the field.
For public fields, you could safely do it for final fields, like constants:
public static final ...
And final fields:
public final ...
like the length field in java arrays. Although the convention is to provide a accessor method (a getter) in preference to making a field public.
Use protected fields when you want to publish the field to
subclasses.
Use default visibility (ie not specified) when you want to publish the field to other classes in the same package.
I think this is good to have this possibility (excluding static final constants), because You can use this to solve some problems quickly(instead of defining getters and setters), you just need to be careful here by breaking encapsulation rules.
It's a matter of managing complexity.
A public member can be accessed from outside the class, which for practical considerations means "potentially anywhere". If something goes wrong with a public field, the culprit can be anywhere, and so in order to track down the bug, you may have to look at quite a lot of code.
A private member can only be accessed from inside the same class, so if something goes wrong with that, there is usually only one source file to look at. If you have a million lines of code in your project, but your classes are kept small, this can reduce your bug tracking effort by a lot.
Another advantage is related to the concept of coupling. Some answers forgot to mention this.
I'd say make everything private by default, and then expose only those parts that absolutely have to be public (or just use getters and setters). The more you can make private, the better.
In the past I often used "import static" construct in Java classes. Recently I realized that instead of
import static my.pack.A.MY_CONSTANT;
you can use
import my.pack.A;
public class B {
private static final MY_CONSTANT = A.MY_CONSTANT;
}
The most obvious advantages of this approach are:
You can use refactoring in Eclipse to easily strip out all long constant expressions like A.B.C.CONSTANT.ANOTHER_ONE.TOO_LONG from your code without messing with static imports (which are not so quick to master in Eclipse)
You can give any name to any expression, which may be more meaningful in the current context.
For example:
private static final PAYMENT_TYPE = PaymentType.CASH;
...
calculateSomething(amount, PAYMENT_TYPE);
instead of
import static my.pack.PaymentType.CASH
...
calculateSomething(amount, CASH);
and also this is more easy to refactor, if the default PaymentType value changes to CREDIT_CARD.
My question is: are there any downsides of this approach compared to static imports or can it be used everywhere instead?
My only concern for now is the resulting compiled .class file, which is probably different for the two described approaches. So performance and memory usage may theoretically suffer.
I think the only downside is you have more code where you assign one constant to another constant. Other than that there should be no difference. Performance and memory shouldn't matter, you'll likely have more references back to the same constant pool entries. Even if it created separate constant pool entries it would take a lot of them to make a difference.
Being able to give good names to constants might be a very good thing, in cases where it isn't feasible to rename the original entries.
It is mostly a matter of taste, but the official docs recommend using the static version sparingly, especially with a wildcard. The main downside of static import is that it pollutes your namespace by added all the static members to it. In your above example, it should be about what you think it more readable for your code. Resist the urge to do "import package.*" unless you really want all the static members of package.
It should not effect your compiled code -- it is merely provides a shorthand access to the same constant.
Let's say I have a constants class containing 200+ static fields :
class AnimalConstants {
static final int AARDVARK = 1;
static final int ANTELOPE = 2;
static final int BEAR = 3;
...
...
static final int ZEBRA = 200;
}
Can anyone explain if there are any negative impact on performance and memory from using such classes.
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
Would it be better or worse if I implement the constants as an Enum class?
I don't think the impact is performance or memory.
I think it has to do with things like readability of code, keeping constants close to where they're used, and fundamental understanding of your problem.
I prefer to declare constants closer to where they're used. I believe they're easier to understand that way.
I would be surprised if the real constants that you claim number 200+ are truly related. If they are, they belong together in one place. If not, I'd say that they should be broken into smaller pieces and declared closer to where they're used.
I'll bet there's more context than your contrived example that would change responses if known.
Sure , enums are great. But see my other comments first.
Of course enum implementation is more ponderous than bunch of int constants but using enum:
you don't need to hardcode actual values of Animals (in your case) that can change later
you don't need to hardcode total number of Animals and you can simply iterate through all animals
methods with parameter of this enum will be understood correctly (foo(Animal animal) is better than foo(int animal))
you can add additional functionality to your enum values later, e.g. internal value isMammal
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
--> That would be a Constant Interface Pattern. If we use interfaces for constant and it is implemented by all classes but if you are developing an API, it is something like you are exposing your implementation details. Above wiki link explains this very well.
In both approach(Interface or Class) I would suggest using final class, create constants and do static import for constants wherever necessary.
Would it be better or worse if I implement the constants as an Enum class?
--> With Enums, this would be the best approach.
Changing any value that has already been compiled into another class may require a full build.
Addendum: See Is it possible to disable javac's inlining of static final variables? for a more thorough examination.
Yes it is okay to create a large number of constants. It is hard to discuss negative impact because we don't know any alternatives because we don't have your functional requirements.
But be assured that the compiler is written to work well with code written by humans. Having a bunch of fields is probably going to be okay.
I feel that constants can be very nice as it can be used in switch case since JDK7, you can compare with == and the variable name can be informative.
Can enum be even better? Yes it can. Explore the features of enums and see if anything is appealing to you
For your kind of vars (Animal Types) i suggest you to use an Enumerator instead of a class. With the number of vars using it shouldn't be a problem for performance as you're only using int primitive. The problem would have occurred if any var has been a class, that are more memory demanding to maintain their structure. I hope to have clarified your doubt (Sorry for the poor english, i'm a little rusted)
By now my average class contains about 500 lines of code and about 50 methods.
IDE is Eclipse, where I turned “Save Actions” so that methods are sorted in alphabetical order, first public methods, and then private methods.
To find any specific method in the code I use “Quick Outline”. If needed, “Open Call Hierarchy” shows the sequence of methods as they called one by one.
This approach gives following advantages:
I can start typing new method without thinking where to place it in the code, because after save it will be placed by Eclipse to appropriate place automatically.
I always find public methods in the upper part of the code (don’t have to search the whole class for them)
However there are some disadvantages:
When refactoring large method into smaller ones I’m not very satisfied that new private methods are placed in different parts of code and therefore it’s little bit hard to follow the code concept. To avoid that, I name them in some weird way to keep them near each one, for example: showPageFirst(), showPageSecond() instead of showFirstPage(), showSecondPage().
May be there are some better approaches?
Organize your code for its audiences. For example, a class in a library might have these audiences:
An API client who wants more detail on how a public method works.
A maintainer who wants to find the relevant method to make a small change.
A more serious maintainer who wants to do a significant refactoring or add functionality.
For clients perusing the source code, you want to introduce core concepts. First we have a class doc comment that includes a glossary of important terms and usage examples. Then we have the code related to one term, then those related to another, then those related to a third.
For maintainers, any pair of methods that are likely to have to change together should be close by. A public method and its private helper and any constants related to it only should show up together.
Both of these groups of users are aided by grouping class members into logical sections which are separately documented.
For example, a collection class might have several mostly orthogonal concerns that can't easily be broken out into separate classes but which can be broken into separate sections.
Mutators
Accessors
Iteration
Serializing and toString
Equality, comparability, hashing
Well, naming your methods so that they'll be easier to spot in your IDE is really not good. Their name should reflect what they do, nothing more.
As an answer to your question, probably the best thing to do is to split you class into multiple classes and isolate groups of methods that have something in common in each of such classes. For example , if you have
public void largeMethodThatDoesSomething() {
//do A
//do B
//do C
}
which then you've refactored such that:
public void largeMethodThatDoesSomething() {
doA();
doB();
doC();
}
private void doA() {};
private void doB() {};
private void doC() {};
you can make a class called SomethingDoer where you place all these 4 metods and then use an instance of that class in your original class.
Don't worry about physically ordering your methods inside the class, if you can't see it just use Ctrl-O and start typing the method name and you will jump straight to it.
Having self-describing method names results in more maintainable code than artificially naming them to keep them in alphabetical order.
Hint: learn your shortcut keys and you will improve your productivity
Organizing the way you described sounds better than 99% of the Java code I have seen so far. However, on the other side, please make sure your classes don't grow too much and methods are not huge.
Classes should usually be less than 1000 lines and methods less than 150.
I am designing a java API(not an API exactly) in my office which will contain 4000+ constants. So all the teams can use them directly. Initially i thought to create their classes according to their type and create their static objects into a separate class. So anybody any use them directly.
But after reading need of static variable, i afraid it could be a problem of creating so many static variables. Is there any alternate?
*After me whoever will join this project can also add a constraint in my Constant class without caring of performance. There is a possibility that many of the constants will be used rarely.
*Every member of Constant class will represent a class which will have its own behavior. It might be the part of some inheritance tree further. So using enum might not be a good idea.
You want to create a location where some 4000+ constants will live. there's the possibility that users of this class may add constants (possibly at runtime)?. T
Concern about the memory issues of statics is misplaced. If you need 4000 values, they're going to have to live somewhere, right?
If people will be adding values at runtime, this sounds like a singleton Map or Properties (which is really just a kind of map anyway) of some kinds. People often use dependency injection frameworks like Spring or Guice to manage this sort of thing.
If you just mean adding compile constants, you can make them all static. You'd probably want to make them static final as well, they'll be compiled inline.
It's very likely that 4000 constants is a very bad idea. Where I've seen systems with large numbers of constants (>100, even) defined in one place, what usually happens is that people forget the definitions of them and end up using their own variants , which sort of defeats the purpose (for example, I've worked on a system with 100's of SQL queries defined in a "Queries" class. Of course people immediately ignore it as it's more of a bother to look up if the exact query you need is in there than to roll your own. The class eventually grew to something like 1500 queries, many exact duplicates and many unused, most used once. Utterly pointless). I can imagine exceptions where you wouldn't "lose" things with naming conventions, but unless you've got a use case like that this seems like a really bad idea.
Breaking out your constants into enums gives you type-safe references. It also makes things conceptually easier to deal with. Compare:
-
public class Constants {
String WORK_ADDRESS;
String WORK_PHONE;
String HOME_ADDRESS;
String HOME_PHONE;
}
with
public enum ADRESS{ WORK, HOME }
public enum PHONE { WORK, PHONE }
Which would you rather work with?
Performance is highly unlikely to be the problem with this design. RAM is cheap. (Cue the usual quote: Premature optimization is the root of all evil.)
On the other hand, I'm not quite sure how any client developer can remember and use 4000+ constants. Can you give us an idea what sort of object this is?
You may, depending on details you haven't given us, find it useful to collect constants into enums. Stateless enums can be easier to understand than public static final variables if there are some natural groupings you can take advantage of.
What happens when you allocate in static is that it surely won't be freed in the runtime of your app.
so what ?
if you don't create them static then they'll be duplicated through every instance of your classes.
what you don't want to do is to set static huge amounts of data such as images or GUI
an image takes up a lot more than a few fields;
4000 constants of surely int (4 octet) = 16000 octets not even the size of an icon ^^
I would point out hte Javadoc to prove my point
http://download.oracle.com/javase/1.4.2/docs/api/constant-values.html#java.awt.event.KeyEvent.CHAR_UNDEFINED
this is the KeyEvent decleration in Java, check the out declarations ^^
Unless you are creating large arrays or very long strings, 4000 data values isn't going to be a lot of memory. I think that post you cited was talking about much larger amounts of data.
Another approach is to read the values from a preferences file.
Perhaps the constants be modularized into a collection of classes, so the more rarely used ones will be loaded only on demand.