案例分析:设计模式与代码的结构特性

  软件设计模式分为三种类型:

  • 创建型
  • 结构型
  • 行为型

   本文以行为型中的模板方法模式(Template Method)为例,分析其代码结构特性

一、什么是模板模式方法?

 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板模式方法由抽象类和具体类组成:

  • 抽象类:
    1. 定义抽象的原语操作,具体子类将重定义它们来实现算法的步骤。
    2. 实现一个模板方法定义一个算法的构架。模板方法调用原语操作和抽象类或其他对象定义的操作。
  • 具体类:实现原语操作来执行算法中子类特有的步骤。

   模板方法模式中的方法可以分为两大类:模板方法和基本方法。

  • 模板方法

 一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
 一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。

  • 基本方法

 基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
 抽象方法:由抽象模板角色声明,abstract修饰,具体模板角色实现。
 具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。
 钩子方法:由抽象模板角色声明并实现,具体模板角色可实现加以扩展。

二、模板模式UML图

三、分析其代码结构特性

  •  引用关键代码(引用代码是为解释说明服务的,不要贴对解释问题无关的代码)解释该设计模式在该应用场景中的适用性;
  • /*抽象类:消息发送*/
    public abstract class MessageSender {
    
        //发送 
        public void send(String content) {
            verification(content);
            if (!execute(content)) {
                error(content);
            }
        }
    
      //验证
        protected abstract void verification(String content);
      //判断是否成功发送
        protected abstract boolean execute(String content);
       //错误记录
        protected abstract void error(String content);
    }
    /* 短信*/
    public class SmsSender extends MessageSender {
    
        //验证
        @Override
        protected void verification(String content) {
            if (content == null || "".equals(content.trim()) || content.trim().length() != 11) {
                throw new RuntimeException("手机号码不合法!");
            }
        }
    
        //判断
        @Override
        protected boolean execute(String content) {
            Random random = new Random();
            if (random.nextInt(10) % 2 == 0) {
                System.out.println("短信发送成功!");
                return true;
            } else {
                return false;
            }
        }
    
        //错误 
        @Override
        protected void error(String content) {
            System.err.println("短信发送失败!");
        }
    }
    /* 邮件 */
    public class EmailSender extends MessageSender {
        //验证 
        @Override
        protected void verification(String content) {
            if (content == null || "".equals(content.trim())) {
                throw new RuntimeException("数据为空!");
            }
        }
    
        //判断
        @Override
        protected boolean execute(String content) {
            Random random = new Random();
            if (random.nextInt(10) % 2 == 0) {
                System.out.println("邮件发送成功!");
                return true;
            } else {
                return false;
            }
        }
    
        //错误
        @Override
        protected void error(String content) {
            System.err.println("邮件发送失败!");
        }
    }
    /* 测试类*/
    public class PatternTest {
        public static void main(String[] args) {
            //邮件发送 
            EmailSender emailSender = new EmailSender();
            emailSender.send("测试");
            //短信发送 
            SmsSender smsSender = new SmsSender();
            smsSender.send("12345678901");
        }
    }

     

 

  •  引入该设计模式后对系统架构和代码结构带来了哪些好处;
    • 提高代码复用性
      将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中
    • 实现了反向控制
      通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制,符合“开闭原则”。
  •  解释其中用到的多态机制;

  多态性是对象多种表现形式的体现。多态存在的三个必要条件是:继承,重写,父类引用指向子类对象。

  本例定义了抽象类“MessageSender”,”SmsSender"和“EmailSender"继承自抽象类,分别重写了抽象类的verification,execute,error三个方法。

  •  说明模块抽象封装的方法;

        通过对类的方法赋予指定的修改符”protected“来达到封装的目的,使得数据不被外部对象恶意的访问及方法不被错误调用导造成破坏对象的封装性。

  •  分析各个模块的内聚度和模块之间的耦合度;

  通过定义抽象类“MessageSender”,将逻辑上相关的抽象放在一起,将抽象的消息发送和具体发送方式分离,降低耦合度。

posted on 2019-12-08 17:45  suseso  阅读(224)  评论(0)    收藏  举报

导航