I saw sometime in the last month an implementation of Null Object pattern as what seemed like a Singleton field on a type. I can't really remember the approach though. I'm working on patterns and conscious of implementing them out of place.
From my mind I think it would be as follows but can I get a review on that?
public final class SearchCriteriaAnomalyFilter {
public static final SearchCriteriaAnomalyFilter NULL_INSTANCE;
private final T2AnomalyStatus status;
private final T2AnomalyType type;
private final boolean limitMaxOneAnomaly;
public SearchCriteriaAnomalyFilter(T2AnomalyStatus status, T2AnomalyType type,
boolean limitMaxOneAnomaly){
this.status = status;
this.type = type;
this.limitMaxOneAnomaly = Boolean.valueOf(limitMaxOneAnomaly);
}
private SearchCriteriaAnomalyFilter(){}
public static SearchCriteriaAnomalyFilter instanceOfNullObject(){
if (NULL_INSTANCE == null) {
NULL_INSTANCE = new SearchCriteriaAnomalyFilter();
}
return NULL_INSTANCE;
}
...
}
public static final SearchCriteriaAnomalyFilter NULL_INSTANCE = new SearchCriteriaAnomalyFilter();
public static SearchCriteriaAnomalyFilter instanceOfNullObject(){
return NULL_INSTANCE;
}
The rest of your code seemed fine.
The reason to use the above construct is that there is no need for a lazy initialization: the null-object won't change, nor does it need any special construction (as you properly implemented with the private constructor).
Related
I'm writing a library, which has a predefined set of values for an enum.
Let say, my enum looks as below.
public enum EnumClass {
FIRST("first"),
SECOND("second"),
THIRD("third");
private String httpMethodType;
}
Now the client, who is using this library may need to add few more values. Let say, the client needs to add CUSTOM_FIRST and CUSTOM_SECOND. This is not overwriting any existing values, but makes the enum having 5 values.
After this, I should be able to use something like <? extends EnumClass> to have 5 constant possibilities.
What would be the best approach to achieve this?
You cannot have an enum extend another enum, and you cannot "add" values to an existing enum through inheritance.
However, enums can implement interfaces.
What I would do is have the original enum implement a marker interface (i.e. no method declarations), then your client could create their own enum implementing the same interface.
Then your enum values would be referred to by their common interface.
In order to strenghten the requirements, you could have your interface declare relevant methods, e.g. in your case, something in the lines of public String getHTTPMethodType();.
That would force implementing enums to provide an implementation for that method.
This setting coupled with adequate API documentation should help adding functionality in a relatively controlled way.
Self-contained example (don't mind the lazy names here)
package test;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<HTTPMethodConvertible> blah = new ArrayList<>();
blah.add(LibraryEnum.FIRST);
blah.add(ClientEnum.BLABLABLA);
for (HTTPMethodConvertible element: blah) {
System.out.println(element.getHTTPMethodType());
}
}
static interface HTTPMethodConvertible {
public String getHTTPMethodType();
}
static enum LibraryEnum implements HTTPMethodConvertible {
FIRST("first"),
SECOND("second"),
THIRD("third");
String httpMethodType;
LibraryEnum(String s) {
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
static enum ClientEnum implements HTTPMethodConvertible {
FOO("GET"),BAR("PUT"),BLAH("OPTIONS"),MEH("DELETE"),BLABLABLA("POST");
String httpMethodType;
ClientEnum(String s){
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
}
Output
first
POST
Enums are not extensible. To solve your problem simply
turn the enum in a class
create constants for the predefined types
if you want a replacement for Enum.valueOf: track all instances of the class in a static map
For example:
public class MyType {
private static final HashMap<String,MyType> map = new HashMap<>();
private String name;
private String httpMethodType;
// replacement for Enum.valueOf
public static MyType valueOf(String name) {
return map.get(name);
}
public MyType(String name, String httpMethodType) {
this.name = name;
this.httpMethodType = httpMethodType;
map.put(name, this);
}
// accessors
public String name() { return name; }
public String httpMethodType() { return httpMethodType; }
// predefined constants
public static final MyType FIRST = new MyType("FIRST", "first");
public static final MyType SECOND = new MyType("SECOND", "second");
...
}
Think about Enum like a final class with static final instances of itself. Of course you cannot extend final class, but you can use non-final class with static final instances in your library. You can see example of this kind of definition in JDK. Class java.util.logging.Level can be extended with class containing additional set of logging levels.
If you accept this way of implementation, your library code example can be like:
public class EnumClass {
public static final EnumClass FIRST = new EnumClass("first");
public static final EnumClass SECOND = new EnumClass("second");
public static final EnumClass THIRD = new EnumClass("third");
private String httpMethodType;
protected EnumClass(String name){
this.httpMethodType = name;
}
}
Client application can extend list of static members with inheritance:
public final class ClientEnum extends EnumClass{
public static final ClientEnum CUSTOM_FIRST = new ClientEnum("custom_first");
public static final ClientEnum CUSTOM_SECOND = new ClientEnum("custom_second");
private ClientEnum(String name){
super(name);
}
}
I think that this solution is close to what you have asked, because all static instances are visible from client class, and all of them will satisfy your generic wildcard.
We Fixed enum inheritance issue this way, hope it helps
Our App has few classes and each has few child views(nested views), in order to be able to navigate between childViews and save the currentChildview we saved them as enum inside each Class.
but we had to copy paste, some common functionality like next, previous and etc inside each enum.
To avoid that we needed a BaseEnum, we used interface as our base enum:
public interface IBaseEnum {
IBaseEnum[] getList();
int getIndex();
class Utils{
public IBaseEnum next(IBaseEnum enumItem, boolean isCycling){
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
if (index + 1 < list.length) {
return list[index + 1];
} else if(isCycling)
return list[0];
else
return null;
}
public IBaseEnum previous(IBaseEnum enumItem, boolean isCycling) {
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
IBaseEnum previous;
if (index - 1 >= 0) {
previous = list[index - 1];
}
else {
if (isCycling)
previous = list[list.length - 1];
else
previous = null;
}
return previous;
}
}
}
and this is how we used it
enum ColorEnum implements IBaseEnum {
RED,
YELLOW,
BLUE;
#Override
public IBaseEnum[] getList() {
return values();
}
#Override
public int getIndex() {
return ordinal();
}
public ColorEnum getNext(){
return (ColorEnum) new Utils().next(this,false);
}
public ColorEnum getPrevious(){
return (ColorEnum) new Utils().previous(this,false);
}
}
you could add getNext /getPrevious to the interface too
#wero's answer is very good but has some problems:
the new MyType("FIRST", "first"); will be called before map = new HashMap<>();. in other words, the map will be null when map.add() is called. unfortunately, the occurring error will be NoClassDefFound and it doesn't help to find the problem. check this:
public class Subject {
// predefined constants
public static final Subject FIRST;
public static final Subject SECOND;
private static final HashMap<String, Subject> map;
static {
map = new HashMap<>();
FIRST = new Subject("FIRST");
SECOND = new Subject("SECOND");
}
private final String name;
public Subject(String name) {
this.name = name;
map.put(name, this);
}
// replacement for Enum.valueOf
public static Subject valueOf(String name) {
return map.get(name);
}
// accessors
public String name() {
return name;
}
This question already has answers here:
Elegant alternatives for huge amount of arguments in class constructor [closed]
(4 answers)
Closed 7 years ago.
I have a client library in which I am making http remote calls to my rest service and then I am returning List<DataResponse> back to the customer who is calling our library with the response I am getting from my REST service along with any errors if there are any wrapped around DataResponse object.
public class DataResponse {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
// constructors and getters here
}
Here is my ErrorCode enum class:
public enum ErrorCode {
// enum values
private final int code;
private final String status;
private final String description;
// constructors and getters
}
And here is my StatusCode enum class:
public enum StatusCode {
SUCCESS, FAILURE;
}
As you can see in my DataResponse class I have lot of fields so basis on that I have a very long constructor and everytime when I make a DataResponse object I have a big line with new DataResponse(.......). In future I might have more fields but for now I only have these fields.
Is there any better way I can use to make a DataResponse object and then return back List<DataResponse> from my library?
Do not use the builder pattern right away. It is not for types with tons of required fields. It's for types with tons of optional fields.
Builders' required properties are specified via the constructor. You are not forced to define values using methods, which makes those values optional.
This leaves potential for your object being only partially constructed. Using a builder for this would be abuse of the design.
With that said, you should decompose your type. I'm not sure what lmd or ctime is, or really what a DataResponse is supposed to represent, so I cannot tell you in which way you should decompose. But I can tell you cohesion is what determines such.
isLink, maskInfo and idType could possibly be decomposed into a DataResponseDetails object:
class DataResponseDetails {
private boolean isLink;
private String maskInfo;
private TypeOfId idType;
public DataResponseDetails(boolean isLink, String maskInfo, TypeOfId idType) {
//...
}
}
Now your DataResponse could be composed of DataResponseDetails:
class DataResponse {
private DataResponseDetails details;
private String response;
//...
public DataResponse(DataResponseDetails details, String response, ...) {
//...
}
}
Feel your constructor requires too much still? Decompose more!
Maybe you can identify smaller logical groups of fields an move them into objects of an own class. Then you can assemble all these objects in your DataResponse objects.
As Joshua Bloch stated it in Item 2 of Effective Java 2nd Edition, you should consider using a builder pattern, as it is a best practice.
Here is what you code could look like using it :
public class DataResponse {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
// constructors and getters here
public static class Builder {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
public Builder reponse(final String response) {
this.response = response;
return this;
}
public Builder isLing(final boolean isLink) {
this.isLink = isLink;
return this;
}
public DataResponse builder() {
return new DataResponse(this);
}
...
}
private DataResponse(final Builder builder) {
this.response = builder.response;
this.isLink = builder.isLink;
}
}
and then do something as follow :
DataResponse response = new DataResponse.Builder().reponse(anyResponse).isLink(isLink).build();
I have some doubts regarding how to do the following operation on a class that follow the Singleton model.
I have this original Singleton class:
public class ThreadsManager {
// I can have only one instance:
private final static ThreadsManager instance = new ThreadsManager();
// Private constructor:
private ThreadsManager() {
}
public static ThreadsManager getInstance(){
return instance;
}
}
Ok, this work well but now I have to modify it adding a new property (a String named userName) that have to be initialized when the singleton object is build and that
can not be changed at a later time
So I am trying to do something like it:
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private final static String userName;
private ThreadsManager() {
}
public static ThreadsManager getInstance(String user){
userName = user;
return instance;
}
}
So I am trying to add the new String userName variable that is static (once for the class) and final (can not be changed at a second time)
My problem is that Eclips marks as an error the lines:
1) private final static String userName; saying to me that:
The blank final field userName may not have been initialized
It seems that would that the field will be initialized (I can initialize it to null but since it is final...I can't initialize later in the constructor)
2) userName = user; say to me that:
The final field ThreadsManager.userName cannot be assigned
So what is the best solution to handle this situation?
If I remove the final from the userName variable definition it seems to me that work well but then I can change this value but maybe I simply can not provide the setter method for this field so I prevent external changes....
Some ideas?
I think you want a singelton 'with arguments'. This should explain it :
Singleton with Arguments in Java
It is not going to be singleton if you want multiple state of an instance of that class,
you could create a cache of Object keyed with user so it would still be singleton for same state asked
private final Map<String, ThreadsManager> instanceCache = Collections.synchronizedMap<String, ThreadsManager>();
Also make sure you don't leak memory if you have tons of states for this class
Since this class is a Singleton then the name shouldn't really change too much. I would suggest just keeping it as a constant inside the class. If the name might change when the program is executed on different occasions then see Solution 2 below.
Solution 1:
public class ThreadsManager
{
private final static ThreadsManager instance = new ThreadsManager();
private String userName;
private ThreadsManager()
{
final String name = "Name";
userName = name;
}
public static synchronized ThreadsManager getInstance(String user)
{
return instance;
}
}
Solution 2:
If you really want to set the name of the Singleton and every time the program is execute the name might be different. Just add this method:
private String userName = null;
// Can only be set after Singleton is created and when userName is null.
public void setName(String n)
{
if(userName == null)
userName = n;
}
Don't make your getInstance() method have a parameter, that is a bad design. Every time someone, or you, tries to get an instance from your class they/you have to provide a parameter which will be 99% of the time be irrelevant.
You can do it using a nested class.
public class ThreadsManager {
private static String userName;
private ThreadsManager() {
}
public static ThreadsManager getInstance(String user){
if (userName == null)
userName = user;
// the holder's instance is only initialised at this point,
// after userName is set.
return Holder.instance;
}
static class Holder {
private final static ThreadsManager instance = new ThreadsManager();
}
}
First of all:
private final static String userName
may only be initialized inside the private constructor or during definition.
Secondly
You may end up with a null instance, so you might do something like this:
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private String userName;
private ThreadsManager() {
}
private ThreadsManager(String user) {
userName = user;
}
public static ThreadsManager getInstance(String user){
if(instance == null) {
instance = new ThreadsManager(user);
} else {
Logger.getInstance().logWarning("User has already been set. Will continue with user ["+username+"].);
}
return instance;
}
}
The handling of how to deal with a second user name handed needs some thinking.
Overall you should try to keep the getInstance() method parameter free since it leads to the above mentioned problems.
How about
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private static String userName;
public static synchronized ThreadsManager getInstance( String user ) {
if ( username == null ) { userName = user; }
return instance;
}
That would ensure userName is only set the first time.
It is, however, potentially very confusing semantics for a singleton to take a parameter that is ignored on subsequent getInstance()'s - possibly even race-condition-prone, depending on your use-case.
Cheers,
I have a basic question relating to the #SuppressWarnings("unused") annotation. Basically, I would like to suppress unused warnings on a block of code in my declarations section of my class. I would prefer not to suppress unused warnings on the entire class.
Currently, I am doing this:
public class MyClass {
//Constants
private final String ACCEPT = "Yes";
#SuppressWarnings("unused")
private final String DENY = "No"; //Not currently used
private final String TENTATIVE = "Maybe";
#SuppressWarnings("unused")
private final String POSTPONE = "Later"; //Not currently used
//Variables
private int counter;
....
I find the above code to be a bit messy with the annotations thrown in randomly like that. What I would like to do is something like:
//Constants
#SuppressWarnings("unused")
{
private final String ACCEPT = "Yes";
private final String DENY = "No"; //Not currently used
private final String TENTATIVE = "Maybe";
private final String POSTPONE = "Later"; //Not currently used
}
//Variables
private int counter;
....
This is, of course, illegal in Java as a block cannot be simply made like this. Its not a huge deal or anything, but I am curious if I am missing an obvious and elegant solution.
If you reeeeealy want to keep all those unused constants, a quick and dirty trick would be;
public class MyClass {
//Variables
private int counter;
#SuppressWarnings("unused")
private static final class UnusedConstants{
private final String ACCEPT = "Yes";
private final String DENY = "No";
private final String TENTATIVE = "Maybe";
private final String POSTPONE = "Later";
}
}
And i would make them static too, but your call.
EDIT:
Or, what i think is much nicer:
public class MyClass {
private enum Answer {
ACCEPT ("Yes"),
DENY ("No"),
TENTATIVE("Maybe"),
POSTPONE("Later");
private final String answer;
private Answer(String answer) {
this.answer = answer;
}
public String toString() {
return answer;
}
}
}
This way you don't get the unused warning as long as you use at least one of the values.
I'm new in java programming and trying to learn it.
I ran into a problem that cannot find a solution for it in the web:
I have an enum, that is a "list" of actions and each of them has a property
of type Actions that conains a list of possible subactions. The subacions are constant string.
I'd like to instanziate a anonymus instance of Actions in the enum constructor so that
in addition to the standart subactions, each enum could have its subactions
I tried to write an enum like the following
public enum Action {
ACTION1("One", new Actions(){
public static final String TEST = "test";
}),
ACTION2("TWO", null),
ACTION3("THREE,null);
private final String act;
public final Actions actions;
private Action(String act, Actions actions) {
this.act = act;
this.actions = actions;
}
}
and this is Actions class
public class Actions {
public static final String SUBACTION_TEST1 = "suoOne";
public static final String SUBACTION_TEST2 = "subTwo";
}
than, this is how I use the Action enum:
String as = Action.ACTION1.params.SUBACTION_TEST1;
and up to here it wors but I'cannot write this:
String ast = Action.ACTION1.params.TEST;
I know that probably this approach is wrong but before the change the implementation
I'd like to know why doesn't work.
Thanks.
Your enum has no property named params, which is the immediate reason your code example does not work. One thing you could do to improve this design, is to have your Actions class return the list of sub-actions via a well defined method:
public class Actions {
public static final String SUBACTION_TEST1 = "suoOne";
public static final String SUBACTION_TEST2 = "subTwo";
public List<String> getSubActions() {
return Arrays.asList(SUBACTION_TEST1, SUBACTION_TEST2);
}
}
public enum Action {
ACTION1("One", new Actions(){
public static final String TEST = "test";
#Override
public List<String> getSubActions() {
return Arrays.asList(TEST);
}
}),
private final String act;
private final Actions actions;
private Action(String act, Actions actions) {
this.act = act;
this.actions = actions;
}
public Actions getActions() {
return actions;
}
}
And to use this:
List<String> subActionList = Action.ACTION1.getSubActions();