IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式第一步:【六大设计原则】 -> 正文阅读

[Java知识库]设计模式第一步:【六大设计原则】

这两天项目刚结束,就听说要开始二期迭代开发了,我的天还好在项目设计初期的时候了解了设计模式,项目中用到了几个设计模式,二期还不是简简单单,三下五除二搞完就可以摸鱼了,做个总结,分享一下!!!

单一职责原则

介绍

单一职责原则定义是:应该且仅有一个原因印奇类的变更。也就是一个类只做一件事情

优点

1、降低类的复杂性,实现了什么职责都有清晰的定义;
2、可读性提高;
3、可维护性提高;
4、变更引起风险降低。

代码示例

开发个支付宝,用户登陆后支付退款

/**
 * 支付宝类
 */
public interface AliPay {
    //登录
    public void login(User user);
    //支付
    public void pay(int money);
    //退款
    public void refund(int money);
}

从项目上看这个类是操作支付宝的,它符合单一原则吗?很明显不符合
对接口一定要做到职责单一,类的设计尽量做到只有一个原因引起变话

/**
 * 修改后支付宝支付类
 */
public interface AliPay {
    //支付
    public void pay(int money);
    //退款
    public void refund(int money);
}
/**
 * 修改后支付宝登录类
 */
public interface AliPayLogin {
    //登录
    public void login(User user);
}

里氏替换原则

介绍

里氏替换原则定义是:只要父类存在的地方子类就可以替换父类出现,并且不会出现异常,但是反过来就不一定满足

解析

因为代码过程中会经常出现继承关系,所以这是给继承关系施加的一种约束
1、子类必须完全实现父类的方法;不实现继承无意义
2、子类可以有自己的个性;子类可以扩展自己
3、覆盖或者是实现父类的方法时入参可以被放大;子类入参应该是父类入参的父类(你可以把Map传给HashMap,但是不能反过来)
4、覆写或者实现父类方法时输出结果可以被缩小;(父类输出是Map,子类可以HsahMap,但是父类是HsahMap,子类用什么?)

代码示例

开发个支付宝,用户登陆后支付退款



/**
 * 支付宝类
 */
public class AliPay {
    //支付
    public void pay(HashMap money){
        System.out.println("父类:普通支付");
    }
    //退款
    public Map refund(HashMap money){
        System.out.println("父类:退款成功");
        return money;
    }
}

class SaomaPay extends AliPay{

//    @Override
//    public void pay(HashMap money) {
//        System.out.println("子类:扫码支付11");
//    }
//
//    @Override
//    public Map refund(HashMap money){
//        System.out.println("子类:扫码支付11");
//        return new HashMap();
//    }



    public void pay(Map money) {
        System.out.println("子类:扫码支付");
    }

    public HashMap refund(Map money) {
        System.out.println("子类:操作成功后返回新的Map");
        return new HashMap();
    }


}

class Client{
    public static void main(String[] args) {
        System.out.println("父类");
        AliPay aliPay = new AliPay();
        HashMap hashMap = new HashMap();
        aliPay.pay(hashMap);
        Map refund = aliPay.refund(hashMap);
        System.out.println("子类");
        SaomaPay saomaPay = new SaomaPay();
        saomaPay.pay(hashMap);
        Map refundSaoma = saomaPay.refund(hashMap);
    }
}

输出结果

输出结果:
父类
父类:普通支付
父类:退款成功
子类
父类:普通支付
父类:退款成功
可以看到这是正常的

修改子类覆盖的方法入参HashMap后:
父类
父类:普通支付
父类:退款成功
子类
父类:普通支付
子类:操作成功后返回新的Map
子类没有覆写的前提下走到了子类的方法中,这样会引起业务混乱

依赖倒置原则

介绍

依赖倒置原则定义是:模块之间的依赖应该通过抽象联系在一起,而不是依赖于实现类,简而言之就是面向接口编程。

优点

1、减少类之间的耦合;
2、提高了系统的稳定性;
3、降低了并行开发引起的风险;
4、提高了代码可读性和可维护性。

代码示例

开发个支付宝,用户登陆后支付退款


/**
 * 支付动作
 */
public interface Pay {
    //支付
    public void pay(int money);
    //退款
    public void refund(int money);
}

/**
 * 微信支付
 */
class WeCatPay implements Pay{
    /**
     * 支付
     * @param money
     */
    @Override
    public void pay(int money) {
        System.out.println("你使用了微信支付金额:" + money);
    }

    /**
     * 退款
     * @param money
     */
    @Override
    public void refund(int money) {
        System.out.println("你使用了微信退款金额:" + money);
    }
}

/**
 * 信用卡支付
 */
