软件设计-模块化设计初思考二

软件设计-模块化设计初思考二

书接上回

我们已经
设计了Sender接口 用来实现信息的发送,为此我们做了两个实现类,分别实现,邮箱发送与短信发送。(实现类,未实现功能)
设计了 Verify接口 用来实现 不同的验证方式 为此我们做了两个实现类 ,分别实现,邮箱验证与账号验证。(实现类,未实现功能)

我们将接口聚合于 AccountModularity 类 代码如下

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 {

    //发送接口 实现
    private Sender sender;

    //验证接口 实现
    private Verify verify;

    public AccountModularity() {
        init();
    }

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

    private String sendVerifyCode(String account) {
        //TODO 处理逻辑
        String code = "123asd";
        return sender.sendVerifyCode(account,code) ? code : null;
    }

    public boolean verifyAccount(String account) {
        //TODO 处理逻辑
        return verify.verifyAccount(account);
    }
}

AccountModularity类的升级

今天我们要对这个类进行升级
升级之前,我们在看看需要的功能:

  • 登录
  • 注册
  • 修改个人信息
  • 验证账号是否存在(隐藏功能)

首先,我们来分析一下,具体功能

登录

登录 所需要的参数 可以是 邮箱 账号 手机号 。。。
返回的参数可以是 用户实体类,

问题:

1、用户实体类 不能固定,应该根据不同的实体类返回值不同
2、登录时、参数不同。

解决

1、可以将 用户实体类 抽象出来,作为泛型。
2、可以将具体不同的验证抽象出来,没错,我们已经抽象出来了 就是 Verify接口 还记得其作用吗? 实现不同的验证方式。

同理可得 注册修改密码 需要使用泛型 是否需要不同的接口,我们再行思考。

于此 ,我们已经发现,AccountModularity 并不是一个实现类,而是定义了一套规范,因此,我们将其做成具有泛型的抽象类。
代码如下:

package com.ss.account.main;

import com.ss.account.sender.Sender;
import com.ss.account.verify.Verify;
import com.ss.main.BaseModularity;
import com.ss.main.Lifecycle;

/**
 * @author Jangs
 * @param <T> 用户类
 */
public abstract class AccountModularity<T> {

    //发送接口 实现
    protected Sender sender;

    //验证接口 实现
    protected Verify verify;

    /**
     * 保护构造器
     */
    protected AccountModularity() {
    }

    /**
     * 发送 验证码
     * @param account 用户
     * @return String 验证码
     */
    protected abstract String sendVerifyCode(String account) ;

    /**
     * 验证用户是否存在
     * @param account 用户
     * @return boolean 是否存在
     */
    protected abstract boolean verifyAccount(String account);

    /**
     * 登录
     * @return T 用户实体类
     */
    protected abstract T login();

    /**
     * 注册
     * @param t 用户实体类
     */
    protected abstract void register(T t);

    /**
     * 修改个人信息
     * @param t 用户实体类
     */
    protected abstract void updateAccountInfo(T t);

}

边界化

在此,我提出模块化开发的一个理解 : 边界化

说明

1、模块内的所有方法,都必须是不能直接被外部访问的
2、提供一个 public 入口方法,来调用其他方法。

举一个例子

我们设计了一个房子,在房子内部 设计了它很多的功能,可以做饭,可以洗澡,可以睡觉,但是这些内容都是在房子内部完成的。

如果,我们想要去做饭,我们应该怎么办?
我们需要从门口进入,进入厨房,做饭,出厨房的同时带出饭菜。
这是一整套流程,
我们模块内的所有方法,都必须是不能直接被外部访问的,如果可以直接被外部访问,就好像,我们去做饭不需要进房间一样,那么房子的意义在哪里呢?(家徒无四壁)。别人可以随随便便的进入你家的厨房,去你家洗澡,碎觉。

再举一个例子

我们是一个人,我们可能做很多的事情,但是,当我们需要别人的帮助时,比方,需要他人借给我点钱。
这时我们需要怎么做呢?
直接掏他的口袋,去拿钱?且不说能不能成功,你伸进去的时候,你也被打了。而且,现在都是电子货币。
那正常情况下,我们需要怎么做呢?
第一步、我们需要通知他,我想借点钱。
第二步、由他自己决定,要不要,借钱给我们。

我们不能主宰别人的行为,我们需要通知告知Ta 让Ta 自己来做。

因此,我们的 AccountModularity类 需要以下几项优化
1、将类,修改成抽象类, AbstractAccountModularity类
2、我们需要提供一个 入口方法,鉴于,以后的模块都需要此方法,我们直接抽象成抽象类BaseModularity (仅 提供入口方法)

入口抽象类

代码如下:

package com.ss.main;

/**
 * @author Jangs
 * 此类 仅提供入口方法
 */
public abstract class BaseModularity {
    /**
     * 入口方法
     */
    public abstract void doService();
    
}

再来

我们设计一个房子(模块) 但是,我们也仅仅是提供各种可能性,具体建设,我们不能定义,最后,销毁,我们不可定义
所以,我设计一个生命周期接口,去统一所有模块的初始化与销毁工作。

Lifecycle接口
package com.ss.main;

/**
 * @author Jangs
 */
public interface Lifecycle {
    /**
     * 初始化
     */
    void init();

    /**
     * 销毁
     */
    void destroy();
}

设计此模块的好处如下“
1、统一初始化与销毁
2、为后期多模块组合,树状初始化做装备。
最后我们优化的

本期最终优化成果

AbstractAccountModularity 如此

package com.ss.account.main;

import com.ss.account.sender.Sender;
import com.ss.account.verify.Verify;
import com.ss.main.BaseModularity;
import com.ss.main.Lifecycle;

/**
 * @author Jangs
 * @param <T> 用户类
 */
public abstract class AbstractAccountModularity<T> extends BaseModularity implements Lifecycle {

    //发送接口 实现
    protected Sender sender;

    //验证接口 实现
    protected Verify verify;

    /**
     * 发送 验证码
     * @param account 用户
     * @return String 验证码
     */
    protected abstract String sendVerifyCode(String account) ;

    /**
     * 验证用户是否存在
     * @param account 用户
     * @return boolean 是否存在
     */
    protected abstract boolean verifyAccount(String account);

    /**
     * 登录
     * @return T 用户实体类
     */
    protected abstract T login(String account, String password);

    /**
     * 注册
     * @param t 用户实体类
     */
    protected abstract void register(T t);

    /**
     * 修改个人信息
     * @param t 用户实体类
     */
    protected abstract void updateAccountInfo(T t);

}

自此完成

对于 用户模块的抽象已经实现并优化,但是,具体如何调用?我们下期分解
在此我提出几个问题
1、如何实现不同的验证?
2、如果以后同时实现两种验证方式,我们该如何扩展与优化?
3、如果,以后此模块需要扩展,如何扩展?
4、如果,以后需要跟其他模块一同合作,如何链接?
5、我大量使用集成,java又不能实现多继承,日后扩展如何?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值