I have 7-8 callable classes which makes use of some similar functionality and also read on some same list and HashMap.
So I created a static class containing all the functionality as static functions and static list and hashMap.
Now, I have some queries :
1.) Is it a wrong practice to have static classes in java as my senior scold me over using a static class and rather asked me to convert it into a singleton class.
But static classes are faster than singleton. Isn't it ?
2.) Is it a bad design to have a reference to a static/non-static method to obtain some data like a list inside a call method (in a thread) or to perform some task?
Does it violate thread safety or parallelism as my senior said ? And ask me to have the list inside the thread class as private member.
But isn't that bad use of memory as other 6-7 thread classes makes use of the same list to read only.
3.) How can I improve the OO design with improvement in performance as well.
A sample code would look like this :
public class StaticClass {
private static List<String> ListOne;
private static List<String> listTwo;
private static HashMap<String, String> hMap;
static{
//initialize list and maps by reading from file
}
public static List<String> getListOne() {
return ListOne;
}
public static List<String> getListTwo() {
return listTwo;
}
public static HashMap<String, String> gethMap() {
return hMap;
}
public static void commonMethodOne(){
}
public static String commonMethodTwo(){
}
public static String[] commonMethodThree(){
}
}
public class CallableThread implements Callable<String>{
public String call(){
HashMap<String, String> mapTask = StaticClass.gethMap();
List<String> taskOne =StaticClass.getListOne();
for(String temp : taskOne){
//do what you are suppose to do
}
for(String key : mapTask.keySet()){
//do what you are supposed to do
}
return "Done with CallableThread";
}
}
A method like this is a terrible idea (poor naming and failure to follow the Java coding standards aside):
public static List<String> getListOne() {
return ListOne;
}
You return a mutable reference, so anyone who gets this List can modify its contents as they see fit. Private is no longer private.
If you must return a reference to a private List or data structure (no reason to do so that I can see), you should either make it immutable or return a copy.
public static List<String> getListOne() {
return Collections.unmodifiableList(ListOne);
}
You've got mutable shared data without any synchronization of any kind, so this class is not thread safe at all.
I think Singletons are far better than Static classes
Below is Answers to your question serially :
1) No , It totally depends upon your requirements but yes static classes are faster but also allows more bugs into your project
2) Yes sometimes as long as its not affecting your private data members and make your data insecure
3) Using Singletons as it provides more OO funtionalities and thus increase performance
Here is a great reference article for you :
http://javarevisited.blogspot.in/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
Related
I have been looking over some java projects and have seen this inconsistency between different developers/projects:
(PLEASE NOTE: For the below, only ONE Edibles will EVER exist, Edibles is NEVER required to have two active instances.)
Project 1:
public class Edibles1 {
private final HashMap<Integer, Food> edibleFoods = new HashMap<>();
private static final Edibles edibles = new Edibles();
public static Edibles getEdibles() {
return edibles;
}
//external usage for this project:
public static void main(String[] args) {
Food foodForId = Edibles.getEdibles().edibleFoods.get(123);
System.out.println(foodForId);
}
}
Project 2:
public class Edibles2 {
private static final HashMap<Integer, Food> edibleFoods = new HashMap<>();
//external usage for this project:
public static void main(String[] args) {
Food foodForId = Edibles.edibleFoods.get(123);
System.out.println(foodForId);
}
}
Please keep in mind that ONLY ONE Edibles#edibleFoods is EVER required by the project.
In the documentation, some developers who use edibles1 write that is it safer? Although maybe they just want to be consistent with their classes because even though only one Edibles is needed for the project, similar classes require multiple and therefore need example1.
So could it be that developers just want consistency or is there a deeper meaning/understanding?
Project 1 is (partially) implementing the Singleton design pattern. By partially I mean that it should have a private constructor so that other classes can access the singleton only through the static getEdibles() method.
The Singleton design pattern is needed only if other classes need to access the Singleton class and interact with it (get/set values, invoke methods etc)
project 2 does not implement the Singleton DP. the map is accessible only to methods of the class Edibles2
Why would you declare a static final variable as private for an immutable type?
Could it possibly do any harm to declare them public on any case?
So that nobody can access it from outside and rely on that value, giving you the freedom to change it without risk of side-effect (at least outside of the class where it's declared).
There are serveral reasons...
Privacy
Keep implementation details hidden from the clients, for example constants for internal use only and with no use for clients
Security
Protect your code from maliscious client codes for example:
static class A
{
public final static List<String> list = buildList();
public static List<String> buildList()
{
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList("A", "B", "C"));
return list;
}
}
static class B
{
public static void main(String[] args)
{
A.list.clear();
System.out.println(A.list);
}
}
You dont want any one to manipulate you internal data.
It's just best OOP practice to keep variables within the proper scope. An example would be a global static final integer for performing a number of calculations within the class. Having it exposed (public) not only could cause problems, but confusion as well.
Say you had a class where you needed to know the value of pi:
public class MyClass {
private static final double PI = 3.14159;
//functions performing calculations with value of PI
}
The value of pi is only needed within MyClass, so leaving it to be exposed makes no sense - all calculations with the variable are done within MyClass. If you need it again to perform a calculation, it should be done within the class holding the value to keep your code organized.
public class GUICommon {
private static final ExecutorService executorServices = Executors.newWorkStealingPool();
public static void useExecutors(Runnable run)
{
executorServices.execute(run);
}
}
I used it on this way.
There are 7-8 class (implements callable) which have some similar behaviour i.e. these have some similar functions with similar implementations. And also all of these makes use of a HashMap (only for reading purpose) which is same for all these classes.
So I decided to make a abstract superclass containing all the similar methods plus this hashMap as a static member.
And I will be making subclasses for these 7-8 callable classes (hence those will also be callable by inheritance), so that performance of app can be improved.
Now I have 3 queries :
1.) Is there any flaw in this design and can I even further improve it ?
2.) Can there occur any concurrency issues as it's a three level hierarchy with callable classes at bottom two levels?
3.) Is initializing static member(hashmap) inside static block wrong ? As my boss is obsessively against using static members and blocks. So what possible problems can occur if I initialize this map inside static block ?
public abstract class AbSuper {
private static HashMap hmap;
private static CompletionService<String> service;
private static int maxThreads = 10;
static{
initializeMap();
}
public static void initializeMap(){
//load from file
}
public HashMap getmap(){
return hmap;
}
public void commonMethodOne(){
//do something
}
public static CompletionService<String> getService(){
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
service = new ExecutorCompletionService<String>(executor);
return service;
}
}
public class CallableOne extends AbSuper implements Callable<String>{
private List<String[]> taskList;
protected HashMap resultMap;
public List<String[]> getTaskList(){
return taskList;
}
public String call(){
for(String[] task : getTaskList()){
getService().submit(new SubCallableOne(task));
}
return "done with Callable One";
}
}
public class SubCallableOne extends CallableOne {
String[] task;
public SubCallableOne(String[] task) {
this.task = task;
}
public String call(){
//do what you are suppose to do
//and then access and populate "resultMap" fom superclass
return "done with subCallableOne";
}
}
There will be 7-8 CallableOne/two/three and thier corresponding SubCallableOne/two/three.
1) Do you really need to use static members? If so, maybe you should encapsulate that in a separate class and use it through encapsulation instead of inheritance. I'd still keep a superclass with the common methods.
But in any case, your current code has issues. Namely:
You are exposing the map via the public method AbSuper.getMap and it is mutable. Any code could add, delete or overwrite entries. Should it really be public? It looks like only subclasses are using it. If so, you could make it protected and return them a read only map, or a copy, or create a protected function readFromMap(key) instead.
Same for the AbSuper.getService method: it is public and static. Any code in any class could submit tasks or shutdown it. Except that you are creating a new executor each time. This is probably a bug, as each call to getService will override the service variable. Looks like you were trying to implement a singleton here but failed.
2) Callable classes might be the ones at the bottom, but you are exposing functionality in the base class to every other class in your program due to public static methods, and to anyone holding an instance due to public methods. And even if these methods didn't exist, the fact that all your instances use a shared map and executor service could result in accidental side effects. Execution order of submitted tasks, for instance.
3) It is not wrong per se, but statics are well known code smells. It makes classes hard to test. And cannot be overriden. In pure OO design there should be no need for statics. In your case, the map will be initialized the first time the class is loaded, so any call to AbSuper.getMap will get the map populated. But there are two problems with your map. The first one is that this is usually no place for long operations like populating a map from file. You should make long operations explicit, don't hide them in constructors or static initializers. The second is that the map is mutable.
Edit: I am trying to create a shared database connection pool for all sessions of a web application. A different post said the best way to create a servlet context object was by having the init listener create it. I am however unclear on how to make this object available for use by my servlet.
Another way you could do this is use static initialization:
public class SomeClass {
private static final Object[] CONTENT;
static {
CONTENT = new Object[SomeOtherClass.getContentSize()]; // To show you can access runtime variables
}
}
This will initialize the CONTENT array once the class is loaded using the ClassLoader.
One solution is using a private holder class:
public class SomeClass {
private static class ResourceHolder {
private static final Resource INSTANCE = new Resource();
}
public static Resource getInstance() {
return ResourceHolder.INSTANCE;
}
}
the instance will be initialized when SomeClass.getInstance() is called the first time.
The simplest lazy initialisation is to use an enum with one instance.
enum Singleton {
INSTANCE; // lazy initialised
}
The added problem is you want initialisation values. To handle this you can nest the class.
enum Utility {;
static MyType val;
static OtherType val2;
enum Holder {
INSTANCE;
Holder() {
// uses val and val2
}
}
public static Holder getInstance(MyType val, OtherType val2) {
Utility.val = val;
Utility.val2 = val2;
return Holder.INSTANCE; // only created the first time.
}
}
Note: this is thread safe as static block initialisation is safe.
Something like:
public static abstract class Lazy<T> {
private T t = null;
public synchronized T get() {
if (t == null) {
t = create();
}
return t;
}
protected abstract T create();
}
public static final Lazy<List<String>> lazyList = new Lazy<List<String>>(){
#Override
protected List<String> create() {
return new ArrayList<String>();
}
};
I'll caution you up front, what you're describing has a bit of code smell, and I suspect you'll do better to avoid this pattern entirely. A static resource that depends on external runtime state breaks all sorts of best practices about variable scope.
What you're describing, however, would best be implemented by either a Supplier or a Future, depending on the work involved in successfully constructing the object you need. The difference is somewhat pedantic, but you'd generally use a Future to hold a reference that will take a long time to compute, while a Supplier generally returns quickly. Future also has some nice hook-ins with Java's concurrency utilities, but by the sound of it you don't need that.
You'd use a Supplier like so:
public class GlobalState {
public static final Supplier<LazyData> MY_DATA = Suppliers.memoize(
new Supplier<LazyData>() {
public LazyData get() {
// do whatever you need to construct your object, only gets executed once needed
}
});
...
}
Suppliers.memoize() will cache the result of the first call to the underlying Supplier in a threadsafe way, so simply wrapping the Supplier you define with this call prevents duplicate processing.
/* Atleast is it needed in this case?*/
public class Service
{
private static List<String> subscribedFields;
private static List<String> unsubscribedFields;
//---------------------------------
// is this necessary?
//---------------------------------
public static void setFields(List<String> subscribedFields, List<String> unsubscribedFields)
{
Service.subscribedFields = subscribedFields;
Service.unsubscribedFields = unsubscribedFields;
}
public static List<String> getSubscribedFields()
{
return subscribedFields;
}
public static List<String> getUnsubscribedFields()
{
return unsubscribedFields;
}
}
// some other class
public class User{
// Is this not enough to change the lists? Isn't the setter redundant?
Change(Service.getSubscribedFields());
Change(Service.getUnsubscribedFields());
}
No, a public setter is not always needed for a private variable. The idea of providing public setters (and getters, for that matter) is based on - what external entities such as classes need access to the insides of the particular piece of code you are writing. Getters and setters provide that public interface for that to happen. However, you don't necessarily NEED to provide a public getter or setter to every private variable you create as that private variable may only exist for internal, private use to the class.
You'll have to decide if you specifically need to give access to your private variables based on the particular needs of your code.
Update Based on ada's Question in Comments
You could give the user access to your lists directly (yes - they can use the getter and then edit the list). This may work if you trust the users of your code. However, for various reasons, you may not want to give them direct access to your list like that (especially because it gives them free reign to do what they want to do, it can create problems if you have threading within your application, etc). In that case, you should provide interfaces into the underlying list. For example, in your class, instead of providing a getSubscribedFields(), you may want to provide methods like:
// Pseudocode
public String getSubscribedField(int i) {
return subscribedFields.Get(i);
}
public String addSubscribedField(String field) {
subscribedFields.Add(field);
}
Hopefully that helps clarify things a bit for you.
The more popular choice in this case is to use a Singleton which you initialize once with the fields. However, not even Singleton is really a good idea, but to do otherwise requires that we know a bit more about what you're trying to do. In most cases you can get around using static instances by making it a member of a class with a long lifetime. For example, if these fields were related to database fields, you'd associate it with a table class which holds information pertaining to a database table for instance.
Really it depends on what you're trying to accomplish.
No you shouldn't. And even more you should avoid static state.
Your class seems to be very prone to thread safety problems. I also question the relevance of your need to put your List as static variables.
Another thing, your setter isn't in line with JavaBeans setters & getters standards, you might have problem if you want to integrate with some common frameworks.
I suggest you a variation of your class. I refactored it in order to keep the responsibility of the class is to hold the subscriptions.
If you use a dependency injection framework like Spring or Guice, you could simply make a class like this one, and inject it to the classes that need this object.
public class SubscriptionServiceUsingDependencyInjection {
private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();
public boolean isSubscribed(String field_) {
return subscribedFields.contains(field_);
}
public void subscribe(String field_) {
subscribedFields.add(field_);
}
}
Otherwise If you really need a Singleton, you may use an enum to achieve the same goal :
public enum SubscriptionServiceUsingASingleton {
INSTANCE;
private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();
public boolean isSubscribed(String field) {
return subscribedFields.contains(field);
}
public void subscribe(String field) {
subscribedFields.add(field);
}
}
The CopyOnWriteArraySet will prevent concurrency problem if you are running this in a multithreaded environment.