Java OO Design help - how to abstract out a save method? - java

I have a Preference class (module) that's used across several different apps. Basically it's a cache of the preferences so that the systems don't have to call the backend all the time. It's similar to a cache but with some additional niceties such as isPreferenceSelected, has some helper methods, etc.
The issue is that I'd like to include a savePreference within the class so that whoever uses it can just override that method, be it to a database, to a flat file, etc. The key is that this module just doesn't want to care. The issue is that it's not an abstract class so I can't override the static methods and even if it was, I don't want to create a million instances because I don't want to load the preferences each time. And I can't create a abstract singleton either.
Therefore I'm not sure what to do. Here is a code snippet of what I'd like to do with comments:
// Please ignore the missing Generics, etc.
public class Preference
{
private static HashMap preferences = new HashMap();
public static ...
// Some preferences are objects, such as images, etc.
public static setPreference(String name, Object value)
{
.. some helper code
preferences.put(name, value); // ignoring issues with if it already exists ;)
savePreference(name, value); // saves to database, flatfile, etc.
}
}
That was the core class/code that the different systems leverage. Now what I'd like to do is say in a webapp, a desktop app, etc., be able to use this class in my code such as:
public someFunction(...)
{
.. do some cool code
Preference.savePreference("logoImage", image);
}
And have the savePreference() method not just save the in-memory preferences, but also save it to the external source. Otherwise everywhere I have savePreference() I have to follow it by a db call savePreferenceToDB(), a FlatFile call such as savePreferenceToFlatFile(), and so on. This is very error prone, someone somewhere will forget to save it. Plus it really makes no sense to sprinkle the save to permanent storage code everywhere with this type of code when it should really only be done once. Also remember that the main module has no idea if the permanent storage is a database, an xml file, a flat file, etc.
Hint: If I did Preference.getInstance().savePreference() that wouldn't work because you can't abstract a singleton. And I can't create a static method savePreference() because it's not possible to override a static method.
The only options I can see is to create some kind of complex Factory pattern, but that seems like a lot of overkill to me. Therefore any suggestions would be greatly appreciated.

This sounds like something that your dependency injection (DI) container should be handling, not a complex factory pattern.
That is, I think you should ditch the usages of static, have whatever creates the other applications inject an instance of Preference into your applications. You can do this without a DI framework if you just take the Preference as a parameter in your constructor for whatever other classes depend on it.
Edit: Let me give you an example of dependency injection without a framework. Take the following set of classes:
public class Preference
{
private String userName;
public Preference(String userName)
{
this.userName = userName;
}
public void savePreference()
{
// Default implementation saves it to the screen. ;-)
System.out.println(userName);
}
}
public class Foo
{
private Preference p;
public Foo(Preference p)
{
this.p = p;
}
}
public class Bar
{
private Preference p;
public Bar(Preference p)
{
this.p = p;
}
}
public class Main
{
public static void main(String[] args)
{
Preference p = new Preference("Mike");
Foo f = new Foo(p);
Bar b = new Bar(p);
}
}
This is a simplistic example, but it satisfies your requirements:
The Preference instance is only created once
The Preference class can be extended by whoever implements the Main class to instantiate whatever kind of Preference subclass they want to, if they wanted to persist it in a relational database (or whatever)
By avoiding having static calls in the first place you also make it possible for your someFunction() example to be unit tested without pulling in a potentially big, complicated preferences framework. Rather, someone implements a mock Preference subclass and passes it into the class that runs someFunction(). Your code will be much more testable that way.

