Are there any notable advantages and/or disadvantages, expecially regarding performance, to replacing
private class MyClass{
/**
* Some code here
**/
private int numberOfPeople();
private Human[] people;
private void printPeople(){
// some code here
}
/**
* Some code here
**/
}
with an inner class like this, that better encapsulates the data:
private class MyClass{
/**
* Some code here
**/
private class PeopleHandler{
private int numberOfPeople();
private Human[] people;
private void printPeople(){
// some code here
}
private void doOherStuff{
// some code here
}
}
/**
* Some code here
**/
}
I need to know this specifically for Java and Java Android.
If you replace one class with another it makes little difference.
Using a nested class is about as expensive is adding a reference to a class. It could make a difference if you have many millions, but for most use cases you will have trouble measuring the difference.
I suggest you do what you believe is simplest and easiest to understand, and this is likely to perform well enough also.
Related
I'm mainly a C#, .NET developer and am used to interfaces and TDD in C#. Interfaces in C# primarily define the contract when implemented. The usage seems to be slightly different in Java. In particular, it seems that every project I've come across implements a basic interface for accessing the application, as if it's always a requirement for any Java app to utilise an interface. I'm thinking I'm missing some basic understanding, so I'd really appreciate any prompts to a good primer that I can read.
For example, I have a test which looks like this (in a separate 'Test' folder in my solution):
Tests.java
package com.dius.bowling;
class DiusBowlingGameTest {
private BowlingGame bowlingGame;
#BeforeEach
void setUp() {
this.bowlingGame = new DiusBowlingGame();
this.bowlingGame.startGame();
}
To be able to access this.bowlingGame.startGame(); I need to add the method to the interface. Why? There seems to be a difference between Java and C#/.NET I'm unaware of?
Interface
package com.dius.bowling;
/**
* Interface for a bowling game.
*/
public interface BowlingGame {
/**
* roll method specifying how many pins have been knocked down
* #param noOfPins no. of pins knocked down
*/
void roll(int noOfPins);
/**
* get player's current score
* #return player's current score
*/
int score();
void startGame();
}
DiusBowlingGame
package com.dius.bowling;
/**
* Scoring system for tenpin bowls
*/
public class DiusBowlingGame implements BowlingGame {
ArrayList<BowlingFrame> gameFrames = new ArrayList<BowlingFrame>();
public void roll (int noOfPins) {
/* Implementation */
}
}
/**
* Activate the 1st frame of the game
*/
public void startGame() {
advanceFrame();
};
If it's not in the interface, and you store the reference in a variable of the interface type, how does the compiler know the method exists?
In general, the value assigned to the variable could be any implementation of BowlingGame. Unless the method is on the interface, there is no requirement for those classes to implement the method.
To avoid adding the method to the interface, either change the variable type to DiusBowlingGame, or use a local variable in the setUp method:
DiusBowlingGame bowlingGame = new DiusBowlingGame();
bowlingGame.startGame();
this.bowlingGame = bowlingGame;
As far as I know, interfaces work the same in C# and Java. The only differences are that it is common to name interfaces with an "I" in the beginning at C# and that in C# both classes and interaces use the : operator, whereas in Java the keyword implements is used for interface, the keyword extends is used for classes. Your code does not need the interface, it would work perfectly also this way:
package com.dius.bowling;
class DiusBowlingGameTest {
private DiusBowlingGame bowlingGame;
#BeforeEach
void setUp() {
this.bowlingGame = new DiusBowlingGame();
this.bowlingGame.startGame();
}
I remember a couple years ago I was using static initializers to call class-level setup operations. I remember it having very bizarre behaviors and I just decided to steer clear from them. Maybe it was because I was messing up the top-bottom order or being a newbie. But I am encountering a need to revisit them and I want to make sure there is not a better way that is just as concise.
I know it is not fashionable, but I often have data-driven classes that maintain a static list of instances imported from a database.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}
When I have dozens of table-driven classes like this one, this pattern is very concise (yes I know it tightly couples the class with one source of data/instances).
However, when I discovered the goodness of Google Guava I want to use the EventBus to update the static list when a certain event posted. I would create a static final boolean variable just to call a static method that initialized the registration.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private static final boolean subscribed = subscribe();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
private static boolean subscribe() {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
return true;
}
}
This got annoying very quickly, because the compiler would throw warnings over the subscribed variable never being used. Also, it just added clutter. So I'm wondering if it is kosher to use the static initializer, and there really is no better way if I do not decouple this into two or more classes. Thoughts?
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
static {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
}
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}
So I'm wondering if it is kosher to use the static initializer
The funny thing is that
private static final boolean subscribed = subscribe();
and
private static final boolean subscribed;
static {
subscribed = subscribe();
}
get compiled to exactly the same bytecode. So using the needless static variable is strictly worse.
But until we are ready to scale up to a DI-driven framework,
Discover Guice. Don't call it framework (though it is). It's easy to use and let's you get rid of static.
Or do it manually. Rewrite your class by dropping all static modifiers and pass it everywhere you need it. It's rather verbose sometimes, but stating dependencies explicitly allows you to test classes in isolation.
The way it is, you can't test StratBand without hitting the database, no matter how trivial the method under test is. The problem is the coupling of every StratBand instance to the list of all StratBands.
Moreover, you can't test the behavior dependent on the stratBands contents as it always get loaded from the DB (sure, you can fill your DB correspondingly, but it's a big pain).
For starters, I'd create StratBandManager (or StratBands or whatever name you like) and move all the static functionality to it. In order to easy the transition, I'd create a temporary class with static helpers like
private static StratBandManager stratBandManager = new StratBandManager();
public static ImmutableList<StratBand> stratBands() {
return stratBandManager.stratBands();
}
Then deprecate it all and replace it by DI (using Guice or doing it manually).
I find Guice useful even for small projects. The overhead is tiny as often there's no or hardly any configuration.
I never see this kind of constants declaration in any Java code around me...
So i'd like to know if you see any drawback of using non-static final constants.
For exemple, i've declared a Guava function as a public constant of a given MaintenanceMode instance. I think it's better because if i created a getDecoratorFunction() it would create a new function instance each time...
Or the get function could return the single instance function that is kept private in the class, but it hads useless code... When we declare constants at class level, we declare directly the constants being public, we do not put them private and provide a public getter to access them...
public class MaintenanceMode {
/**
* Provides a function to decorate a push service with the appropriate decorator
*/
public final Function<PushService,PushService> MAINTENANCE_DECORATION_FUNCTION = new Function<PushService,PushService>() {
#Override
public PushService apply(PushService serviceToDecorate) {
return new PushServiceMaintenanceDecorator(serviceToDecorate,MaintenanceMode.this);
}
};
private final EnumMaintenanceMode maintenanceMode;
private final long milliesBetweenMaintenances;
private final Optional<ExecutorService> executorService;
public EnumMaintenanceMode getMaintenanceMode() {
return maintenanceMode;
}
public long getMilliesBetweenMaintenances() {
return milliesBetweenMaintenances;
}
public Optional<ExecutorService> getExecutorService() {
return executorService;
}
private MaintenanceMode(EnumMaintenanceMode maintenanceMode, long milliesBetweenMaintenances, ExecutorService executorService) {
Preconditions.checkArgument(maintenanceMode != null);
Preconditions.checkArgument(milliesBetweenMaintenances >= 0);
this.maintenanceMode = maintenanceMode;
this.milliesBetweenMaintenances = milliesBetweenMaintenances;
this.executorService = Optional.fromNullable(executorService);
}
}
And i can access this variable with:
pushServiceRegistry.decoratePushServices(maintenanceMode.MAINTENANCE_DECORATION_FUNCTION);
I guess it could lead to strange behaviours if my maintenanceMode was mutable and accessed by multiple threads, but here it's not.
Do you see any drawback of using this kind of code?
Edit: I can have multiple instances of MaintenanceMode, and all instances should be able to provide a different constant function according to the MaintenanceMode state. So i can't use a static variable that would not access the MaintenanceMode state.
The point of a getter would be dynamic dispatch. If you have no need for it, using a public final field is perfectly fine. I even routinely write bean-like objects that have no getters, just public final fields.
By making a constant non-static, you are basically saying that the constant can only be accessed when you have an instance of that class. But it is public (in the case of MAINTENANCE_DECORATION_FUNCTION) and it is part of that class so why not make it static? The constant is, after all, a constant and it does not require an instance of that class to be used elsewhere. The variable maintenanceMode is fine as it is a private constant.
Im implementing some generic components and I just wonder if my design patters makes sense and if there are any improvements that can be made. E.g., here is a generic panel that can be used to filter stuff:
/**
* Abstract class for textfields used for filtering. When overriding abstract method onUpdateFilter, the first thing
* that must be done is to set the paramsobject, or else filtering wont work.
* #author fred
*
*/
public abstract class FilterFormPanel extends Panel {
private static final long serialVersionUID = 1L;
private FilterForm filterForm;
private Object paramsObject; //this is object because paramsobjects differ depending on entity type
public FilterFormPanel(String id) {
super(id);
filterForm = new FilterForm("filterForm");
add(filterForm);
}
public String getFilterString(){
return filterForm.getFilterString();
}
public void setParamsObject(Object paramsObject){
this.paramsObject = paramsObject;
}
/**
*For developers to implement in class that contains the correct references to params and facade objects, dataviews etc.
*e.g. they could do params.setFilter(<reference to an instance of this class>.getFilterString() and ajax stuff too)
*/
public abstract void onUpdateFilter(AjaxRequestTarget target, Object paramsObject);
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 1L;
private transient String filterString;
public FilterForm(String id) {
super(id);
final TextField<String> filterTextField = new TextField<String>("filterTextField", new PropertyModel<String>(this, "filterString")); //textField for user to enter filter string
add(filterTextField);
add(new AjaxButton("filterButton") { //button to click for performing overriden method
private static final long serialVersionUID = 1L;
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
onUpdateFilter(target, paramsObject);
}
});
}
public String getFilterString(){
return filterString;
}
}
}
Used as follows in another class:
filterFormPanel = new FilterFormPanel("filterFormPanel"){
private static final long serialVersionUID = 1L;
#Override
public void onUpdateFilter(AjaxRequestTarget target, Object paramsObject) {
filterFormPanel.setParamsObject(params);
params.setFilterString(filterFormPanel.getFilterString());
//ajax stuff
target.addComponent(dataViewContainer);
nav.setVisible(dataProvider.size()!=0);
target.addComponent(nav);
emptyLabel.setVisible(dataProvider.size()==0);
target.addComponent(emptyLabel);
}
};
settingsContainer.add(filterFormPanel);
Its kind of annoying that one is forced to use the setParamsObject method first thing when one overrides the method. Is there a nicer way of achieving a reference to that object? And is this is general a sane way of implementing reusable and relatively generic components in wicket? Any feedback would be greatly appreciated, Im sure theres room for improvement here.
EDIT I: Just for some context, what Im doing is Im implementing pages like these
where I present the user with a dataview and options for filtering it. There are lots of pages for lots of different entities, but the GUI components can and should be made as generic as possible as to not violate DRY. The example code is obviously the filter textfield and button part of the page.
EDIT II: I want this component to be even more loosely coupled if possible, e.g. make it able to do completely different things, not just modifying a params object (say, e.g. have another case where I need to update TWO params objects, then I wont be able to use this panel). The onSubmit method in the form as it is now requires a reference to the objects to be used in the overriden method are known beforehand. Is there any way to not have it that way or set the presence and/or types of those objects dynamically?
EDIT III: The point is that this panels core function really is only to allow the user to
enter a string
notify and give access to that string to some other part of the system when the user clicks the button.
What that "other part of the system" does with the string should not really have to concern this panel, but as it is now, it is coupled to the params object upon which "the other part of the system" must perform some operation. It is this coupling I would like to get rid of if possible. I might as well want to use the string from this panel for just printing to console or use it for some other arbitrary task.
You can use the constructor of the class to set the object.
A more generic approach would be if you let paramsObject make use of the Java Generics (hence the name :)). You could superclass the entities or let them implement an interface.
I work for more than 3 years on a web application using Wicket (started using 1.3.x now under 1.4.x and planning to upgrade to 1.5.x in a few weeks). The approach you are using is the one we use internally. We often use abstract classes to represents common panels. The only thing we do is what rotsch said in his answer, we use a lot of generics to infer the type arguments as much as possible.
Actually, even though I didnt realize it at first, this could be achieved quite easily with by simply doing this:
/**
* Abstract class for textfields used for filtering.
* #author fred
*
*/
public abstract class FilterStringPanel extends Panel {
private static final long serialVersionUID = 1L;
private FilterForm filterForm;
public FilterStringPanel(String id) {
super(id);
filterForm = new FilterForm("filterForm");
add(filterForm);
}
public String getFilterString(){
return filterForm.getFilterString();
}
/**
*For developers to implement in class that contains the correct references to params and facade objects, dataviews etc.
*e.g. they could do params.setFilter(<reference to an instance of this class>.getFilterString() and ajax stuff too)
*/
public abstract void onUpdateFilter(AjaxRequestTarget target);
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 1L;
private transient String filterString;
public FilterForm(String id) {
super(id);
final TextField<String> filterTextField = new TextField<String>("filterTextField", new PropertyModel<String>(this, "filterString")); //textField for user to enter filter string
add(filterTextField);
add(new AjaxButton("filterButton") { //button to click for performing overriden method
private static final long serialVersionUID = 1L;
#Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
onUpdateFilter(target);
}
});
}
public String getFilterString(){
return filterString;
}
}
}
And then implementing it this way:
settingsContainer.add(new FilterStringPanel("filterStringPanel"){
private static final long serialVersionUID = 1L;
#Override
public void onUpdateFilter(AjaxRequestTarget target) {
params.setFilterString(getFilterString());
target.addComponent(dataViewContainer);
nav.setVisible(dataProvider.size()!=0);
target.addComponent(nav);
emptyLabel.setVisible(dataProvider.size()==0);
target.addComponent(emptyLabel);
}
});
This way we dont need to send any references to any objects (e.g. params objects or wicket components that needs to be targeted for updating with AJAX) and we can re-use this panel for whatever we want!
General question here: If I'm making a new class, and it's only private field is a string, can I do something like this.privateString = argumentIn; in the constructor to set that private field? I'm just weary since I'm not good with the whole referencing part of java.
Yes, and thus the definition of a private field being only accessible from within the class itself.
And as a tip, without any accessors, this may render your objects of this class mostly useless.
Definitely. Consider this example. I have added some basic defensive copying practice.
/**
* MyClass is an immutable class, since there is no way to change
* its state after construction.
*/
public final class MyClass{
private final String myString;
public MyClass(String myString){
this.myString = myString;
}
/**
* Returns an immutable object. String is immutable.
*
*/
public String getMyString(){
return myString;
}
//no need to provide a setter to keep myString as immutable after initial state
}
Consider reading this post by Joshua Bloch on defensive copying of fields.