Understanding Open/Closed Principle (OCP) from the SOLID OO principles with a simple Java example
Spring Interview Questions and Answers Q1 - Q14 are FAQs
Q. Is there anything wrong with the following class design? If yes, can the design be improved?
package com.ocp; import javax.management.RuntimeErrorException; import org.apache.commons.lang.StringUtils; public class MathOperation { public int operate(int input1, int input2, String operator){ if(StringUtils.isEmpty(operator)){ throw new IllegalArgumentException("Invalid operator: " + operator); } if(operator.equalsIgnoreCase("+")){ return input1 + input2; } else if(operator.equalsIgnoreCase("*")){ return input1 * input2; } else { throw new RuntimeException("unsupported operator: " + operator); } } }
JUnit test class.
package com.ocp; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; public class MathOperationTest { MathOperation operation; @Before public void init(){ operation = new MathOperation(); } @Test public void testAddition() { Assert.assertEquals(8, operation.operate(5, 3, "+")); } @Test public void testMultiplication() { Assert.assertEquals(15, operation.operate(5, 3, "*")); } }
A. It’s not a good idea to try to anticipate changes in requirements ahead of time, but you should focus on writing code that is well written enough so that it’s easy to change. This means, you should strive to write code that doesn't have to be changed every time the requirements change. This is what the Open/Closed principle is. According to GoF design pattern authors "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". Spring framework promotes this principle.
In the above example, you can anticipate more operators like "-" (subtraction) and division (/) to be supported in the future and the class "MathOperation" is not closed for modification. When you need to support operators "-" and "%" you need to add 2 more "else if" statements. Whenever you see large if/else or switch statements, you need to think if "Open/Closed" design principle is more suited.
Let's open for extension and close for modifications
In the rewritten example below, the classes AddOperation and MultiplyOperation are closed for modification, but open for extension by allowing you to add new classes like SubtractOperation and DivisionOperation by implementing the Operation interface.
Define the interface Operation.
package com.ocp; public interface Operation { abstract int operate(int input1, int input2); }
Define the implementations
package com.ocp; public class AddOperation implements Operation { @Override public int operate(int input1, int input2) { return input1 + input2; } }
package com.ocp; public class MultiplyOperation implements Operation { @Override public int operate(int input1, int input2) { return input1 * input2; } }
Finally, the JUnit test class
package com.ocp; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; public class MathOperation2Test { Operation operation; @Test public void testAddition() { operation = new AddOperation(); Assert.assertEquals(8, operation.operate(5, 3)); } @Test public void testMultiplication() { operation = new MultiplyOperation(); Assert.assertEquals(15, operation.operate(5, 3)); } }
This is only a trivial example, but in real life applications, wherever you have large if/else statements, you need to think if OCP can be applied. Spring framework promotes this principle.
Q. Can you explain if the following classes are badly designed?
Labels: design pattern, OO
1 Comments:
Your blog is really very informative and useful for me..Thanks for sharing such a nice blog..
JAVA Training
Post a Comment
Subscribe to Post Comments [Atom]
<< Home