Software design - Preliminary Thinking on modular design I

Software design - Preliminary Thinking on modular design I

Modular design

Note: modular design, in short, means that the programming does not start by inputting computer statements and instructions one by one, but first describes the main structure and process of the software with the framework of main program, subroutine and subprocess,
And define and debug the input and output link relationship between each framework.
The result of step-by-step refinement is a series of algorithm descriptions in functional blocks.
The method of programming with function blocks as units and realizing its solution algorithm is called modularization.
The purpose of modularization is to reduce program complexity and simplify program design, debugging and maintenance.
To change a sub function, you only need to change the corresponding module.

Recently, I had a whim in designing software and recorded my thinking on modular design

first

During requirement analysis, all possible functions and functions that may be expanded in the future should be understood as much as possible
When we sort out all the functions, we should modularize them. (if we have enough experience, we can think directly from top to bottom.) for novices, the simplest way is to list all the functions, classify them and abstract them.

give an example

We analyze from the start module (personal module) of a software. For personal module, we can analyze the following functions

  • Sign in
  • register
  • Forget password
  • frozen
  • Apply for unfreezing
  • Audit user status

Authentication method involved in login:

  1. Account verification
  2. Mailbox verification
  3. Mobile number verification
  4. . . . (others can be added)

Verify user uniqueness at registration

  1. Mailbox verification
  2. Mobile number verification
  3. . . . (QQ, WeChat ... and so on)

There is a status reminder during freezing and unfreezing

  1. Email reminder
  2. SMS reminder

At the same time
During login, registration, freezing and unfreezing:
1. You can abstract out a Verify interface
The specific implementation can be

  • Mailbox verification
  • Mobile number verification

2. You can abstract out a Sender interface
The specific implementation can be

  • Email send
  • Mobile number sending

Therefore, the specific implementation of Verify will be aggregated in the user module
Specific implementation of Sender

in addition
We can configure the sent content through the configuration file. When there are many modules, we can configure the abstract class
- > configuration class

code

This is how I designed the Verify interface

package com.ss.account.verify;

public interface Verify {

    boolean verifyAccount(String account);

}

Verify interface implementation class

package com.ss.account.verify;

public class MailVerify implements Verify{

    @Override
    public boolean verifyAccount(String account) {
        //TODO 
        System.out.println("verifyAccount : " + account);
        return true;
    }
}

Sender interface

package com.ss.account.sender;

public interface Sender {

    //send message
    boolean sendMessage(String account, String message);

    //send content
    boolean sendVerifyCode(String account,String code);

    //Content validation
    boolean checkContent(String content);
}

The abstract implementation class of the Sender interface can have a default implementation for content verification (take the content length less than 200 as an example)

package com.ss.account.sender;

public class AbstractSender implements Sender{
    @Override
    public boolean sendMessage(String account,String message) {
        return false;
    }

    @Override
    public boolean sendVerifyCode(String account,String code) {
        return false;
    }

    @Override
    public boolean checkContent(String content) {
        return content.length() < 200 ;
    }
}

Concrete implementation of AbstractSender Abstract implementation class

package com.ss.account.sender;

public class MailSender extends AbstractSender{

    @Override
    public boolean sendMessage(String account, String message) {
        checkContent(message);
        System.out.println("send message : " + message);
        return true;
    }

    @Override
    public boolean sendVerifyCode(String account, String code) {
        checkContent(code);
        System.out.println("send verify code : " + code);
        return true;
    }
}

Main class

package com.ss.account.main;

import com.ss.account.sender.MailSender;
import com.ss.account.sender.Sender;
import com.ss.account.verify.MailVerify;
import com.ss.account.verify.Verify;

public class AccountModularity {

    //Sending interface implementation
    private Sender sender;

    //Verify interface implementation
    private Verify verify;

    public AccountModularity() {
        init();
    }

    private void init() {
        sender = new MailSender();
        verify = new MailVerify();
    }

    private String sendVerifyCode(String account) {
        //TODO processing logic
        String code = "123asd";
        return sender.sendVerifyCode(account,code) ? code : null;
    }

    public boolean verifyAccount(String account) {
        //TODO processing logic
        return verify.verifyAccount(account);
    }
}

The module needs to be initialized, so there is an init method
Assign a value to its attribute

advantage

The benefits of such modular design
1. High scalability
All specific implementations can be extended
2. High cohesion, low coupling. (think again)
Other modules are independent of this module,
3. High reuse
In the future, the newly designed software can directly move the whole module, and only need to change the specific implementation without major changes.

last

For interface oriented programming and modular design, the first thinking summary will be updated in the future

Tags: Java Back-end architecture

Posted on Sun, 05 Dec 2021 17:58:17 -0500 by Volte