The story of the system in business. After logging in, when I investigated the conditions under which the menu changes depending on the company and people, I once thought, "Isn't it better to use a class?", So make a note of your thoughts.
The following company classes and user classes exist, and views that use those information are implemented.
Here, getters and setters are assumed to be implemented automatically by @Data
.
Also, the magic number should not be used originally, but the constantization is omitted.
Company.java
/**
*Class to store company information
*/
@Data
public class Company {
private String companyId; //Company ID
private int option1Flg; //Option 1 flag (0 or 1)
private int option2Flg; //Option 2 flag (0 or 1)
}
User.java
/**
*Class to store user information
*/
@Data
public class User {
private String userId; //User ID
private int userType; //User type (0: general user, 1: administrator)
}
menu.jsp
<% if (company.getOption1Flg() == 1) { %>
//Show menu 1
<% } %>
<% if (company.getOption2Flg() == 1) { %>
//Show menu 2
<% } %>
<% if (user.getUserType() == 1
&& (company.getOption1Flg() == 1 || company.getOption2Flg() == 1)) { %>
//Show administrator menu
<% } %>
Think of company as an object of the Company class and user as an object of the User class.
Basically, if each option is 1, it just displays the respective menu. Only the admin menu is special, it will be displayed if the user is an admin and one of the options is 1.
Isn't it a code that you have seen for a while? At present, there is no problem at first glance.
I had to change the specifications as follows.
--Add a reader to the user type --Add options 3-5 --Only the reader can display menus 3 to 5 corresponding to options 3 to 5. --The administrator menu is displayed if the user is an administrator and any of options 1 to 4 is 1 (5 is irrelevant).
Let's code this again, but first let's follow the original format.
Company.java
/**
*Class to store company information
*/
@Data
public class Company {
private String companyId; //Company ID
private int option1Flg; //Option 1 flag (0 or 1)
private int option2Flg; //Option 2 flag (0 or 1)
private int option3Flg; //Option 3 flag (0 or 1)
private int option4Flg; //Option 4 flag (0 or 1)
private int option5Flg; //Option 5 flag (0 or 1)
}
User.java
/**
*Class to store user information
*/
@Data
public class User {
private String userId; //User ID
private int userType; //User type (0: general user, 1: administrator, 2: reader)
}
menu.jsp
<% if (company.getOption1Flg() == 1) { %>
//Show menu 1
<% } %>
<% if (company.getOption2Flg() == 1) { %>
//Show menu 2
<% } %>
<% if (user.getUserType() == 2 && company.getOption3Flg() == 3) { %>
//Show menu 3
<% } %>
<% if (user.getUserType() == 2 && company.getOption4Flg() == 4) { %>
//Show menu 4
<% } %>
<% if (user.getUserType() == 2 && company.getOption5Flg() == 5) { %>
//Show menu 5
<% } %>
<% if (user.getUserType() == 1
&& (company.getOption1Flg() == 1 || company.getOption2Flg() == 1)
|| company.getOption3Flg() == 1) || company.getOption4Flg() == 1)) { %>
//Show administrator menu
<% } %>
The menu view can still be identified, but you can see that the code has become quite troublesome. If the specifications are changed in the future, I think it will be bad.
I think there are various solutions, but I will design it to add a menu class. At the same time, the existing class will also add a state determination method.
Company.java
/**
*Class to store company information
*/
@Data
public class Company {
private String companyId; //Company ID
private int option1Flg; //Option 1 flag (0 or 1)
private int option2Flg; //Option 2 flag (0 or 1)
private int option3Flg; //Option 3 flag (0 or 1)
private int option4Flg; //Option 4 flag (0 or 1)
private int option5Flg; //Option 5 flag (0 or 1)
public boolean isEnabledOption1() {
return option1Flg == 1;
}
public boolean isEnabledOption2() {
return option2Flg == 1;
}
public boolean isEnabledOption3() {
return option3Flg == 1;
}
public boolean isEnabledOption4() {
return option4Flg == 1;
}
public boolean isEnabledOption5() {
return option5Flg == 1;
}
public boolean isEnabledAdminOption() {
return isEnabledOption1()
|| isEnabledOption2()
|| isEnabledOption3()
|| isEnabledOption4();
}
}
User.java
/**
*Class to store user information
*/
@Data
public class User {
private String userId; //User ID
private int userType; //User type (0: general user, 1: administrator, 2: reader)
public boolean isNormalUser() {
return userType == 0;
}
public boolean isAdmin() {
return userType == 1;
}
public boolean isLeader() {
return userType == 2;
}
}
User.java
/**
*Menu class
*/
@RequiredArgsConstructor
@Getter
public class Menu {
private final Company company;
private final User user;
public boolean isEnabledMenu1() {
return company.isEnabledOption1();
}
public boolean isEnabledMenu2() {
return company.isEnabledOption2();
}
public boolean isEnabledMenu3() {
return user.isLeader() && company.isEnabledOption3();
}
public boolean isEnabledMenu4() {
return user.isLeader() && company.isEnabledOption4();
}
public boolean isEnabledMenu5() {
return user.isLeader() && company.isEnabledOption5();
}
public boolean isEnabledAdminMenu() {
return user.isAdmin() && company.isEnabledAdminOption();
}
}
menu.jsp
<% if (menu.isEnabledMenu1()) { %>
//Show menu 1
<% } %>
<% if (menu.isEnabledMenu2()) { %>
//Show menu 2
<% } %>
<% if (menu.isEnabledMenu3()) { %>
//Show menu 3
<% } %>
<% if (menu.isEnabledMenu4()) { %>
//Show menu 4
<% } %>
<% if (menu.isEnabledMenu5()) { %>
//Show menu 5
<% } %>
<% if (menu.isEnabledAdminMenu()) { %>
//Show administrator menu
<% } %>
After the improvement, I think that the display conditions of the menu and the status of the company and users have become very easy to understand. In a real application, it is possible to create a class that corresponds to one menu such as MenuItem and let that class make a decision, but this article will stop here.
In this example, there was a problem with starting to directly determine the state of the company or user in the menu view. However, in object orientation,
** Don't ask, order **
Is the basic idea. It depends on the responsibility of the class, but let's leave the processing to the side with the value.
You'll often see this kind of code in legacy projects. Mostly out of control anymore, it's usually the result of starting with these small breach and leaving it unrefactored. If possible, be proactive in refactoring.