I got a class Config wich looks like that:
public Class Config {
public static int someIntValue = 0;
public static String someText = "some text";
}
What i want to do now is saving and loading that config and there is also that inital config if there is no need to load another. So the config can change at any point in the programm.
What i came up with was a Singelton like pattern
public Class Config {
public static Config instance;
private int someIntValue = 0;
private int String someText = "some text";
public static Config getInstance(){
if(instance == null)
instance = new Config();
return instance;
}
public void setInstance(Config config){
this.instance = config;
}
//getter/setter
...
}
But in the end it doesnt look like the best approach and im not quite happy with it :/
Maybe you guys can help me out with a usual / "best practice" way to do that.
Best Regards
Made
I would just use java.util.Properties, or some wrapper around it. Another good approach is java bean and something like xstream to save/load stuff.
Usually in Java for configuration use properties files. And then use ResuorseBundle for reading properties.
Your "singleton" is not a Singleton in the conventional sense.
1) Field instance must be private
2) Remove SetInstance method
3) And you should make your singleton thread safe.
If you'd consider avoiding writing the boilerplate code around java.util.Properties, you can have a look at something that does it for you: OWNER API.
It's configurable to tailor your needs and it offers some additional neat features if compared to java.util.Properties (read the docs).
Example. You define an interface with your configuration parameters:
public interface ServerConfig extends Config {
int port();
String hostname();
#DefaultValue("42")
int maxThreads();
#DefaultValue("1.0")
String version();
}
Then you use it like this:
public class MyApp {
private static ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
private MainWindow window;
public MyApp() {
// you can pass the cfg object as dependency, example:
window = new MainWindow(cfg);
}
public void start() {
window.show();
}
public static void main(String[] args) {
// you can use it directly, example:
System.out.println("MyApp version " + cfg.version() + " copyright (c) ACME corp.");
MyApp app = new MyApp();
app.start();
}
}
You can define the cfg object as member instance on the classes where you need, or you can pass the instance to constructors and methods where you need it.
Version 1.0.4 will be released soon and it will include also "hot reload" and many improvements.
Related
I decided to split the last part of that question here into a new question here: https://softwareengineering.stackexchange.com/questions/411738/extension-of-classes-where-to-put-behaviour-how-much-direct-access-is-allowe
If i have a lib and i want to use it, i wrote mostly a own class. This class has one method. In that there is the code how to instantiate the lib/framework. Sometimes there are a few more methods, with them i not only instantiate the class but use it. For example if i want to start a http-server i have there a start-method.
class Container
{
TheLib theLib;
public void init() //or a constructor
{
//some init of the theLib
}
public void start() //
{
theLib.doSomething(...)
theLib.doSomethingmore(...);
theLib.start(...);
}
//important!
public TheLib getTheLib()
{
return this.theLib; //after i started configured it and so on, i want of course use all methods,
which the lib have in some other parts in my application
}
}
But it seems not to be the best solution.
Are there any better solutions, that OO is?
Often i also use only one method, a own class for this seems to be here a big overhead?
Exposing the lib breaks encapsulation? Tell-Dont-Ask is also violated?
Everything depend on what you actually need or how you have access to your 'the lib' instance.
public class Container {
private TheLib theLib;
/* #1: Do you already created the instance before? */
public Container(TheLib theLib) {
this.theLib = theLib;
}
/* #2: Do you need to created the instance each time? */
public Container() {
this.theLib = new TheLib();
}
public void start() {
theLib.doSomething(...)
theLib.doSomethingmore(...);
theLib.start(...);
}
public TheLib getTheLib() {
return this.theLib;
}
public static void main(String[] args) {
/* #1 */
TheLib theLib = ...;
Container container = new Container(theLib);
/* #2 */
Container container = new Container();
/* Continue the flow of your program */
container.start();
container.getTheLib().doSomethingEvenMore();
}
}
Or maybe you actually need only one instance of your 'Container' class. In this case, you should look on how to make a singleton: Java Singleton and Synchronization
Anwser: Often i also use only one method, a own class for this seems to be here a big overhead?
Well, in Java, you cannot do formal programming like in C, so everything line of code that you write, or will be using, has to be in a class of some sort.
If your piece of code is small and don't really need an object, static function might do the work.
Hello i am trying to familiarize myself with Java by doing a very simple "bankaccount" application and it doesn't even save to db or something so it resets all data on rerun.
The problem i am trying to find a good way of doing is that i have an ArrayList of accounts that i want to be able to access from any class so that during runtime for example after an deposit if i access that account later when i want to get balance i get an that account from the ArrayList and it is updated to the deposit value.
When googling i found this solution but i dont like it since it uses static ArrayList. is there any more elegant way than this for an applicaiton that only saves the state/data during runtime.
Simple class that adds the test accounts and so on where first value is acountId and second is balance
public class AccountsModel {
private ArrayList<AccountModel> listOfAccounts;
public AccountsModel() {
listOfAccounts = new ArrayList<AccountModel>();
listOfAccounts.add(new AccountModel(1,0));
listOfAccounts.add(new AccountModel(2,0));
listOfAccounts.add(new AccountModel(3,0));
listOfAccounts.add(new AccountModel(4,0));
}
public ArrayList<AccountModel> getListOfAccounts(){
return listOfAccounts;
}
}
Then in my main class i just do this
static AccountsModel accounts = new AccountsModel();
public static ArrayList<AccountModel> listOfAccounts = accounts.getListOfAccounts();
this "works" as i can get the same list from anywhere within the application. But is there any simple and elegant way of doing this some other way?
You said you dislike the static solution but to me "It needs to be accessed by many classes" screams static variables.
Basically, you create a wrapper for your ArrayList which carries out operations:
class AccountsModel {
private static ArrayList<AccountModel> singleton;
// a static constructor also wouldn't be a bad idea here
public static void init() {
/* add a bunch of AccountModels here*/
}
public static ArrayList<AccountModel> getAccounts() {
return singleton;
}
}
An example of a main method:
public static void main(String[] args) {
ArrayList<AccountModel> accounts = AccountModels.getAccounts();
}
I'm learning to code and currently I'm trying to clean up my massive code by finally learning classes. I'm telling you this just to give a heads-up my terminology might still be off :) :)
The situation
My code works with "layers" that will be drawn on top of each other
There are two types of layers: video layers and image layers.
Both types of layers are child from parent class "Layer"
They need to be run by creation order
The goal
I want to run a code for each item/object of the class.
current code
import java.util.*;
public class main {
public static void main(String[] args){
// defining the objects
LayerVideo item01 = new LayerVideo();
item01.path = "import/01/";
LayerVideo item02 = new LayerVideo();
item02.path = "import/02/";
LayerImage item03 = new LayerImage();
item03.path = "import/03/";
// here is the main goal:
// to run/call each object from class "Layer"
// "allLayers" does not exist, but that's what I don't know how to do.
allLayers.forEach( item ->{
System.out.println( item.path );
// expected result in console:
// import/01/
// import/02/
// import/03/
});
}
public static class Layer {
}
public static class LayerVideo extends Layer {
public String path;
}
public static class LayerImage extends Layer {
public String path;
}
}
Thoughts
How to get all excising objects from a class
If I have them, how to ID them?, by var name?
Could I sort/filter the objects in a loop?
Two things:
consider to make your classes top level ones. So don't go public static class LayerVideo inside your Main class. If they are that important, the classes should each go into their own java file.
then learn about Java collections to organized object instances. You could define use an ArrayList for example.
Beyond that, the point is probably: if you want common things for two different classes, then your base class needs to have that, like:
public abstract class Layer {
private String path;
public String getPath() { return path; }
public void setPath(String newPath) { path = newPath; }
and then your subclasses simply inherit that behavior.
Then, you simply can add objects with that extend that base type to a collection:
List<Layer> layers = new ArrayList<>();
Layer layer = new VideoLayer();
layers.add(layer);
So, with the help and pointers of #GhostCat I've came to the following working code:
main.java
public class main {
public static void main(String[] args){
// debug to see amount of elements in list
System.out.println( settings.layers.size() );
// Aggregate with .forEach(), but will switch to .stream() to also be able to filter
settings.layers.forEach( layer -> {
System.out.println( layer.path );
// do stuff
});
}
}
settings.java
import java.util.ArrayList;
import java.util.List;
public class settings extends main{
public static List<Layer> layers = new ArrayList<>();
static {
layers.add( new LayerImage(true, "input/01/", new int[] {255,255,255} ) );
layers.add( new LayerImage(false, "input/02/", new int[] {255,0,0} ) );
layers.add( new LayerVideo(true, "input/03/", new int[] {0,0,255} ) );
}
}
Layer.java
public abstract class Layer {
boolean run;
String path;
int[] color;
public Layer(boolean startRun, String startPath, int[] startColor) {
run = startRun;
path = startPath;
color = startColor;
}
}
LayerImage.java
public class LayerImage extends Layer {
public LayerImage( boolean startRun, String startPath, int[] startColor) {
super( startRun, startPath, startColor) ;
}
}
LayerVideo.java
public class LayerVideo extends Layer {
public LayerVideo( boolean startRun, String startPath, int[] startColor) {
super( startRun, startPath, startColor) ;
}
}
In the main.java I'll swap the aggregator .forEach() with .stream() later on. Sounds more flexible and to be able to filter the results in advance seems like a big advantage. (then I can also use the item.run to see if I want to run this layer).
Why is there a settings class? I want to be able to have ALL the settings and variables to set for the outcome in one file. This way I can (I think) quickly use different setting files. Maybe also change it to XML input later. Use a GUI or whatever. (You might think "ah, sweet summer child", I'll cross that bridge when I get there).
The Layer SuperClass will have around the 10 parameters/arguments in the constructor when finished. Feels a lot to change and maintaining for the SubClasses by passing it with super(); And later on make changes. What is I will have around, say, 20 SubClasses. Is there a more efficient way?
Any other pointers on what I can do better in this code above?
All in all a LOT learned today! Thanks everyone and special thanks to #GhostCat
I personally create an static ArrayList from the object for every class and add the objects to it in the constructor (with list.add(this)).
Like:
public class Layer{
static ArrayList<Layer> layerList = new ArrayList<>();
public Layer() {
layerList.add(this);
}
}
I'm searching for a concept to forward an object to subobjects.
Example:
I would like to create log files for several main Objects, that include sub objects (imagine a REST server that would log every single connection by ID).
Creating one big log file is simple ( redirect System.out.println, I already encapsulated that)
Example code:
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Application.java
package com.dev4ag;
class Application{
private ElementA elA;
private String prefix;
public Application(String name){
this.elA = new ElementA();
this.prefix = name;
}
public void countUp(){
Debugger.debug(this.prefix+": I will now count up");
this.elA.doSomeStuff();
}
}
ElementA.java
package com.dev4ag;
class ElementA{
private int counter;
private SubElementA subElementA;
public void doSomeStuff(){
counter++;
Debugger.debug("Counter is: "+counter);
}
//Constructor
public ElementA(){
subElementA = new SubElementA();
this.counter = 0;
};
}
SubElementA.java
package com.dev4ag;
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Debugger.java
package com.dev4ag;
public class Debugger {
public static void debug(String output){
//Just imagine we would write to a file here ;)
System.out.println(output);
}
}
(it was more easy to write system.out.println than to create a file, just imagine, Debugger.debug would write to a file).
Now I am thinking about a solution to create one Debug output target for each App. I could definitely change debug to not being static and create a debug object within Application.
But is there any way to use this object in the sub classes without forwarding the debug object either through Constructor or setter function, which would mean to have to add an object for the debugger to each class?
What would be the most beautiful solution for that?
Note that this solution might decrease performance a lot and it is pretty dirty way, but some loggers include such data.
But you can use Thread.currentThread().getStackTrace() to get stacktrace like in error and get class and method from where your method was called.
If you are using java9+ then you should probably use StackWalker API instead, especially that it have nice filters and other useful features.
So then you could guess app by class/method names on the stack.
I'm doing some big refactoring operations relative to some performance improvements in an android app which is using a class with lot of static variables and even static activity references which are then use through the app ! So I was looking for some best practices in Android to store data and give to these data a global access in my app.
First I removed all the activity references to avoid any memory leak, but I'm still looking to know what is the best practice regarding static variables which need to be used anywhere in the android app.
I read many times (example1, exemple2) : using static variables is not necessary a good practices and it's better/cleaner to use one singleton class with getter and setter to have access to my global variables whatever the activity where I am. So what I've started to think is a class which could looks like this one :
public class AppSingleton extends Application {
private static AppSingleton appInstance;
// different stored data, which could be relative to some settings ..
private String setting1;
private String setting2;
private AppSingleton() {
super();
appInstance = new AppSingleton();
}
public static AppSingleton getAppInstance() {
if (appInstance == null) {
appInstance = new AppSingleton();
}
return appInstance;
}
// Getter and Setter for global access
public String getSetting1() {return setting1;}
public void setSetting1(String setting1) {this.setting1 = setting1;}
public String getSetting2() {return setting2;}
public void setSetting2(String setting2) {this.setting2 = setting2;}
}
Then I can use for example :
// Get the application instance
AppSingleton appS = (App) getApplication();
// Call a custom application method
appS.customAppMethod();
// Call a custom method in my App singleton
AppSingleton.getInstance().customAppSingletonMethod();
// Read the value of a variable in my App singleton
String var = AppSingleton.getInstance().getCustomVariable;
For me AppSingleton sounds good because this singleton which restrics ths instantiation of this class to one object, also this class is not destroyed until there are any undestroyed Activity in the application so it means I can keep my global data in the current lifecycle of my app for example from a 'Log in'. But also I can maintain the state of my global variables from my getters/setters.
But then I also had a look on the official android documentation about Performance Tips which say it's good to use static variable it's faster and don't forget to avoid internal getter and setter it's too expansive !
I'm a bit confused about all of these and I'm really keen to learn more about that topic. What is the best practices about using one class to provide an access to some variables which are needed in different part of my code ? Is the class above AppSingeleton is something which could be interesting to use in terms of architecture and performance ?
Is it a good idea to use a singleton pattern for managing global variables in android ?
those lines are completely wrong on your code:
private AppSingleton() {
super();
appInstance = new AppSingleton();
}
public static AppSingleton getAppInstance() {
if (appInstance == null) {
appInstance = new AppSingleton();
}
return appInstance;
}
you cannot instantiate new Application, the Android framework instantiates it. Change to this:
private AppSingleton() {
super();
appInstance = this; // keep ref to this application instance
}
public static AppSingleton getAppInstance() {
return appInstance;
}
Regarding the accessing of global variables. I believe it's more organized to have those singletons somewhere else on your application. The application class have different responsibilities you should not overload it with different tasks. That's OO clean coding.
Also, sometimes there's not that much reason in an Android app to have getters/setters for everything, because u don't need as much access control as in bigger projects. But this should be considered case-by-case about the necessity and not be used a general rule.
So you could for example have it like:
public class Globals {
private static final Globals instance = new Globals();
public static Globals get() { return instance; }
public String value1 = "Hello"
public int value2 = 42;
}
then on your code call as needed:
Log.d(TAG, Globals.get().value1);
Globals.get().value1 = "World";
Log.d(TAG, Globals.get().value1);
Log.d(TAG, "Value2 = " + Globals.get().value2);