#Mike says:
... I think you should ditch the usages of static
#Stephane responds:
... what is the major issue with static methods?
It is not just static methods. It is also the singleton instance.
Basically, they are inflexible:
They make it difficult to do things in alternative ways, as illustrated by your problem. If you didn't use a static method and a private singleton instance, you could create a Preferences interface and/or abstract base class, together with implementations that load and save the in-memory preferences in different ways.
Static instances tend to make testing harder. For instance, if you had a preferences UI that made use of your Preferences class, you couldn't unit test the UI classes using a "mock" version of Preferences. (Or at least, it would be a lot harder to do.)
Statics tend to make it difficult to reuse your code because of the hard dependencies on specific named classes and specific implementations.
Statics are non-OO. This is not intrinsically a bad thing, but it does mean that you can't make use of the nice properties of OO ... like overriding and polymorphism ... when you use statics.
If you have a significant number of these static methods / static objects in your application, a DI framework is a good solution. But as #Mike says, using Factory methods and passing objects in constructors will work just as well in many cases.
You commented:
One of the reasons I have it as a static class is because the preferences are loaded at startup. After that they stay in memory in the one static object. With DI, each time I create the object, I'd have to reload the information into memory from the data source. This defeats the whole purposes of having a Preferences Object (that pretty much acts like a cache with benefits).
This does not require you to use a static instance.
With DI (or explicitly wiring instances via constructors), you don't create the Preferences object more than once. You create it once, and then inject it as many times as required.
There is a halfway between your current approach with a static method that wraps a static instance of a hard-wired class and full DI. That is a what can best be described as a static holder; e.g.
public interface Preferences {
// Preferences API
}
public abstract class PreferencesBase implements Preferences {
// Implement as much if the API as makes sense
}
public class FileBackedPreferences extends PreferencesBase {
// Implement (protected) persistence methods.
}
public class DatabaseBackedPreferences extends PreferencesBase {
// Implement (protected) persistence methods.
}
public class ApplicationPreferences {
private static Preferences instance;
private ApplicationPreferences() { }
public Preferences getInstance() { return instance; }
// Call this once during application startup with the
// Preferences instance to be used by the application.
public void initPreferences(Preferences instance) {
if (this.instance != null) {
throw new IllegalStateException(...);
}
this.instance = instance;
}
}

I think it might take some rework of your design (unfortunately, I don't have a decent whiteboard in my apartment yet, so I can't easily sketch things out to conform), but I immediately thought Strategy pattern as soon as you said this:
The issue is that I'd like to include a savePreference within the class so that whoever uses it can just override that method, be it to a database, to a flat file, etc. The key is that this module just doesn't want to care.
You might have an abstract Preferences class that has every method but saving (and loading) implemented. In the sense of the pattern, this would be the Strategy interface. Your different types of saving and loading would be handled by the concrete implementations.

Create an interface for your preference manipulation class:
public interface PreferenceHandler {
void savePreference();
void readPreference();
}
Pass an instance of type PreferenceHandler to your class with all the static methods.
Invoke the methods on that class within your class.
Though, not lovin' all those static methods. It's probably why you're having so many issues here. Create a factory that gives you a copy of the class if you don't want to be creating lots of copies of it. But static methods really impede code re-use and extension. Or perhaps use a framework like Spring to manage classes of this sort.

Related

Is using a Singleton pattern good for large Generic classes in Java?