class CreditCardPay implements Pay{
    /**
     * 支付
     * @param money
     */
    @Override
    public void pay(int money) {
        System.out.println("你使用了信用卡支付金额:" + money);
    }

    /**
     * 退款
     * @param money
     */
    @Override
    public void refund(int money) {
        System.out.println("你使用了信用卡退款金额:" + money);
    }
}


class ZhangSan{
    private Pay pay;
    public void setPay(Pay pay){
        this.pay = pay;
    }

    private int money;
    public void setMoney(int money){
        this.money = money;
    }

    public void pay() {
        pay.pay(money);
    }

    public void refund() {
        pay.refund(money);
    }
}


class Client{
    public static void main(String[] args) {
        ZhangSan zhangSan = new ZhangSan();
        //设置金额
        zhangSan.setMoney(10);
        //设置微信渠道
        zhangSan.setPay(new WeCatPay());

        zhangSan.pay();
        zhangSan.refund();

        //设置信用卡渠道
        zhangSan.setPay(new WeCatPay());

        zhangSan.pay();
        zhangSan.refund();
    }
}

输出结果

输出结果:
你使用了微信支付金额:10
你使用了微信退款金额:10
你使用了微信支付金额:10
你使用了微信退款金额:10

接口隔离原则

介绍

接口隔离原则定义是:客户端不应该依赖它不需要的接口,类之间的依赖应该建立在最小的接口上。
简单一句话就是接口要单一,也就是接口或者类中方法尽量少。

优点

1、降低类的复杂性,实现了什么职责都有清晰的定义;
2、可读性提高;
3、可维护性提高;
4、变更引起风险降低。

解析

接口设计不能太小(定义一个员工类,一级证件,二级证件,三级证件,虽然灵活性上去了,但是有的员工没有一级证件,所以要拆分这个类中的接口),不能太大(灵活性太差,过于于臃肿),与单一职责类似,单一职责是业务上的划分,接口隔离是接口上的。

迪米特法则

介绍

迪米特法则定义是:一个类对其他类有最少的了解。简单地说提供一个public方法解决我的问题。

优点

1、减少类之间的耦合;
2、提高系统稳定;
3、降低并行开发风险;
4、提高可读性和可维护性。

解析

一个类暴漏的公共方法越多面临的风险越大。
一个场景中用大一个类中的多个方法,尽量合并。

开闭原则

介绍

开闭原则定义是:一个模块应该对扩展开放对修改关闭。

优点

1、减少类之间的耦合;
2、提高复用性;
3、有较高的维护性;
4、提高可读性和可维护性。

解析

修改关闭并不意味着不修改,一个方法更改对其它模块不产生任何影响。
去扩展一个类好过于直接修改类本身。
设计之初应该多考虑各种情况,确保之后新的需求逻辑顺畅进行

代码示例

原有设计仅仅是商品支付

/**
 * 支付动作
 */
public interface Pay {
    //支付
    public void pay(Order order);
}

/**
 * 微信支付
 */
class WeCatPay implements Pay{
    /**
     * 支付
     */
    @Override
    public void pay(Order order) {
        System.out.println("支付");
        System.out.println(order.getGoodsName() + "价格:" + order.getOrderMoney());
    }
}

/**
 * 订单金额类
 */
@Data
class Order{
    //商品名字
    String goodsName = "《设计模式之禅》";

    //订单金额
    int orderMoney = 10;

}

class Client{
    public static void main(String[] args) {
        Pay pay = new WeCatPay();
        pay.pay(new Order());
    }
}

输出结果

结果:
支付
《设计模式之禅》价格:10

扩展示例

新的需求,商品支付要有优惠
怎么办?
最简单修改Order类中getOrderMoney()方法打个折就行
但是这个类被多个场景使用呢?比如采购,再比如对账。他们要看到原价,所以不可以在原Order属性中修改


/**
 * 支付动作
 */
public interface Pay {
    //支付
    public void pay(Order order);
}

/**
 * 微信支付
 */
class WeCatPay implements Pay{
    /**
     * 支付
     */
    @Override
    public void pay(Order order) {
        System.out.println("支付");
        System.out.println(order.getGoodsName() + "价格:" + order.getOrderMoney());
    }
}


@Data
class Order{
    //商品名字
    String goodsName = "《设计模式之禅》";

    //订单金额
    int orderMoney = 10;

}

class DiscountOrder extends Order{
    //折扣金额
    int discountMoney = 1;

    @Override
    public int getOrderMoney() {
        return super.getOrderMoney() - this.discountMoney;
    }
}
class Client{
    public static void main(String[] args) {
        Pay pay = new WeCatPay();
        pay.pay(new DiscountOrder());
    }
}

输出结果

结果:
支付
《设计模式之禅》价格:9

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-04 12:43:31  更:2021-10-04 12:45:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:53:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码