Java 23种设计模式之策略模式(二)

1.策略模式到底是什么?

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

简单的说,策略模式代表了一类算法的通用解决方案,你可以在运行时选择使用哪种解决方案。

1.1策略模式的重心

策略模式的重心不是如何实现算法, 而是如何组织、调用这些算法, 从而使得程序结构更加灵活,具有更好的维护性和扩展性。

1.2算法的平等性

策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,地位都是一样的,因此可以实现算法之间可以互相替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。

1.3运行时策略的唯一性

运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。

1.4公有的行为

经常见到的是,所有的具体策略都有一些公有的行为。这时候,就应该把这些公有的行为放到共同的抽象策略角色

2.策略模式的结构

策略模式包含三部分内容:(如下图所示)

  • a.一个或多个使用策略对象的客户.(环境角色)
  • b.一个代表某个算法的接口, 它是策略模式的接口. (抽象策略角色)
  • c.一个或多个该接口的具体实现, 它们代表了算法的多种实现.(具体策略角色)

3.策略模式的应用

  • a.容错恢复机制, 程序运行的时候, 如果发生某种错误, 系统并不会直接挂掉或者说影响系统的其他功能点.
  • 而是系统可以容忍这样的错误, 并且事先提供好了这种容错恢复机制, 来使得程序正常的运行下去.
  • 例如: 一个系统要对所有的操作进行日志记录, 且需要把日志记录落库, 方便后续的使用, 但是在把日志记录落库的时候,
  • 可能会发生错误, 如数据库出现问题, 那就先可以记录在文件里面, 等到数据库问题修复, 再把文件中的日志记录同步到数据库中去
  • 对于这样的功能设计, 可以采用策略设计模式, 根据需要在运行期间进行动态的切换.
  • b.假设现在要设计一个会员机制的购物系统, 对本系统的所有SVIP提供打八折的购物优惠,
  • 对本系统的所有VIP提供打九折的购物优惠, 对非会员购物不打折. 那么对于这样的系统功能设计, 也可以采用策略模式来设计.
  • c.使用不同的条件(物品的重量或者颜色等)来筛选库存中的物品, 可以将这一模式应用到更广泛的领域,
  • 比如使用不同的标准来验证输入的有效性, 使用不同的方式来分析或者格式化输入.

4.策略模式Demo 

4.1策略接口:

/**
 * @decription 连接数据库业务层
 * @author qiye
 * @date 2023/12/25
 * @version 1.0.0
 */
public interface DriverMangerService {
    /**
     * 连接数据库
     * @param vo
     * @return
     */
     Boolean connect(DbDataBase vo);
}

策略接口封装类

/**
 * @decription jdbc连接数据库的上下文类
 * @author qiye
 * @date 2023/12/26
 * @version 1.0.0
 */
public class DriverManger {

    private final DriverMangerService driverMangerService;

    public DriverManger(DriverMangerService v) {
        this.driverMangerService = v;
    }

    public Boolean  getDriverMangerService(DbDataBase vo) {
        return driverMangerService.connect(vo);
    }
}

4.2策略接口的实现

策略接口实现1
/**
 * @author qiye
 * @version 1.0.0
 * @decription mysql连接数据库
 * @date 2023/12/25
 */
@Service("mysqlDriverMangerService")
public class MysqlDriverMangerServiceImpl implements DriverMangerService {


    /**
     * 连接数据库
     *
     * @param vo
     * @return
     */
    @Override
    public Boolean connect(DbDataBase vo) {
        Connection conn = null;
        boolean flag = false;
        try {
            //加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            //建立与数据库的连接
            conn = DriverManager.getConnection(vo.getJdbcUrl(), vo.getUserName(), vo.getPassword());
            System.out.println("JDBC连接成功!");
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return flag;
    }
}
策略接口实现2
@Service("oracleDriverMangerService")
public class OracleDriverMangerServiceImpl implements DriverMangerService {

    /**
     * @decription oracle连接
     * @author qiye
     * @date 2023/12/25
     * @version 1.0.0
     */
    @Override
    public Boolean connect(DbDataBase vo) {
        boolean flag = false;
        Connection conn = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");

            conn = DriverManager.getConnection(vo.getJdbcUrl(), vo.getUserName(), vo.getPassword());

            if (conn != null && !conn.isClosed()) {
                System.out.println("成功连接到Oracle数据库!");
                flag = true;
            } else {
                System.out.println("无法连接到Oracle数据库!");
            }
            conn.close();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }

        return flag;
    }
}
策略接口实现3
@Service("postgreDriverMangerService")
public class PostgreDriverMangerServiceImpl implements DriverMangerService {

    /**
     * @decription Postgre连接
     * @author qiye
     * @date 2023/12/25
     * @version 1.0.0
     */
    @Override
    public Boolean connect(DbDataBase vo) {
        boolean flag = false;
        Connection connection = null;
        try {
            Class.forName("org.postgresql.Driver");
            connection = DriverManager.getConnection(vo.getJdbcUrl(), vo.getUserName(), vo.getPassword());

            if (connection != null) {
                System.out.println("PostgreSQL database 连接成功");
                flag = true;
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }
}

4.3调用

        DriverManger driverManger = null;

        try {
            switch (vo.getJdbcDriver()) {
                case "com.mysql.jdbc.Driver":
                    driverManger = new DriverManger(mysqlDriverMangerService);
                    break;
                case "org.postgresql.Driver":
                    driverManger = new DriverManger(postgreDriverMangerService);
                    break;
                case "oracle.jdbc.driver.OracleDriver":
                   driverManger = new DriverManger(oracleDriverMangerService);
                    break;
            }
            if(driverManger!=null){
                flag = driverManger.getDriverMangerService(vo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Response.error(500, "连接失败");
        }

5.策略模式的优缺点

5.1优点

  • a.使用策略模式可以避免使用多重条件if…else if…else语句, 多重条件不易维护且代码可读性差.
  • b.策略模式提供了管理相关的算法族的办法. 策略类的等级结构定义了一个算法或者行为族. 恰当使用继承可以把公共的代码移到父类里面, 从而避免代码重复

5.2缺点

  • a.客户端必须知道所有的策略类, 并自行决定使用哪一个策略类. 这就意味着客户端必须理解这些算法的区别, 以便适时选择恰当的算法类. 换言之, 策略模式只适用于客户端知道算法或行为的情况.
  • b.由于策略模式把每个具体的策略实现都单独封装成类, 如果备选的策略很多的话, 那么对象的数目就会很多.
  • 39
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值