设计模式之为什么要学好设计模式

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 设计模式之为什么要学好设计模式

1 回顾软件设计原则

文章推荐IDEA快速构建UML类图:https://blog.csdn.net/ZGL_cyy/article/details/118278233


不用设计模式并非不可以,但是用好设计模式能帮助我们更好地解决实际问题,设计模式最重要的是解耦。设计模式天天都在用,但自己却无感知。我们把设计模式作为一个专题,主要是学习设计模式是如何总结经验的,把经验为自己所用。学设计模式也是锻炼将业务需求转换技术实现的一种非常有效的方式。

设计原则 解释
开闭原则 对扩展开放,对修改关闭
依赖倒置原则 通过抽象使各个类或者模块不相互影响,实现松耦合。
单一职责原则 一个类、接口、方法只做一件事。
接口隔离原则 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口。
迪米特法则 又叫最少知道原则,一个类对其所依赖的类知道得越少越好。
里氏替换原则 子类可以扩展父类的功能但不能改变父类原有的功能。
合成复用原则 尽量使用对象组合、聚合,而不使用继承关系达到代码复用的目的。

2 设计模式总览

写出优雅的代码以下是超级乱的代码

    public void setExammingForm(ExammingForm curForm,String parameters)throws BaseException {                                                                             
              ...
        JSONObject jsonObj = new JSONObject(parameters);
        //试卷主键                                                 
        if(jsonObj.getString("examinationPaper_id")!= null && (!jsonObj.getString ("examinationPaper_id").equals("")))
            curForm.setExaminationPaper_id(jsonObj.getLong("examinationPaper_id"));
        //剩余时间                                                 
        if(jsonObj.getString("leavTime") != null && (!jsonObj.getString("leavTime").equals("")))
            curForm.setLeavTime(jsonObj.getInt("leavTime"));
        //单位主键                                                 
        if(jsonObj.getString("organization_id")!= null && (!jsonObj.getString ("organization_id").equals("")))
            curForm.setOrganization_id(jsonObj.getLong("organization_id"));
        //考试主键                                                 
        if(jsonObj.getString("id")!= null && (!jsonObj.getString("id").equals("")))
            curForm.setId(jsonObj.getLong("id"));
        //考场主键                                                 
        if(jsonObj.getString("examroom_id")!= null && (!jsonObj.getString ("examroom_id").equals("")))
            curForm.setExamroom_id(jsonObj.getLong("examroom_id"));
        //用户主键                                                 
        if(jsonObj.getString("user_id")!= null && (!jsonObj.getString("user_id").equals("")))
            curForm.setUser_id(jsonObj.getLong("user_id"));
        //专业代码                                                 
        if(jsonObj.getString("specialtyCode")!= null && (!jsonObj.getString ("specialtyCode").equals("")))
            curForm.setSpecialtyCode(jsonObj.getLong("specialtyCode"));
        //报考岗位                                                 
        if(jsonObj.getString("postionCode")!= null && (!jsonObj.getString ("postionCode").equals("")))
            curForm.setPostionCode(jsonObj.getLong("postionCode"));
        //报考等级                                                 
        if(jsonObj.getString("gradeCode")!= null && (!jsonObj.getString ("gradeCode").equals("")))
            curForm.setGradeCode(jsonObj.getLong("gradeCode"));
        //考试开始时间                                             
        curForm.setExamStartTime(jsonObj.getString("examStartTime"));
        //考试结束时间                                             
        curForm.setExamEndTime(jsonObj.getString("examEndTime"));  
              ...
    }

优雅的赋值:

注:这里的下划线可以转换一下驼峰这里我要总结几篇文章

@JSONType(naming= PropertyNamingStrategy.SnakeCase)

    public class ExammingFormVo extends ExammingForm{
        private String examinationPaperId; //试卷主键              
        private String leavTime; //剩余时间                        
        private String organizationId; //单位主键                  
        private String id; //考试主键                              
        private String examRoomId; //考场主键                      
        private String userId; //用户主键                          
        private String specialtyCode; //专业代码                   
        private String postionCode; //报考岗位                     
        private String gradeCode; //报考等级                       
        private String examStartTime; //考试开始时间               
        private String examEndTime; //考试结束时间                 
              ...
    }
    public void setExammingForm(ExammingForm form,String parameters)throws BaseException {
        try {
            JSONObject json = new JSONObject(parameters);
            ExammingFormVo vo = JSONObject.parseObject(json,ExammingFormVo.class);
            form = vo;
        }catch (Exception e){
            e.printStackTrace();
        }
    }

更好地重构项目

请查看以下代码发现问题

  public void save(Student stu){
                String sql = "INSERT INTO t_student(name,age) VALUES(?,?)";
        Connection conn = null;
        Statement st = null;
        try{
            //1. 加载注册驱动                                          
            Class.forName("com.mysql.jdbc.Driver");
            //2. 获取数据库连接                                        
            conn=DriverManager.getConnection("jdbc:mysql:///jdbc_demo","root","root");
            //3. 创建语句对象                                          
            PreparedStatement ps=conn.prepareStatement(sql);
            ps.setObject(1,stu.getName());
            ps.setObject(2,stu.getAge());
            //4. 执行SQL语句                                           
            ps.executeUpdate();
            //5. 释放资源                                              
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(st != null)
                    st.close();
            }catch(SQLException e){
                e.printStackTrace();
            }finally{
                try{
                    if(conn != null)
                        conn.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
    //删除学生信息                                             
    public void delete(Long id){
        String sql = "DELETE FROM t_student WHERE id=?";
        Connection conn = null;
        Statement st = null;
        try{
            //1. 加载注册驱动                                          
            Class.forName("com.mysql.jdbc.Driver");
            //2. 获取数据库连接                                        
            conn=DriverManager.getConnection("jdbc:mysql:///jdbc_demo","root","root");
            //3. 创建语句对象                                          
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setObject(1,id);
            //4. 执行SQL语句                                           
            ps.executeUpdate();
            //5. 释放资源                                              
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(st != null)
                    st.close();
            }catch(SQLException e){
                e.printStackTrace();
            }finally{
                try{
                    if(conn != null)
                        conn.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
    //修改学生信息                                             
    public void update(Student stu){
        String sql = "UPDATE t_student SET name=?,age=? WHERE id=?";
        Connection conn = null;
        Statement st = null;
        try{
            //1. 加载注册驱动                                          
            Class.forName("com.mysql.jdbc.Driver");
            //2. 获取数据库连接                                        
            conn=DriverManager.getConnection("jdbc:mysql:///jdbc_demo","root","root");
            //3. 创建语句对象                                          
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setObject(1,stu.getName());
            ps.setObject(2,stu.getAge());
            ps.setObject(3,stu.getId());
            //4. 执行SQL语句                                           
            ps.executeUpdate();
            //5. 释放资源                                              
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(st != null)
                    st.close();
            }catch(SQLException e){
                e.printStackTrace();
            }finally{
                try{
                    if(conn != null)
                        conn.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }

上述代码的功能没问题,但是代码重复得太多,因此可以进行抽取,把重复代码放到一个工具类JdbcUtil里。

工具类:

  public class JdbcUtil {
        private JdbcUtil() { }
        static {
            //1. 加载注册驱动                                          
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        public static Connection getConnection() {
            try {
                //2. 获取数据库连接                                        
                return DriverManager.getConnection("jdbc:mysql:///jdbc_demo", "root", "root");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        //释放资源                                                 
        public static void close(ResultSet rs, Statement st, Connection conn) {
            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (st != null)
                        st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (conn != null)
                            conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

只需要在实现类中直接调用工具类JdbcUtil中的方法即可。

    //增加学生信息
    public void save(Student stu) {
        String sql = "INSERT INTO t_student(name,age) VALUES(?,?)";
        Connection conn = null;
        PreparedStatement ps=null;
        try {
            conn = JDBCUtil.getConnection();
            //3. 创建语句对象
            ps = conn.prepareStatement(sql);
            ps.setObject(1, stu.getName());
            ps.setObject(2, stu.getAge());
            //4. 执行SQL语句
            ps.executeUpdate();
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null, ps, conn);
        }
    }
    //删除学生信息
    public void delete(Long id) {
        String sql = "DELETE FROM t_student WHERE id=?";
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn=JDBCUtil.getConnection();
            //3. 创建语句对象
            ps = conn.prepareStatement(sql);
            ps.setObject(1, id);
            //4. 执行SQL语句
            ps.executeUpdate();
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null, ps, conn);
        }
    }
    //修改学生信息
    public void update(Student stu) {
        String sql = "UPDATE t_student SET name=?,age=? WHERE id=?";
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn=JDBCUtil.getConnection();
            //3. 创建语句对象
            ps = conn.prepareStatement(sql);
            ps.setObject(1, stu.getName());
            ps.setObject(2, stu.getAge());
            ps.setObject(3, stu.getId());
            //4. 执行SQL语句
            ps.executeUpdate();
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(null, ps, conn);
        }
    }
    public Student get(Long id) {
        String sql = "SELECT * FROM t_student WHERE id=?";
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        PreparedStatement ps=null;
        try {
            conn = JDBCUtil.getConnection();
            //3. 创建语句对象
            ps = conn.prepareStatement(sql);
            ps.setObject(1, id);
            //4. 执行SQL语句
            rs = ps.executeQuery();
            if (rs.next()) {
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Student stu = new Student(id, name, age);
                return stu;
            }
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(rs, ps, conn);
        }
        return null;
    }
    public List<Student> list() {
        List<Student> list = new ArrayList<>();
        String sql = "SELECT * FROM t_student ";
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        PreparedStatement ps=null;
        try {
            conn=JDBCUtil.getConnection();
            //3. 创建语句对象
            ps = conn.prepareStatement(sql);
            //4. 执行SQL语句
            rs = ps.executeQuery();
            while (rs.next()) {
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Student stu = new Student(id, name, age);
                list.add(stu);
            }
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(rs, ps, conn);
        }
        return list;
    }

虽然完成了重复代码的抽取,但数据库中的账号密码等直接显示在代码中,不利于后期账户密码改动的维护。可以建立一个db.propertise文件,用来存储这些信息。

      driverClassName=com.mysql.jdbc.Driver 
              url=jdbc:mysql:///jdbcdemo            
              username=root                         
              password=root                         

只需要在工具类JdbcUtil中获取里面的信息即可。

    static {
        //1. 加载注册驱动                                          
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            InputStream inputStream = loader.getResourceAsStream("db.properties");
            p = new Properties();
            p.load(inputStream);
            Class.forName(p.getProperty("driverClassName"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection() {
        try {
            //2. 获取数据库连接                                        
            return DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"),
                    p.getProperty("password"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

代码抽取到这里,貌似已经完成,但在实现类中,依然存在部分重复代码,在DML操作中,除了SQL和设置值的不同,其他都相同,把相同的部分抽取出来,把不同的部分通过参数传递进来,无法直接放在工具类中。此时,可以创建一个模板类JdbcTemplate,创建一个DML和DQL的模板来对代码进行重构。

    //查询统一模板
    public static List<Student> query(String sql,Object...params){
        List<Student> list=new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps=null;
        ResultSet rs = null;
        try {
            conn=JDBCUtil.getConnection();
            ps=conn.prepareStatement(sql);
            //设置值
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Student stu = new Student(id, name, age);
                list.add(stu);
            }
            //5. 释放资源
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(rs, ps, conn);
        }
        return list;
    }
    实现类直接调用方法即可。
    //增加学生信息
    public void save(Student stu) {
        String sql = "INSERT INTO t_student(name,age) VALUES(?,?)";
        Object[] params=new Object[]{stu.getName(),stu.getAge()};
        JdbcTemplate.update(sql, params);
    }
    //删除学生信息
    public void delete(Long id) {
        String sql = "DELETE FROM t_student WHERE id = ?";
        JdbcTemplate.update(sql, id);
    }
    //修改学生信息
    public void update(Student stu) {
        String sql = "UPDATE t_student SET name = ?,age = ? WHERE id = ?";
        Object[] params=new Object[]{stu.getName(),stu.getAge(),stu.getId()};
        JdbcTemplate.update(sql, params);
    }
    public Student get(Long id) {
        String sql = "SELECT * FROM t_student WHERE id=?";
        List<Student> list = JDBCTemplate.query(sql, id);
        return list.size()>0? list.get(0):null;
    }
    public List<Student> list() {
        String sql = "SELECT * FROM t_student ";
        return JDBCTemplate.query(sql);
    }

这样重复的代码基本就解决了,但有一个很严重的问题,就是这个程序DQL操作中只能处理Student类和t_student表的相关数据,无法处理其他类,比如Teacher类和t_teacher表。不同的表(不同的对象)应该有不同的列,不同列处理结果集的代码就应该不一样,处理结果集的操作只有DAO自己最清楚。也就是说,处理结果的方法根本就不应该放在模板方法中,应该由每个DAO自己来处理。因此,可以创建一个IRowMapper接口来处理结果集。

    public interface IRowMapper {
        //处理结果集                                   
        List rowMapper(ResultSet rs) throws Exception;
    }

DQL模板类中调用IRowMapper接口中的handle方法,提醒实现类自己去实现mapping方法。

public static List<Student> query(String sql,IRowMapper rsh, Object...params){
        List<Student> list = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps=null;
        ResultSet rs = null;
        try {
            conn = JdbcUtil.getConnection();
            ps = conn.prepareStatement(sql);
            //设置值                                                   
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            rs = ps.executeQuery();
            return rsh.mapping(rs);
            //5. 释放资源                                              
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs, ps, conn);
        }
        return list ;
    }

实现类自己去实现IRowMapper接口的mapping方法,想要处理什么类型的数据在里面定义即可。

    public Student get(Long id) {
        String sql = "SELECT * FROM t_student WHERE id = ?";
        List<Student> list = JdbcTemplate.query(sql,new StudentRowMapper(), id);
        return list.size()>0? list.get(0):null;
    }
    public List<Student> list() {
        String sql = "SELECT * FROM t_student ";
        return JdbcTemplate.query(sql,new StudentRowMapper());
    }
    class StudentRowMapper implements IRowMapper{
        public List mapping(ResultSet rs) throws Exception {
            List<Student> list=new ArrayList<>();
            while(rs.next()){
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Student stu=new Student(id, name, age);
                list.add(stu);
            }
            return list;
        }
    }

到这里为止,实现ORM的关键代码已经大功告成,但是DQL查询不单单要查询学生信息(List类型),还要查询学生数量,这时就要通过泛型来完成。

    public interface IRowMapper<T> {
        //处理结果集                                               
        T mapping(ResultSet rs) throws Exception;
    }
    public static <T> T query(String sql,IRowMapper<T> rsh, Object...params){
        Connection conn = null;
        PreparedStatement ps=null;
        ResultSet rs = null;
        try {
            conn = JdbcUtil.getConnection();
            ps = conn.prepareStatement(sql);
            //设置值                                                   
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            rs = ps.executeQuery();
            return rsh.mapping(rs);
            //5. 释放资源                                              
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(rs, ps, conn);
        }
        return null;
    }

StudentRowMapper类的代码如下。

    class StudentRowMapper implements IRowMapper<List<Student>>{
        public List<Student> mapping(ResultSet rs) throws Exception {
            List<Student> list=new ArrayList<>();
            while(rs.next()){
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                Student stu=new Student(id, name, age);
                list.add(stu);
            }
            return list;
        }
    }

这样,不仅可以查询List,还可以查询学生数量。

public Long getCount(){
        String sql = "SELECT COUNT(*) total FROM t_student";
        Long totalCount = (Long) JdbcTemplate.query(sql,
                new IRowMapper<Long>() {
                    public Long mapping(ResultSet rs) throws Exception {
                        Long totalCount = null;
                        if(rs.next()){
                            totalCount = rs.getLong("total");
                        }
                        return totalCount;
                    }
                });
        return totalCount;
    }

这样,重构设计就已经完成,好的代码能让我们以后维护更方便,因此学会对代码的重构是非常重要的。

3 经典框架都在用设计模式解决问题

比如,Spring就是一个把设计模式用得淋漓尽致的经典框架。本书会结合JDK、Spring、MyBatis、Netty、Tomcat、Dubbo等经典框架的源码对设计模式展开分析,帮助大家更好、更深入地理解设计模式在框架源码中的落地。

经典框架都在用设计模式解决问题

Spring就是一个把设计模式用得淋漓尽致的经典框架,其实从类的命名就能看出来,我来一一列举:

设计模式名称 举例
工厂模式 BeanFactory
装饰器模式 BeanWrapper
代理模式 AopProxy
委派模式 DispatcherServlet
策略模式 HandlerMapping
适配器模式 HandlerAdapter
模板模式 JdbcTemplate
观察者模式 ContextLoaderListener

围绕 Spring 的 IOC、AOP、MVC、JDBC这样的思路展开,根据其设计类型来设计讲解顺序:

类型 名称 英文
创建型模式 工厂模式 Factory Pattern

单例模式
Singleton Pattern
原型模式 Prototype Pattern
结构型模式 适配器模式 Adapter Pattern
装饰器模式 Decorator Patter
代理模式 Proxy Pattern
行为性模式 策略模式 Strategy Pattern
模板模式 Template Pattern
委派模式 Delegate Pattern
观察者模式 Observer Pattern


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
设计模式 算法 架构师
【搞懂设计模式】设计模式与面向对象原则
【搞懂设计模式】设计模式与面向对象原则
77 1
|
设计模式 存储 消息中间件
设计模式之美(二)——设计模式
《设计模式之美》是极客时间上的一个代码学习系列,在学习之后特在此做记录和总结。
设计模式之美(二)——设计模式
|
设计模式 SQL Java
为什么一定要学习设计模式
先来看一个生活案例,当我们开心时,也许会寻求享乐。在学习设计模式之前,你可能会这样感叹:
59 0
|
设计模式 算法
设计模式学习
设计模式学习
|
设计模式 算法 安全
设计模式日常学习(四)
三.原型模式 概述 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。 结构 原型模式包含如下角色: ● 抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。 ● 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。 ● 访问类:使用具体原型类中的 clone() 方法来复制新的对象。 实现 原型模式的克隆分为浅克隆和深克隆。 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。 Ja
77 0
|
设计模式 存储 安全
设计模式日常学习(五)
五.结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: ● 代理模式 ● 适配器模式 ● 装饰者模式 ● 桥接模式 ● 外观模式 ● 组合模式 ● 享元模式 5.1.代理模式 5.1.1 概述 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
121 0
|
存储 设计模式 算法
设计模式日常学习(六)
六.行为型模式 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: ● 模板方法模式 ● 策略模式 ● 命令模式 ● 职责链模式 ● 状态模式 ● 观察者模式 ● 中介者模式 ● 迭代器模式 ● 访问者模式 ● 备忘录模式 ● 解释器模式 以上 11 种行为型模
85 0
|
设计模式 存储 Java
设计模式日常学习(三)
创建者模式 二.工厂模式 在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则。如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦。 ● 简单工厂模式(不属于GOF的23种经典设计模式) ● 工厂方法模式 ● 抽象工厂模式 1.简单工厂模式 简单工厂不是一种设计模式,反而比较像是一种编程习惯。 1.1 结构 简单工厂包含如下角色: ●
96 0
|
设计模式 数据可视化 程序员
设计模式日常学习(一)
设计模式 软件设计模式的概念 软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。 学习设计模式的必要性 设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。 正确使用设计模式具有以下优点。 ● 可以提高程序员的思维能力、编程能力和设计能力。 ● 使程序设计更加标准化、代
118 0