I'm new to Generics and the Singleton pattern in Java. I have the following questions:
Is a Generic class compatible with the Singleton Pattern, namely having a static instance?
If so, I have the following Generic class that I want to convert to a Singleton. What is the best practice?
(Beginner question) Is there a good way to de-generify an instance of the class in runtime? passing the class as parameter in getInstance()?
class GenFooSingleton <T>
{
private T t;
// Prevent direct instantiation
private GenFooSingleton(T o){
this.t = o;
}
private static GenFooSingleton INSTANCE = null;
// Returns the single instance of this class, creating it if necessary
static synchronized <T> GenFooSingleton<T> getInstance(T tClass)
{
if (INSTANCE == null)
{
INSTANCE = new GenFooSingleton<>(tClass);
}
return INSTANCE;
}
}
Edit
My use case of a Generic with Singleton:
1. Why Generic?
First let's say I have the the following Singleton Repository for one type of data to begin with, the following example is from what I learned in the googlesamples/android-architecture
class FooRepository implements FooDatasource
{
private final FooDatasource local;
private final FooDatasource remote;
Map<String, Foo> mCahcedItems;
// Prevent direct instantiation
private FooRepository(FooDatasource remote, FooDatasource local){
this.remote = remote;
this.local = local;
}
private static FooRepository INSTANCE = null;
// Returns the single instance of this class, creating it if necessary
public static synchronized FooRepository getInstance(FooDatasource remote, FooDatasource local)
{
if (INSTANCE == null)
{
new FooRepository(remote,local);
}
return INSTANCE;
}
// implement CRUD methods
#Override
public Flowable<List<Foo>> getFoos(){
// Update the mCahcedItems with the list of Foos
// return a list of Foos and syncing between the local and remote datasources...For brevity the bunch of Rxjava implementation is omitted.
}
#Override
public Flowable<Optional<Foo>> getFoo(){
// Update the mCahcedItems with Foo
//...
}
}
But I can see I would have to create repository for each data type. (Foo, Baa, Daa, etc) where the CURD logic is essentially the same and each instance. So naturally I'm thinking of making the repository a Generic one.
2. Why Singleton?
Without using the Singleton pattern, each new instance would start a complete new reload the in-memory cache, which means new local database queries. In developing for mobile and memory constrained devices (Android Apps), that would amount to unnecessary and I/O calls each time the device changes configuration/rotation. The mere thought of that just flags a huge performance problem that I would have to deal with. Therefore, I think A globally accessible single instance that is only lazily instantiated is a plus.
My attempt
So I set out to create generic versions of both the Repository and Datasource interface, and have each data type provide the concrete implementation when they implement the Datasource interface, like below:
class FooDatasource implements GenericDatasource<Foo>
{
//...
}
class BarDatasource implements GenericDatasource<Bar>
{
//...and so on and so forth
}
Update
My current approach is a singleton pattern with Generic instances can be better managed with Dependency injection using Dagger 2, for both Java and specifically Android dev.
Is a Generic class compatible with the Singleton Pattern, namely having a static instance?
No, it won't work like that, static fields exist only once, static inheritance doesn't exist in Java. But there are many different ways to implement a singleton.
If so, I have the following Generic class that I want to convert to a Singleton. What is the best practice?
Don't do it. Singleton is an antipattern, mainly because it's horrible for testing purposes. Instead, use a container (Spring, Guice, EJB etc.) to manage singletons for you, making sure only one instance exists. Start by reading about the Dependency Inversion Principle and Inversion of Control.
(Beginner question) Is there a good way to de-generify an instance of the class in runtime? passing the class as parameter in getInstance()?
Yes, passing the class to getInstance would actually make this a bit nicer, especially if you use a class-to-instance-Map internally (Guava has such a type)
Since the singleton pattern tries to guarantee only one living instance of a given class at any time, it's not very compatible with the idea of a versatile class that can accept or produce different results depending on its current generic type. For generics to be any useful, you need to be able to create different flavors of the same type (usual exemple: a List of String and a List of Integer)
N/A
If you are passing a parameter to the getInstance of a singleton, then you are not really wanting a singleton but a factory. A singleton can only be non parameterized, or else the first call freezes the context.
Do not abuse of singleton. They are the first pattern you may try to implement, because it's the first in every book, but it's almost always at least useless, at most a performance bottleneck and a bad design decision (not very OO)
EDIT:
you assumption that each new instance couldn't share the same cache is basically wrong, for two reasons:
not using a Singleton does not forces you to use several instances of the same type. It just allows you to do so, as well as enabling inheritance (which the singleton simply cann't). If you use Spring and a singleton-scoped bean (the default), then your repository exists only once in memory - even if it does not implement the singleton pattern as described in the books - and is shared between all consummers (thus only one cache). This can be accomplished without spring too, just use some kind of factory or registry.
caching with an hashmap in your class is a bit fishy, too. Caching is an implementation detail and you should not try to implement it in this way (you will end up eating the whole memory quite easily, at least, use WeakHashMap instead - or the Guava version, using CacheBuilder). You could also declare your cache as static so it will only exist once in memory. Modern applications treat caching as an aspect, like transactions for example. It should not leak to your code. For example, look at ehcache, redis, terracotta, etc. they all implement the JSR-107 and are configured directly on your method prototype, with some annotation (#Cacheable, etc.). Ho and caching usually goes to the service layer - you do not cache the state of the db, you cache the responses sent to the users after processing of the business logic (even if this rule is not absolutely strict)
The singleton also has a very big problem: it is directly responsible to instantiate the object, that is, direct use of the new keyword. This is a pain, as you can not change the concret type of the implementation at runtime (for testing purpose, or any other use). Look at the factory/factory method pattern to see a better way to change the type at runtime.
What you can do is having an abstract base class, generified, that your concret dao will extend (but those will not be generic). Something like this:
abstract class AbstractDao<ID, T> {
private Class type;
protected AbstractDao(Class type) {
this.type = type;
}
void save(T entity) {
// save an entity
}
T get(ID pkey) { /* get an entity */}
...
}
public class DaoX extends AbstractDao<Long, X> {
DaoX() {
super(X.class)
}
/* Empty! or only methods applicable for X */
}
public class DaoY extends AbstractDao<Integer, Y> {
DaoY() {
super(Y.class)
}
/* Empty! or only methods applicable for Y */
}
In this case you are not duplicating any code.

Using multiple classes without creating objects of each

I am new to java and stackoverflow
I have
class Assemble()
class Start()
class Ignite()
class Move()
...... There are still 12 classes
I want use methods inside these classes
but
i should not create objects of them
i cannot use extends for all these also
i there any way possible?
Please bare anything silly, i am not able to figure out.
And this is my first question hear.
the finaly class is
class run
{
public void run_simple()
{
// hear i should be able to access all methods of above class
}
}
If you use an object oriented language (as java) the way it is meant, your whole program is about creating and using objects (as mentioned in many comments). There are some valid technical reasons not to create objects and to use static methods ("it's tedious" is not one of them). There are environments that forbid to use inheritance.
Please state these reasons, otherwise we have to assume that you don't understand some basic concepts of object oriented languages and that your "restrictions" must be ignored.
Most "restrictions" of object oriented programming are intended to help you structure your solution/program. If you see them as real restrictions, the structure of your program might very well be bad.
I'd like to give an example on how something like this might look "the OO way". This might not fully match your project, but should show you that creating objects must not be an issue programmer effort wise.
First we need an interface that defines what one of your actions (thats what I call your classes) looks like
interface Action {
public void run();
}
The following classes define the concrete actions. Their constructors might take parameters configuring details on how to execute them. In the run()-method of each class, you program on what an action does when executed.
class Assemble implements Action {
public void run() {...}
}
class Start implements Action {...}
class Ignite implements Action {...}
class Move implements Action {...}
The controller does the "run everything". That's basically your "overhead" for creating objects!
class Controller {
/** Returns a list of the configured action objects. */
public static List<Action> buildActions() {
List<Action> actions = new LinkedList<Action>();
actions.add(new Assemble(parameter)); // or whathever parameters you need
actions.add(new Start(parameter1, parameter2));
actions.add(new Ignite());
actions.add(new Move());
}
/** Build the list of actions and run one after the other. */
public static void main(String[] args) {
List<Action> actions = buildActions();
for (Action action: actions) {
action.run();
// here you could add logging, profiling etc. per Action.
}
}
}

Java - best practice for creating package-wide or global variables

What is the standard approach/best practice to creating variables that are program- or package-wide in Java?
I want to set up some global variables that are accessible by multiple classes. Examples of these global variables would be things like a boolean flag testModeOn, a language setting, current local server, time display format, etc. According to some other questions (namely this one) there aren't any global variables, but there are some work-arounds using interfaces (not recommended?) or classes. Since the original poster didn't explain their situation, they got nearly every answer under the sun and I want to ask specifically for program configuration variables.
Is it better to create a class/package/interface and then import it into my working class/package? Is there anything I should be aware of when trying to implement these variables using a separate class or interface? Is there any other way to fudge package-level variables since Java apparently doesn't do this natively?
NOTE: These variables would probably not change except when the program is re-compiled.
If you're talking about constants, then they should be declared as static final fields in a class (never in an interface, according to Joshua Bloch).
If you're talking about settings which can change on the fly, then these could be either static fields in a class, or you could create a ConfigHandler class to manage the setting and fetching of configurable values.
Using class fields for mutable values might lead to concurrency problems, so if your application is multi-threaded it might be better to create a ConfigHandler class which manages concurrent access carefully and provides synchronized methods to avoid problems.
In my opinion, the best approach to passing anything into your classes is using dependency injection. This would eliminate your need for Singletons, static constants and the likes.
Depending on which DI you favor, here are some link solutions to the problem you describe:
CDI
Spring
Guice
Create a Bean class if multiple variables are required to be used in different classes. Best practice is to create a private variable with its getters and setters.
public class ListBean implements Serializable
{
private boolean testModeOn;
public boolean getTestModeOn()
{
return testModeOn;
}
public setTestModeOn(boolean testModeOn)
{
this.testModeOn = testModeOn;
}
In general there are so many ways to do it wrong regarding this topic.
The simple way is to use a Singelton.
This is not an option - Singelton is an Anti-Pattern. http://c2.com/cgi/wiki?SingletonsAreEvil
So what is else there? An Interface with public static final variables?
Not an option - Thats simply not the use case of an interface: https://stackoverflow.com/a/2659740/1248724
so what is else there?
The answer is:
What I prefer is the spring boot way (e.g. Dependency Injection)
Here an code example which is obviously Spring.
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
#Component
public class MyBean {
#Value("${name}")
private String name;
// ...
}
If you are using some similar Framework such things could be easy archived.
If that is somehow not possible in your environment I had to code something like this:
public final class Configuration {
private Configuration() {
// make sure there is no instance of this class
}
public static final MySetting<DateFormat> setting = new SampleProperty();
public interface MySetting<T> {
T get();
}
private static final class SampleProperty implements MySetting<DateFormat> {
#Override
public DateFormat get() {
return new SimpleDateFormat("...");
}
}
// other inner classes that implement the MySetting interface
}
public static void main(final String[] args) {
Configuration.setting.get();
}
Benefits:
- You can validate your properties how ever you want.
- You can work with the java security manager if you like to
Downsides:
- You may have to maintain a bunch of code (this should be easier with lambda expressions)
- Not that great as the way spring offers here for example.
A very similar approach I just found: https://stackoverflow.com/a/3931399/1248724

Shall we avoid writing static methods in our java code for better testability?

I was prefer using static methods in my java code, since I think they are "functional""stateless" and has less side-effect. So there may be some helper classes and methods like this:
public class MyHelper {
public static Set<String> array2set(String[] items) { ... }
public static List<String> array2list(String[] items) { ...}
public static String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = MyHelper.array2set(myarray);
String content = MyHelper.getContentOfUrl("http://google.com");
}
}
But my friend says we should avoid defining such static utility methods, since we call them directly in our code, it will be hard to mock them or test them if they have external dependencies. He thinks the code should be:
public class ArrayHelper {
public Set<String> array2set(String[] items) { ... }
public List<String> array2list(String[] items) { ...}
}
public class UrlHelper {
public String getContentOfUrl(String url) {
// visit the url, and return the content of response
}
}
public class MyApp {
private final ArrayHelper arrayHelper;
private final UrlHelper urlHelper;
public MyApp(ArrayHelper arrayHelper, UrlHelper urlHelper) {
this.arrayHelper = arrayHelper;
this.urlHelper = urlHelper;
}
public void doSomething() {
String[] myarray = new String[]{ "aa","bb"};
Set<String> set = arrayHelper.array2set(myarray);
String content = urlHelper.getContentOfUrl("http://google.com");
}
}
In this way, if we want to write unit tests for MyApp, we can just mock the ArrayHelper and UrlHelper and pass them to the constructor of MyApp.
I agree totally about the UrlHelper part of his opinion, since the origin static code make MyApp untestable.
But I have a little confused about the ArrayHelper part, since it doesn't depend on any external resources and the logic will be very simple. Shall we avoid using static methods at this case too?
And when to use static methods? Or just avoid using it as much as possible?
update:
We are using "TDD" in our development, so the testability of a class often is the most important concern for us.
And I just replace the word "functional" with "stateless" in the first sentence since the that's real what I meant.
You'll probably never want to mock a method that converts an array to a list (or set), and this method doesn't need any state and doesn't depend on any environment, so a static method looks fine to me.
Just like the standard Arrays.asList() (which you should probably use).
On the other hand, accessing an external URL is typically the sort of thing that you want to be able to mock easily, because not mocking it would
make the test an integration test
require to have this external URL up every time you run your tests, which you probably can't guarantee
require to have this external URL return exactly what you want it to return in your test (including errors if you want to test the event of an error).
Just beware of one disease very common amongst Java "experts": overengineering.
In your specific example, you either do or don't have a mockability issue. If you had an issue, you wouldn't be asking general questions, therefore I conclude you don't have an issue at the moment.
The general argument is that static methods are simpler and therefore the preferred choice, whenever there is a choice. A would-be instance method must first prove itself of needing to be an instance method.
If this was my project, I would defer any makeovers into instance methods until such a moment where the need for that became clear and present.
Static means you can call the method without instantiating the class. Its good if you want to package your code into a class and you have a function that just does some logic or something basic.
Just don't use a static function to try and edit member variables in the class (obviously).
Personally I think its fine to use the static function, since it is stateless.
Static methods should be used by answering the question "is this method a functionality of a specific instance?".
You shouldn't decide about a static method according to tests, you should do it according to design. Your examples doesn't need an instance because it makes no sense. So static is the better choice. You can always wrap these methods inside specific tester classes to do your tests.
The only situation in which a self-contained functionality is not static is just when you want to provide multiple implementation, so that you are forced to avoid static because you need inheritance.
I often use static methods:
for factory methods (explicitly named constructors)
to provide a functional layer above an object-oriented layer, to compose the objects
and sometimes for general-purpose functions (Apache Commons has many good examples of this)
I never use "singletons" (static objects) and methods that refer to static objects because they are a complete headache to test and reuse. I also avoid hardcoding anything into a static method that could feasibly need to be changed. Sometimes I will provide multiple methods - one with all the dependencies as parameters and others, with fewer parameters, that call the more flexible method with some default (hardcoded) values.
java.lang.Math is static which is a good example. I thought statics are not beeing garbage collected and should be avoided if possible.
No.
As mentioned by Peter Lawrey in the comment for the question, Java is all about object oriented programming. While certain functional aspects are doable and being put into eg. Java 8, at its core Java is not functional. static breaks so much of the benefits of learning how to do modern Java - not to mention all kinds of not-fun-at-all scoping problems - that there's no purpose to use them unless you're some kind of a Java wizard who really knows what happens when you use that magical keyword.
You are not a wizard. Java is not functional. If you want to be a wizard, you can learn. If you want to program in functional fashion, look into hybrid languages such as Scala or Groovy or alternatively explore the fully functional world, eg. Clojure.

Java - Encapsulate fields into different file... (with IDE)

I would like to encapsulate my fields (variables), into a different file. Like getting out the logic of my application into a different file (logic.java ?), where every class could access the variables that should be "global".
Netbeans is capable of doing encapsulation, but it will just put a list of setter/getter functions into the same file.
(Later, I would like to call the functions with Logic lo = new Logic();, and lo.getValue(), for example.)
If there is a better way of doing this, please enlighten me, and I'll delete the question. (The classes are in different package. app.logic; app.desk; app.net, etc.)
What you want here are advanced refactoring capabilities, and for that I'd suggest you take a look at IntelliJ IDEA (The community edition is free to use and download and is available for all platforms).
Take a look at it here.
I don't know if I understand correctly but what you can do is implement a singleton class:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
// members, getters and setters
}
Now this guarantees that you only have one instance of Singleton in your entire application that can be obtained anywhere with Singleton.getInstance().

Categories