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
Related
I have a java class:
class User {
private String name;
private String address;
private int age;
private BigDecimal salary;
// other fields
//getters setters
}
I can receive a map of new values in these fields and update it. It looks like this: ChangeItem changeItem where changeItem.key is field's name and changeItem.value is the field's value
I create strategies for updating each field. For example common interface:
public interface UpdateStrategy<T> {
T updateField(T t, ChangeItem changeItem) throws ValidationExceptions;
}
And some implementation:
public class UpdateNameStrategy implements UpdateStrategy<User> {
private static final Pattern USER_NAME = Pattern.compile(...);
#Override
public User updateField(User user, ChangeItem changeItem) throws ValidationExceptions {
String fieldValue = changeItem.value;
if (!validate(fieldValue))
throw new ValidationExceptions(changeItem);
user.setName(fieldValue);
return user;
}
private boolean validate(String value){
return USER_NAME.matcher(value).matches();
}
}
In the real project I have 40 fields and 40 strategies for each field(with different validation and logic).
I think this class violates the SRP(single responsibility principle). And I move validation logic to separately class. I change the validation method to:
public class UpdateNameStrategy implements UpdateStrategy<User> {
#Override
public User updateField(User user, ChangeItem changeItem) throws ValidationExceptions {
String fieldValue = changeItem.value;
ValidateFieldStrategy fieldValidator = new UserNameValidate(fieldValue);
if (!fieldValidator.validate())
throw new ValidationExceptions(changeItem);
return user;
}
}
and
public class UserNameValidate implements ValidateFieldStrategy {
private static final Pattern USER_NAME = Pattern.compile(...);
private String value;
public UserNameValidate(String value) {
this.value = value;
}
#Override
public boolean validate() {
return USER_NAME.matcher(value).matches();
}
}
And now I have 40 strategies for update fields and 40 validators. Is it the correct way? Or maybe I can change this code more clear?
I'm sorry for being blunt, my eyes are bleeding while looking at this. You took one unnecessarily complicated validation model and you split it in two to make it even more complicated. And none of it has much to do with the Single Responsibility Principle.
Without knowing anything specific to your domain problem, this looks like a superfluous usage of the Strategy pattern.
I've never seen a legitimate domain problem requiring a validation strategy split like this, for every single field.
An object in a domain is not just a collection of fields. It is also behavior governing the fields (which is the object state) and the rules governing the mutability of that state.
In general we want rich objects with behavior. And that behavior typically includes validation.
I sincerely doubt that every single field in a model requires validation to this level of granularity. Put the validation in the object's setter methods and be done with it.
You are killing yourself doing all this elaborate setup. We all want structure, but at some point all of this is just ceremony for building very tall sand castles.
Validation in general is part of an object. And an object is responsible, it is its responsibility to govern its state, the collection of fields and values it possesses and controls.
Single Responsibility Principle does not mean extracting the responsibility of validating fields out of an object. That responsibility is intrinsic to the object.
Single Responsibility Principle concerns itself with "external" responsibility, the responsibility of an object to provide a single coherent function (or set of coherent functions) to someone that uses that object.
Consider a Printer object. This object is responsible to print. It is not responsible to manage the network connections between a printer and a user, for instance.
SRP is not limited to classes, but also packages and modules. A Mathematics module should provide you with, obviously, mathematical routines. It should not provide routines for filesystem manipulation, right?
That's what the SRP is about. What you are doing, extracting validation behavior out of an object, that has little, if anything, to do with SRP.
Sometimes one might want to extract out common validation routines (check if a string is black or null, or whether a number is a natural number.)
So you might have a class like this:
public class User {
// some fields, blah blah
public void setName(final String aName){
if( aName == null || a.aName.trim().length() < 1){
throw new SomeException("empty string blah blah");
}
this.name=aName.trim(); // model requires this to be trimmed.
}
public void setRawField(final String aValue){
if( aName == null || a.aName.trim().length() < 1){
throw new SomeException("empty string blah blah");
}
this.rawField=aValue; // model requires this to not be trimmed.
}
public void setRawField2(final String aValue){
// model requires this field to be non-null,
// can be blank, and if not blank, must be all lower case.
if(aValue == null) {
throw new NullPointerException("null string blah blah");
}
this.rawField2=aValue.toLowerCase();
}
changed into a class that delegates minutia to an external validation utility class or module.
public class User {
// some fields, blah blah
public void setName(final String aName){
// model requires this to be trimmed
this.name=Validator.notEmptyOrDie(aName).trim();
}
public void setRawField(final String aValue){
// model requires this to *not* be trimmed
this.rawField=Validator.notEmptyOrDie(aValue);
}
public void setRawField2(final String aValue){
// model requires this field to be non-null,
// can be blank, and if not blank, must be all lower case.
// too contrive to refactor, leave it here.
if(aValue == null) {
throw new NullPointerException("null string blah blah");
}
this.rawField2=aValue.toLowerCase();
}
public class Validator {
static public String notEmptyOrDie(final String aString){
if( aString == null || aString.trim().length() < 1){
throw new SomeException("empty string blah blah");
}
return aString;
}
This is an approach I actually follow, to refactor parts of common validation. I factor out minutia.
But the core validation logic, if any, it remains in the object. Notice that validation is still part of the User class. All that got extracted is the minutia.
The logic that declares the intent of validation (check if black or die) still remains part of the User class. It is intrinsic to the class' behavior.
In some models, the User class might not require validation at all. It might be just a data shuttle, a POJO.
OTH, in a model that requires it to validate its state, that state should usually go inside the class, and a developer must have a very good argument for extricating that logic the way you did in your sample code.
SRP says nothing about how you compose responsibility internal to the object, only external to consumers of said object.
As a rule of thumb, validation of object fields belong to the object as logic internal to the object. It is intrinsic to the object's behavior, invariants, pre conditions and post conditions.
Very rarely you extract out the entire validation out of an object (unless we are talking about POJOs serialized and deserialized by an external package, and with validations added declaratively via annotations or some sort of controlling configuration descriptor.)
Hit me up if you still have any questions. Not sure how fast I can answer back, but I don't mind to answer questions if I can.
**** EDIT ***
User #qujck mentions the valid concern in this proposed approach, that it is not possible to differentiate all validation exceptions (becuase they use common exceptions for all.)
One possibility (which I've used) is to have overloaded and/or polymorphic validators:
public class Validator {
static public String notEmptyOrDie(final String aString){
return Validator.notEmptyOrDie(aString, null);
}
static public String notEmptyOrDie(final String aString,
final String aFieldName){
if( aString == null || aString.trim().length() < 1){
throw new SomeException(
(aFieldName==null? "" : aFieldName + " ")
+ "empty string blah blah");
}
return aString;
}
}
If one uses a hierarchy of validation exceptions with common constructors, then one could take this further by passing the desired exception class, and use reflection to create instances to be thrown.
I've done that also. Actually, I'm doing that now for a common error-throwing mechanism in an EJB layer that itself reaches to another system via network protocols.
But that's something I do to cope with an existing system, not something I would do if I had a design choice. And it still limits itself to refactoring validation or error handling to its core elements.
Actual, object-specific validation still remains at/within the object itself.
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 am building a HTTP server for my android device.
I am using a lot of IF-ELSE statements to handle differnt requests.
As I will be sharing my code with other people for later use, I will have to make it as legible as possible. Right now, I can't even read my code with ease.
I think the problem comes from using a lot of IF-ELSE statements in one class.
For example.
if(purpose.equals("readProfile"){
.....
}
else if(purpose.equals("writeProfile"){
.....
}
....
I tried classifying them in category and ordered the conditions according to their category. But not a lot of legebility was improved.
Then I tried writing short comments infront of each conditions. But this made even more mess.
What can be done to increase legibility for conditional statements?
As Luiggi Mendoza stated, this is a follow up of a previous question...
If you are using Java 7, you can use a switch-case statement for strings
//month is a String
switch (month.toLowerCase()) {
case "january":
monthNumber = 1;
break;
//partsleft out for sake of brevity ..
default:
monthNumber = 0;
break;
}
(excerpt from the Oracle Java Tutorials, referenced above.)
Refactoring
However, this huge if-else is just part of the problem. As this seems to be a structure growing over time, I'd recommend a thorough refactoring, and using what seems to me is a Strategy pattern. You should:
Formulate an interface which covers the boundaries for all the use cases:
interface MyStrategy {
void execute(MyInputContext input, MyOutputContext output);
}
(using a void method with MyInputContext and MyOutputContext are just one approach, this is just an example, but to handle requests that have responses, this makes sense, just like how Servlets work)
Refactor the content of the big IF-ELSE statement into instances of this interface (these will be the strategies):
//VERY simplified...
class ReadProfileStrategy implements MyStrategy {
void execute(MyInputContext input, MyOutputContext output) {
//do the stuff that was in the if-else block in the "readProfile" part
}
}
//... at the branching part:
MyInputContext input; //build this here
MyOutputContext output; //build this here
switch (purpose) {
case "readProfile":
// no need to always instantiate this, it should be stateless...
new ReadProfileStrategy().execute();
break;
//... left out for sake of brevity
}
Refactoring step 2
If this is done, you can add the string IDs to the interface, and the instances themselves, and get rid of the if-else or switch statement altogether, you could create a Map populated even through an IOC container (like), to be up to date, and completely flexible.
class ReadProfileStrategy implements MyStrategy {
String getID() {
return "readProfile";
}
void execute(MyInputContext input, MyOutputContext output) {
//do the stuff that was in the if-else block in the "readProfile" part
}
}
In the class when requests are processed
private final Map<String, MyStrategy> strategyMap; //fill the map using your favorite approach, like using Spring application context, using the getCode() to provide the key of the map
In the processing logic:
MyStrategy strategy = strategyMap.get(purpose);
if(strategy!=null) {
strategy.execute();
}
else {
//handle error here
}
This may be out of scope, but just an observation
try using
if("readProfile".equals(purpose){} instead of
if(purpose.equals("readProfile"){}.
It will help to avoid null pinter exception
Enums can help - you can also add functionality to them.
public void test(String purpose) {
if (purpose.equals("readProfile")) {
// Read.
} else if (purpose.equals("writeProfile")) {
// Write.
}
}
enum Purpose {
readProfile {
#Override
void doIt() {
// Read.
}
},
writeProfile {
#Override
void doIt() {
// Write.
}
};
abstract void doIt();
}
public void test2(String purpose) {
Purpose.valueOf(purpose).doIt();
}
You can try using some kind of Action-Interface with implementations for each block and preload a map with concrete Implementations of this action.
interface Action {
void execute();
}
Map<String, Action> actions = new HashMap<>();
actions.put("readProfile", new Action() { ... });
actions.put("writeProfile", new Action() { ... });
actionMap.get(purpose).execute();
That will lower your cyclomatic complexity as well. Of course you should preload the map only once.
Well, If it makes sense to separate code inside if-else condition to another class, perhaps use Factory pattern. Also make all separated classes implement common interface (eg: MyActivity.class) with a method such as execute().
Factory decides what object (ReadProfile.class, WriteProfile.class etc.) has to be created based on the string you pass and then call execute() method.
MyActivity obj = MyFactory.createMyActivity(String)
obj.execute(...);
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() );