A brief discussion on the open and Closed Principle of Java design mode

  • 2020-06-15 09:04:08
  • OfStack

Writing in the front

Recently, I took over a new business. The architecture of the system is commendable. But some areas are daunting, and some code is bloated and unmaintainable. Therefore, combined with Java's open and closed principle, one part of the code was reconstructed and optimized.

Let's look at the old code for the previous system

ShareChannelManager.java


public ResultDO<String> shareChannel(int shareCode) {

  if(ShareCodeUtil.share2A(shareCode)) {
     // TODO,  Share the A Channel business logic code 
  }

  if(ShareCodeUtil.share2B(shareCode)) {
     // TODO,  Share the B Channel business logic code 
  }

  ... channel n...
}

The shareChannel method carries the main link logic of the sharing channel. The code Shared to each channel is written in the method of 1 class, which is very bloated and hard to maintain. Every time you add a sharing channel, you have to modify this heavyweight method. A slight shake of the hand will affect other channels to share. It also violates the open and closed principle of Java.

Introduce the open and closed principle of Java

The open and closed principle of Java is a contradiction in terms. How can it be closed when it's open? Don't take it at face value. From two dimensions to think, ** open ** & *** Closed **. The open principle of Java means that the architecture is designed to be extensible; The closing principle means that the architecture master link of the system cannot be changed greatly with the business iteration, even if it is always whole, it only indicates that the architecture of the system has problems. Every system must go through a process from zero to one, and as the business grows, the system may stay the same. How to make the architecture of the system forward-looking and extensible are the technical points that we must consider in our daily development.
In conclusion, the open and closed principle of Java has two characteristics.

- Open for extension - Is closed for changes

Based on the above mentioned design principles, how to optimize the above mentioned problems

The idea is to make multiple sharing channels into a chain call. The sharing action is abstracted out and distributed to various channels for implementation.

Define the sharing channel chain


public class ShareChannelChain {  
  private final Logger LOG = LoggerFactory.getLogger(this.getClass());

  /**
   *  Sharing channel chain 
   */
  private List<ShareChannel> shareChannels;
  public ResultDO<String> share(int shareCode) {
    for (ShareChannel s : shareChannels) {
      ResultDO<String> r = s.share(shareCode);
         }
  }

Define the sharing channel parent class


public interface ShareChannel {
  public ResultDO<String> share(int shareCod);
}

A channel sharing


public class AChannel implements ShareChannel {

  @Override
  public ResultDO<String> share(int shareCode) {
       // TODO  share A The logical channel 
    }
}

B channel sharing


public class BChannel implements ShareChannel {

  @Override
  public ResultDO<String> share(int shareCode) {
       // TODO  share B The logical channel 
    }
}

Assemble AChannel and BChannel into 1 call chain ShareChannelChain.


  <bean id="AChannel" class="com.test.AChannel">
  </bean>
  <bean id="BChannel" class="com.test.BChannel">
  </bean>
  <bean id="shareChannelChain" class="com.test.ShareChannelChain">
    <property name="shareChannels">
      <list>
        <ref local="AChannel"/>
        <ref local="BChannel"/>
      </list>
    </property>
  </bean>

Channel sharing main interface

ShareChannelManager.java


public ResultDO<String> shareChannel(int shareCode) {
    ShareChannelChain.share(shareCode);
}

Finally, let's review the benefits of an optimized architecture

Let's say there's a new channel for sharing business requirements, CChannel, and think about what we need to change. You don't need to change the ShareChannelManager core class logic this time. You only need to expand 1 CChannel, implement ShareChannel interface share method, and then configure to xml. This risk can be controlled without touching the core class logic.


Related articles: