Single Responsibility Principle (SRP) is one of the most important object-oriented coding principle which, if followed religiously, can help you write a very good quality code. Here is what SRP states:
A block code representing class or method should have just one reason to change
In other words, Single Responsibility Principle can be stated as the following:
A block of code representing class or a method should do just one thing and do it very well
In yet another words, SRP can also be stated as the following:
A block of code representing class or method should have just one responsibility or serve just one functionality
Pictorially, decide for yourself which one of the following you would use for the knife (all in one tool or a single knife):
Noting some of the following would help you understand SRP vis-a-vis reusability
With above, it can be inferred that a class that follows single responsibility principle can said to be more reusable.
In this post, you will learn about some of the following:
You may also want to check my another post on Liskov Substitution Principle using Java example.
The class, UserService, has an API createUser, whose responsibility is to create a user given a User object. The following are more than one reason why the class UserService can change and thus, it violates single responsibility principle (SRP).
public class UserService { private Logger logger = Logger.getLogger("com.training.core.srp.UserService"); public void createUser(User user) throws DBConnectionException { Connection connection = null; DataSource dataSource = null; // // Get the connection (reason to change) try { InitialContext initialContext = new InitialContext(); dataSource = (DataSource) initialContext.lookup("jdbc/tempDB"); } catch (NamingException e) { // Handle the exception using Logger } try { connection = dataSource.getConnection(); } catch (SQLException e) { logger.log(Level.SEVERE, "Issue connecting with database: " + e.getMessage()); throw new DBConnectionException(e.getMessage()); } // // Save the user (reason to change) // String sql = "INSERT INTO User (USER_ID, USERNAME) VALUES (?,?)"; try { PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setString(1, "some-user-id-123456"); pstmt.setString(2, "Ajitesh"); // execute insert SQL stetement pstmt.executeUpdate(); pstmt.close(); } catch (SQLException e) { logger.log(Level.WARNING, "Issue with saving the data: " + e.getMessage()); } } }
Given the fact that class, UserService, has got multiple reasons to change, which makes the class as non-cohesive, it can no longer be reused. That said, the class can be refactored appropriately to restore Single Responsibility Principle. The related code refactoring technique is also termed as Extract Class method.
The refactoring technique is Extract Class. The class UserService can be refactoried into following different classes to fix SRP violation:
With above design followed, the refactored code of UserService would look like following:
public class UserService { private UserDAO userDAO; public void createUser(User user) throws UserCreationException { userDAO.save(user); } public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } }
With above refactoring, the following happens as a result of fixing SRP:
The method, createUser, in the UserService class, violates the Single Responsibility Principle. It can also be noted that the code smell such as Long Method also applies to the method, createUser. The method has got multiple reasons to change as mentioned in above section. The method can change due to change in some of the following:
The recommended refactoring technique is Extract method. The createUser method can be refactored as following:
public void createUser(User user) throws DBConnectionException { saveUser(user); } private void saveUser(User user) throws DBConnectionException { // // Get the connection Connection connection = getConnection(); String sql = "INSERT INTO User (USER_ID, USERNAME) VALUES (?,?)"; try { PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setString(1, "some-user-id-123456"); pstmt.setString(2, "Ajitesh"); // execute insert SQL stetement pstmt.executeUpdate(); pstmt.close(); } catch (SQLException e) { logger.log(Level.WARNING, "Issue with saving the data: " + e.getMessage()); } } private Connection getConnection() throws DBConnectionException { Connection connection = null; DataSource dataSource = null; try { InitialContext initialContext = new InitialContext(); dataSource = (DataSource) initialContext.lookup("jdbc/tempDB"); } catch (NamingException e) { // Handle the exception using Logger } try {<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span> connection = dataSource.getConnection(); } catch (SQLException e) { logger.log(Level.SEVERE, "Issue connecting with database: " + e.getMessage()); throw new DBConnectionException(e.getMessage()); } return connection; }
Make a note of some of the following in refactored code:
In this post, you learned about some of the following:
Did you find this article useful? Do you have any questions about this article or understanding the single responsibility principle using Java? Leave a comment and ask your questions and I shall do my best to address your queries.
In recent years, artificial intelligence (AI) has evolved to include more sophisticated and capable agents,…
Adaptive learning helps in tailoring learning experiences to fit the unique needs of each student.…
With the increasing demand for more powerful machine learning (ML) systems that can handle diverse…
Anxiety is a common mental health condition that affects millions of people around the world.…
In machine learning, confounder features or variables can significantly affect the accuracy and validity of…
Last updated: 26 Sept, 2024 Credit card fraud detection is a major concern for credit…