I have a dialog that displays various things depending on state of the application, security for the current user etc.
I am currently passing in several boolean flags and then enabling and/or hiding UI components depending on these flags.Eg:
new MyDialog(showOptionsTable, allowFooInput, allowBarInput, isSuperUser)
Initially this started out as a couple of flags and that was fine. But now with changing requirements, it has evolved into an input of five boolean flags.
What is the best practices way of handling behavior like this? Is this something that I should subclass depending on how the dialog should look?
As with many things, "it depends".
Ben Noland suggested a class to hold configuration options. This is doable, but favor immutability, and optionally use the builder pattern. Because booleans are built-in types, writing a small builder will really help people understand the code. If you compare this to MyDialog(true, true, ...) you know what I mean:
Options.allowThis().allowThat().build()
Chris suggested bit fields, but as some of the commenters point out, bit fields are evil because of many reasons outlined in Josh Bloch's Effective Java. Basically they are hard to debug and error prone (you can pass in any int and it will still compile). So if you go this route, use real enums and EnumSet.
If you can reasonably subclass (or compose), meaning that you usually only use a couple of combinations of all the booleans, then do that.
Once you get more than two or three flags, I would consider creating a class to store these settings to keep your design clean.
Create a class to hold your configuration options:
public class LayoutConfig
{
public boolean showOptionsTable = true;
public boolean allowFooInput = true;
public boolean allowBarInput = true;
public boolean isSuperUser = true;
}
...
LayoutConfig config = new LayoutConfig();
config.showOptionsTable = false;
new MyDialog(config);
This approach makes it easy to add new options without changes your interface. It will also enable you to add non-boolean options such as dates, numbers, colors, enums...
use the decorator pattern in order to dynamically adding behavior to your dialog
To build on Ben Noland answer, you could define some options as enum, then have a varargs constructor:
class MyDialog {
enum DialogOptions {
SHOW_OPTIONS_TABLE, ALLOW_FOO_INPUT, ALLOW_BAR_INPUT, IS_SUPER_USER
}
public MyDialog(DialogOptions ...options) { ... }
}
...
new MyDialog(DialogOptions.ALLOW_FOO_INPUT, DialogOptions.IS_SUPER_USER);
I have found that this kind of thing becomes MUCH more readable if I use enums for the boolean choices.
public enum ShowOptionsTable { YES, NO }
public enum AllowFooInput { YES, NO }
public enum AllowBarInput { YES, NO }
public enum IsSuperUser { YES, NO }
new MyDialog(ShowOptionsTable.YES, AllowFooInput.NO, AllowBarInput.YES,
IsSuperUser.NO);
With enums like this, usage of code with a lot of boolean parameters becomes easy to understand. Also, since you are using objects rather than booleans as parameters, you have use other patterns to easily refactor things later if you want, to use a decorator or a facade or some other pattern.
I prefer flagged enums to a settings class if the parameters are all going to be boolean. If you can't guarantee that in the future though it would be better safe than sorry though. Here's another implementation for flags:
[Flags]
public enum LayoutParams
{
OptionsTable = 1,
FooInput = 2,
BarInput = 4,
SuperUser = 8,
}
public MyDialog(LayoutParams layoutParams)
{
if (layoutParams & LayoutParams.OptionsTable)
{ /* ... Do Stuff ... */ }
}
public static MyDialog CreateBasic()
{
return new MyDialog(LayoutParams.OptionsTable | LayoutParams.BarInput);
}
Depending on just how different your display is going to be, you might consider subclassing your display class (i.e. MyDialogSuperUser or somesuch). You need to consider just how orthogonal the inputs to your dialog class are and how to express that orthogonality.
I have a favorite way to handle this, but it's not valid for all use cases. If the booleans are not entirely independent (say there are some invalid combinations of booleans, or combinations of booleans are reached through identifiably scenarios.) I create an enum for the state and then define a constructor that holds onto the flags:
public enum status {
PENDING(false,false),
DRAFT(true,false),
POSTED(false,true),
;
public boolean isSent;
public boolean isReceived;
status(boolean isSent, boolean isReceived) {
this.isSent = isSent;
this.isReceived = isReceived;
}
}
The advantage to a piece of code like this is that you can construct your enum constants relatively tersely, but still allow code to only care about one particular aspect of state. For example:
//I want to know specifically what the state is
if (article.state == status.PENDING)
// Do something
//I really only care about whether or not it's been sent
if (article.state.isSent)
// Do something
//I want to do something specific for all possible states
switch(article.state)
// A string of case statements
Another plus is that illegal states are never reached if you define your enum well:
if (article.state.isReceived && !article.state.isSent) {
// This block can never execute ever.
}
Granted, it's not all the time that there's a logical relationship among booleans, but I do recommend mapping them out. If a subset of booleans have logical relationships, it might be worth breaking those off into an enum.
Set it up so MyDialog(false, false, .....) is the expected default behaviour. (ie: The most common case should take all false. You may need to reverse the semantics of the flags.)
Now, define constants:
OPTION1 = 1
OPTION2 = 2
OPTION3 = 4
OPTION4 = 8
...
Change the method to take an int options parameter
public void MyDialog(int options) ...
Now call it:
MyDialog(OPTION1 | OPTION3) // enable Opt1, opt2)
inside the method:
if (options & OPTION1) // use Option 1 config.
etc.
If the GUI depends on the state of the app ( where one state leads to another ) You can take a look at the State pattern. Where each new state will be handled by a different object and you can code whether the flags should go or no.
ie.
abstract class State {
public abstract boolean [] getFlags();
public abstract State next();
}
class InitialState extends State {
public boolean [] getFlags() {
return new boolean [] { true, true, false, false, false };
}
public State next() { return new MediumState(); }
}
class MediumState extends State {
public boolean [] getFlags() {
return new boolean[] { false, false, true, true, false };
}
public State next() { return new FinalState(); }
}
class Final extends State {
public boolean [] getFlags() {
return new boolean[]{false, false, false, false, true };
}
public State next() { return null;}
}
And the show your dialog using this states
new MyDialog(showOptionsTable, new InitialState() );
....
When the state of the application changes, you change the State object.
public void actionPerfomed( ActionEvent e ) {
this.state = state.next();
repaint();
}
To paint the sections of your dialog you query the state:
if( state.getFlags()[SECURITY] ) {
/// show security stuff
} if ( state.getFlags()[VIEW_ONLY] ) {
// enable/disable stuff
} ....
You can go a step further ant let the State define what is presented.
abstract class State {
public abstract JComponent getComponent();
public abstract State next();
}
So each state shows a different section:
Dialog.this.setContentPane( state.getComponent() );
Related
I have the following POJO:
public class Shipment() {
private LocalDate dateShipped; // Sometimes we know the date of shipment, sometimes we don't
private boolean wasItemShipped; // If we know the date of shipment, this value is true. If we don't know the date, it can be either true or false
}
I'm trying to design the best pattern for managing these two fields. The boolean should be true whenever the Date is not null. However when the Date is null, the boolean can be true or false. Here's a couple of approaches:
Standard getter/setters
public void setDateShipped(LocalDate dateShipped) {
this.dateShipped = dateShipped;
}
public LocalDate getDateShipped() {
return dateShipped;
}
public void setWasItemShipped(boolean wasItemShipped) {
this.wasItemShipped = wasItemShipped
}
public boolean getWasItemShipped() {
return wasItemShipped;
}
This is a pretty normal approach. One downside to this approach is that when developers call setDateShipped() they need to also know to call setWasItemShipped(). This could become problematic if this code is found in multiple spots, or if we need to deserialize some incomplete JSON or something.
Add logic into the setter of dateShipped
public void setDateShipped(LocalDate dateShipped) {
this.dateShipped = dateShipped;
if (dateShipped != null) {
setWasItemShipped(true);
}
}
Add logic into the getter of wasItemShipped
public boolean getWasItemShipped() {
return dateShipped != null || wasItemShipped
}
Both of these approaches have the downside of adding logic to a POJO to mutate it in perhaps surprising ways. I feel like this could lead to frustration/bugs down the road.
Are there any other patterns for this type of operation?
You may checkout Observer and Observable, but that's too complicated. On the other hand there is no formal documentation that strictly says 'no logic inside setters'. So you can go ahead and implement your second approach, and retrofit if needed in future.
I prever Logic in the setter. Ist also helps debugging,as your variables represent the State Office your object and you don‘t Need the getter for getting your Objekts State.
And you can use wasItemShipped in other methods too without mich thinking and making your class More complicated.
To ne it Feels More Natural and intuitive to have Logic in the setter Rather the getter
I want to refactor an existing class of almost 5000 lines but I'm having difficulty with the constructor. Right now it's something like the following(methods here are in reality 10-30 blocks of code )
public MyClass( MyObject o ) {
if ( o.name.equalsIgnoreCase("a") ) {
doSomething()
} else {
doSomethingElse()
}
commonCode()
if (o.name.equalsIgnoreCase("a") ) {
doSecondThing()
} else {
doOtherSecondThing() //almost identical to doSecondThing but with some extra steps that absolutely have to be done in this sequence
}
// more of the same
}
I considered using inheritance and breaking things up into functions that would be overridden where necessary but that feels messy to me. Is there a pattern that fits this use case? Incidentally any advice on refactoring legacy code would be more than welcome.
You are exactly right. Refactoring like you described is called
Replace Conditional with Polymorphism.
Also you can look through on Chain-of-responsibility, Command or Strategy design patterns.
If every object follows the following pattern:
if(conditionA)
DoA();
else
DoElse();
Common();
if(conditionA2)
DoA2();
else if(conditionB2)
DoB2();
else
DoElse2();
Common2();
I'd advice you to have a common class that gathers handlers with conditions. This is roughly what I mean (Pseudo-code not java):
public interface IConditionalHandler
{
bool Condition();
void Action();
}
public class ActionHandler
{
private List<IConditionalHandler> m_FirstHandlers;
private List<IConditionalHandler> m_SecondHandlers; //Or possibly use a list of lists
public ActionHandler()
{
m_FirstHandlers = new ArrayList<>();
m_FirstHandlers.add(new HandlerA1());
m_FirstHandlers.add(new HandlerB1());
m_SecondHandlers = new ArrayList<>();
m_SecondHandlers.add(new HandlerA1());
m_SecondHandlers.add(new HandlerB1());
}
void DoStuff()
{
for(IConditionHandler handler : m_FirstHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
CommonA();
for(IConditionHandler handler : m_SecondHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
}
}
If you have lots of segment, a list of lists can include your common code as an exit-handler and contain all of the logic. You delegate the logic out to implementing classes, and shorten the actual code in your class.
However, as far as efficiency goes you are going to kill both the instruction and data cache. If this isn't what you're looking for, then more than likely this is: Chain-of-Responsibility Pattern - Wikipedia
G'day, errata ... My plan was as shown below. This update is to clarify and apologise for a late night question. The compile error was due to a problem elsewhere in the file.
Clarification: a simple Java enum, like this:
public enum ServiceSource
{
NONE,
URL,
FILE;
}
Want to checking like, isURL():
public boolean isURL(){
return (URL == this);
}
This works (and compiles) ... There's no question -- Correctly answered by: dasblinkenlight and Elliott Frisch. Thank you very much for your time.
see also:
Lookup enum by string value
How to test enum types?
Since this is an instance method, you need to check that this is equal to URL, like this:
public boolean isURL(){
return (URL == this);
}
Demo on ideone.
If you want to have methods that are polymorphic - i.e. exhibit different behaviour for different instances (values) of your enum class, my preference is to override a common method:
public enum ServiceSource {
NONE("no_value"),
URL("url"){
#Override
public boolean isURL() {
return true;
}
},
FILE("file");
private final String val;
private ServiceSource(String val) {
this.val = val;
}
public boolean isURL() {
return false;
}
}
But for methods that check whether this is specific enum value then adding an isXXX method for each constant seems very wasteful. Really, the very reason to use an enum, is so that you can write
if(thing == ServiceSource.URL)
Elsewhere in your code.
If I understand your question, the correct method in your enum is to use this like so,
public enum ServiceSource
{
NONE( "no_value" ),
URL( "url" ),
FILE( "file" );
ServiceSource(String v) {
text =v;
}
private String text;
public boolean isURL() {
return this == URL;
}
}
You can make a method on your Enum to check the value of itself like this:
public boolean isURL(){
return (URL == this);
}
But it's hard to see the value in this approach since every Object has a built in equals() method that accomplishes the same thing.
if (serviceSource.equals(ServiceSource.URL)) { ... }
This would be a more common and obvious way to check the assigned value of an Enum variable (or any variable for that matter). Taking the first approach would require you to have a new isX() method on your Enum; every time you add an Enum constant, you would probably want a new method to accompany it.
My question is how to use constant field values defined in predefined classes like I am practicing on the events program, and currently on action event, I have understand
the action listener part but when I go to action event part , I don't know how to use the static field constant, only I am able to use methods of the that classes, it will be more helpful if a simple example is given by you (simple not complex)
Elaboration:
I want to know how to use the ALT_MASK, ACTION_FIRST, ACTION_LAST constant
Also please show me how to create events of my own
Let's imagine you have class:
public Class ConstantsHere {
public static final int INTEGER_CONSTANT = 5;
}
Then, you want to use it in another class, and you write code like this:
//some code
if (myValue < ConstantsHere.INTEGER_CONSTANT) {
//do something
}
As mentioned in commens, Java Enum may be a good choice for this task:
public enum Action {
ALT_MASK, ACTION_FIRST, ACTION_LAST;
}
Usage:
//some code
if (myValue == Action.ACTION_LAST) {
//do something
}
To make things clear, Enum should be used in case when some variable may take limited number of values. For example, human gender can be only male or female (please do not take this as offensive for transsexuals, statement used only for explanation purposes), so it might be a good idea to use Enum for that instead of constants 0 and 1 (or M and F), just because we can put other number (or constant) there and break the logic.
Using enums example.
public enum UserStatus {
PENDING("P"), ACTIVE("A"), INACTIVE("I"), DELETED("D");
private String statusCode;
private UserStatus(String s) {
statusCode = s;
}
public String getStatusCode() {
return statusCode;
}
}
public void method(UserStatus status) {
System.out.println(status.getStatusCode());
}
}
I've used the State pattern to implement a simple finite state machine. Looking at the description given on Wikipedia, and more specifically at the suggested Java implementation, I wondered why classes implementing the State interface (i.e. the various states) are not Singletons?
In the suggested implementation a new State is created whenever a transition occurs. However, one object is sufficient to represent each state. So, why wasting time creating a new instance every time a transition occurs?
Because each state can store instance variables?
Take a look at the Wikipedia example you reference:
class StateB implements State {
private int count=0;
public void writeName(StateContext stateContext, String name) {
System.out.println(name.toUpperCase());
if(++count>1) {
stateContext.setState(new StateA());
}
}
}
Can you see how it stores a count of the number of times it has been entered?
Now, in a FSM you probably want each state to be idempotent (subsequent calls give the same feedback) but the State pattern is more general. One target use as described on the wikipedia page is:
A clean way for an object to
partially change its type at runtime
As most objects probably use their local variables when performing actions, you would want the "changed type" version to use local variables as well.
Assume your object has a state. Now what if you need "just one more whole thing like that"?
You may want a 'stateful-State' object (like demonstrated as one example on the references wikipedia page) and in addition you may want to run several state machines of the same type in the same JVM.
This wouldn't be possible if each State was a Singleton.
If your states don't need machine-specific additional state data, it makes perfect sense to reuse them across machines. That doesn't mean they are Singletons: Singletons also imply global access which you almost never want.
Here's a simple state machine that reuses states, but doesn't make them singletons.
public class SwitchState
{
public SwitchState(bool isOn)
{
mIsOn = isOn;
}
public void InitToggleState(SwitchState state)
{
mToggleState = toggleState;
}
public bool IsOn { get { return mIsOn; } }
public SwitchState Toggle() { return mToggleState; }
private SwitchState mToggleState;
private bool mIsOn;
}
public class LightSwitch
{
public LightSwitch()
{
mState = sOnState;
}
public bool IsOn { get { return mState.IsOn; } }
public void Toggle()
{
mState = mState.Toggle();
}
static LightSwitch()
{
sOnState = new SwitchState(true);
sOffState = new SwitchState(false);
sOnState.InitToggleState(sOffState);
sOffState.InitToggleState(sOnState);
}
private static SwitchState sOnState;
private static SwitchState sOffState;
private SwitchState mState;
}
You can see there will only be a single on and off state in the entire application regardless of how many LightSwitch instances there are. At the same time, nothing outside of LightSwitch has access to the states, so they aren't singletons. This is a classic example of the Flyweight pattern.
The question should be asked the other way around: why have State as a singleton? A singleton is only needed when you require global access and it is an error to have more than one instance.
It's certainly not an error to have more than one instance of a State, and you also do not require global access, so there is no need to make them singletons.