Java instancing classes to allow dynamic fields - java

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

Related

Is it possible to call diffrent instances from static util

Update: I rewrite my question with more details.
Class Disk is a third party with long init time so I want to create it only once as a static member. Since I can't change it I want to wrap it with my own logic as a utility class.
Lets say I have created utilities:
class DiskUtilC {
static Disk disk = new Disk("c:\\");
List static searchFile(String name) {
return soSomething(disk.search(name));
}
...many more static methods ...
}
class DiskUtilD {
static Disk disk = new Disk("d:\\");
List static searchFile(String name) {
return soSomething(disk.search(name));
}
...many more static methods ...
}
Since both classes use the same static method I want move them all to a common location but keep the same usage i.e.
DiskUtilC.searchFile("xxx");
DiskUtilD.searchFile("xxx");
It's not possible to use polymorphism with static I'm not sure if it is possible.
I know that I can always do something like this DiskUtil.getInstance("c").searchFile("xxx") but it's too cumbersome. Is there a way to do it like I demonstrated above?
There isn't any benefit to defining two classes DiskUtilC and DiskUtilD with identical code and different static fields - one may edited out of step with the other.
If the handling logic for C+D drives is identical (that is they don't need different soSomething implementations) you could declare one DiskUtil class with 2 static fields for C and D drives and instance methods such as getName / searchFile. Example:
class DiskUtil {
static final DiskUtil C = new DiskUtil("c:\\");
static final DiskUtil D = new DiskUtil("d:\\");
private final Disk disk;
private DiskUtil(String root) {
disk = new Disk(root)
}
void getName() {
return disk.name();
}
List searchFile(String name) {
return soSomething(disk.search(name));
}
...many more... (not-static methods)
}
Then the usage is via DiskUtil:
DiskUtil.C.searchFile("xxx");
DiskUtil.D.searchFile("xxx");
But it's probably better to use DiskUtil.getInstance("c") or similar so you can make getInstance initialise any drives as necessary on demand on first use rather than hardwire C/D only. An example on demand load can also setup say C() to simplify typing:
private static final ConcurrentHashMap<String,DiskUtil> DISKS = new ConcurrentHashMap<>();
private static DiskUtil getInstance(String drive) {
return DISKS.computeIfAbsent(drive.toLowerCase(), letter -> new DiskUtil(letter+":\\"));
}
// Handy access to C:
static DiskUtil C() { return getInstance("C"); }

OO design vs static classes in java and concurrency exploitation

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

Where should I store lists or maps of objects

In my project I have several objects like layouts, groups, boxes and many others. These objects need to be stored in a list or map with methods to get, remove and put them into the collection. I am currently using static methods and variables in the associated class, for example I have:
public class Layout {
private static Map<String, Layout> layouts = new HashMap<String, Layout>();
/*
Other, non-static variables
*/
public static void addLayout(String name, Layout layout) {
layouts.put(name, layout);
}
public static Layout getLayout(String name) {
return layouts.get(name);
}
public static void removeLayout(String name) {
layouts.remove(name);
}
/*
Non-static methods for layout
*/
}
Would it be better to have a separate class that holds the collection of each kind of object or a single class to hold collections of all the objects? If so, what kinds of names would you use for these classes?
The good point of your solution is that you have all belonging to Layout in one class, no more dependencies needed. But using static methods will make it hard to test implementations using that static methods. I won't use one class to hold all, that would create a dependency magnet.
A better approach may be to create repositories for each of the classes like LayoutRepository for storing and retrieving Layouts. Best to use with dependency injection implemented by a container like Spring if your application becomes bigger.
The most simple would be a generic implementation:
public class Repository<E> {
private final ConcurrentMap<String,E> elements = new ConcurrentHashMap<>();
public void add(String name, E element) {
elements.put(name, element);
}
public E get(String name) {
return elements.get(name);
}
public void remove(String name) {
elements.remove(name);
}
}
So you have the implementation of the repository separated from the class to store. You can simply reimplement the functionality using a file or database without touching the code using it.
For unit tests you can simply mock the repository to make sure it is used right.
If the creation of the class e.g. Layout have to ensure a valid state, a builder would be a good improvement. Another option is to use a factory to have control over creation of instances. Both should be placed in the same package as the element class and the constructor than must no longer be public.

java separate file for global variables

I have a newbie question. If I have some global variables that are shared by two classes or more how can I have them in a separate file so that any class can read and update them. Is this possible without using Interfaces?
Yes, since interfaces variables are all implicitly static, so each of these variables has only one instance in the jvm.
However, a better way to do it [in my opinion] would probably be having them declared in some singleton class and using it.
The best way to do this is to have your shared application state accessible via interface methods, then have an implementing class that holds the variables, and pass this instance of the class to your other classes during construction (which they accept as an instance of the interface).
This is better than using a static class or singleton since it allows you to mock out the functionality of the shared state for testing, improves general code reusability, and allows you to change the implementation and configuration of the shared state without impacting any of the code using it.
E.g.
// Session interface for all application shared state.
public interface ApplicationSession
{
public int getMaxUserLimit();
}
// A backing for the interface (simple in memory version, maybe future versions use a database, who knows).
public class SomeApplicationSession implements ApplicationSession
{
private volatile int maxUserLimit = 0;
public void setMaxUserLimit(int limit) { this.maxUserLimit = limit; }
public int getMaxUserLimit() { return maxUserLimit; }
}
// ClassA uses the supplied session.
public class MyClassA
{
private ApplicationSession session;
public myClassA(ApplicationSession session)
{
this.session = session;
}
}
// usage...
public class MyMain
{
public static void main(String[] args)
{
// Create / get session (ultimately possibly from a factory).
ApplicationSession session = new SomeApplicationSession();
ClassA myClassA = new ClassA(session);
// do stuff..
}
}

Is a public setter necessary for private static variable?

/* 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.

Categories