七大设计模式原则

这篇具有很好参考价值的文章主要介绍了七大设计模式原则。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、开闭原则(Open-closed Principle)

开闭原则,是面向设计中最基础的设计原则。
一个软件实体类、模块、函数应该对扩展开放、对修改关闭
强调的是用抽象构建框架,用实现扩展细节。可以提高软件系统的可复用性和可维护性。

实例:

public interface ICourse {

    Integer getId();

    String getName();

    Double getPrice();

}
public class JavaCourse implements ICourse{

    private Integer id;

    private String name;

    private Double price;

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public Double getPrice() {
        return this.price;
    }

    public JavaCourse(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
}
public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    public Double getOriginPrice() {
        return super.getPrice();
    }

    public Double getPrice() {
        return super.getPrice() * 0.6;
    }

}

2、本末倒置原则(Dependence Inversion Principle)

高层模块不应该依赖底层模块,二者都应该依赖其抽象。
抽象不应该依赖细节,细节应该依赖抽象。
本末倒置可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,降低修改程序造成的风险。

实例:

public interface ICourse {

    void study();

}
public class JavaCourse implements ICourse{

    @Override
    public void study() {
        System.out.println("学习Java");
    }

}
public class PythonCourse implements ICourse{

    @Override
    public void study() {
        System.out.println("学习Python");
    }

}
/**
 * 方式一:依赖注入,每次学习一个新课程就多创建一个类
 */
public class PersonOne {

    public void study(ICourse iCourse){
        iCourse.study();
    }

    public static void main(String[] args) {
        PersonOne personOne = new PersonOne();
        personOne.study(new JavaCourse());
        personOne.study(new PythonCourse());
    }
}
/**
 * 方式二:构造器注入,调用时每次都要创建实例
 */
public class PersonTwo {

    private ICourse iCourse;

    public PersonTwo(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void study() {
        iCourse.study();
    }

    public static void main(String[] args) {
        PersonTwo personTwo = new PersonTwo(new JavaCourse());
        personTwo.study();
    }
}
/**
 * 方式三:Setter方式注入
 */
public class PersonThree {

    private ICourse iCourse;

    public void setCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    public void study() {
        iCourse.study();
    }

    public static void main(String[] args) {
        PersonThree personTwo = new PersonThree();
        personTwo.setCourse(new JavaCourse());
        personTwo.study();
    }
}

3、单一职责(Simple Responsibility Principle)

不要存在多于一个导致类变更的原因
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。

/**
 * course存在两种处理逻辑,这个地方修改代码
 */
public class Course {
    public void study(String name){
        if("直播".equals(name)){
            System.out.println("不能快进");
        }else {
            System.out.println("2xx倍速");
        }
    }

    public static void main(String[] args) {
        Course course = new Course();
        course.study("直播");
    }

}

修改下的代码,这样把两个课程给分开控制。

public class LiveCourse {
    public void study(String name){
        System.out.println("不能快进");
    }
}
public class ReplayCourse {
    public void study(String name){
        System.out.println("2xx倍速");
    }
}
public class Test {

    public static void main(String[] args) {
        LiveCourse liveCourse = new LiveCourse();
        liveCourse.study("直播");

        ReplayCourse replayCourse = new ReplayCourse();
        replayCourse.study("测试");
    }

}`在这里插入代码片`

4、接口隔离原则(Interface Segregation Principle)

用多个专门的接口,而不使用单一的接口,客户端不应该依赖它不需要的接口

  • 一个类对一类的依赖应该建立在最小的接口上
  • 建立单一接口,不要建立庞大的接口
  • 尽量细化接口,接口中的方法尽量少

实例:

public interface Animal {
    void eat();
    
    void fly();
    
    void swimming();
}
public class Bird implements Animal{
    @Override
    public void eat() {

    }

    @Override
    public void fly() {

    }

    @Override
    public void swimming() {

    }
}
public class Dag implements Animal{
    @Override
    public void eat() {

    }

    @Override
    public void fly() {

    }

    @Override
    public void swimming() {

    }
}

当dog不能飞,鸟儿不能游泳的时候,这个方法就会空,这时候需要根据动物行为设计不同的接口

public interface EatAnimal {

    void eat();

}
public interface FlyAnimal {

    void fly();

}
public interface SwimmingAnimal {

    void swimming();

}
public class Dog implements SwimmingAnimal, EatAnimal{
    @Override
    public void eat() {

    }

    @Override
    public void swimming() {

    }
}

5、迪米特法则(Law of demeter LoD)

一个对象应该对其他对象保持最少的了解。只和朋友交流,不喝陌生人说话。
出现在成员变量、方法的输入、输出参数中的类都可以称为成员朋友类,出现在方法体内内部的类不属于朋友类。

实例:

public class Course {
}
public class Employee {
    public void checkNumOfCourse(List<Course> courseList) {
        System.out.println("课程数量" + courseList.size());
    }
}
public class Leader {

    public void CommandCheckNumber(Employee employee){
        List<Course> courseList = new ArrayList<Course>();
        for (int i = 0; i < 20; i++) {
            courseList.add(new Course());
        }
        employee.checkNumOfCourse(courseList);
    }

    public static void main(String[] args) {
        Leader leader = new Leader();
        Employee employee = new Employee();
        leader.CommandCheckNumber(employee);
    }
}

根据迪米特法则,Leader只想要结果,不需要和Course有直接的接触,所以这个地方修改

public class EmployeeCp {
    public void checkNumOfCourse() {
        List<Course> courseList = new ArrayList<Course>();
        for (int i = 0; i < 20; i++) {
            courseList.add(new Course());
        }
        System.out.println("课程数量" + courseList.size());
    }
}
public class LeaderCp {

    public void CommandCheckNumber(EmployeeCp employee){
        employee.checkNumOfCourse();
    }

    public static void main(String[] args) {
        LeaderCp leader = new LeaderCp();
        EmployeeCp employee = new EmployeeCp();
        leader.CommandCheckNumber(employee);
    }
}

6、里氏替换原则(Liskov Substitution Priciple)

如果针对一个类型为T1的对象O1,都有类型T2的对象O2,使得以T1定义的所有程序P在所有的对象O1都替换成O2时,程序P的行为没有发生变化,那么类型T2还是类型T1的子类型。
1)子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
2)子类仲可以增加自己特有的方法
3)当子类的方法重载父类的方法时,方法的前置条件(入参)要比父类方法的输入参数更宽松
4)当子类的方法实现
父类的方法时,方法的后置条件(输出/返回值)要比父类更严格或相等

优点:
1)约束继承泛滥,开闭原则的一种体现
2)加签程序的健壮性,同时变更也可以做到好的兼容,提高程序的维护性、扩展性,降低需求变更时的风险

实例:

public class Rectangle {

    private Long height;
    private Long width;

    public Long getHeight() {
        return height;
    }

    public Long getWidth() {
        return width;
    }

    public void setHeight(Long height) {
        this.height = height;
    }

    public void setWidth(Long width) {
        this.width = width;
    }
}
public class Square extends Rectangle {

    private Long length;

    public Long getLength() {
        return length;
    }

    public void setLength(Long length) {
        this.length = length;
    }

    @Override
    public Long getHeight() {
        return getLength();
    }

    @Override
    public void setHeight(Long height) {
        setLength(height);
    }

    @Override
    public Long getWidth() {
        return getLength();
    }

    @Override
    public void setWidth(Long width) {
        setLength(width);
    }

}
public class Test {
    public static void resize(Rectangle rectangle){
        while (rectangle.getWidth() >= rectangle.getHeight()){
            rectangle.setHeight(rectangle.getHeight()+1);
            System.out.printf("width: %s, height:%s", rectangle.getWidth(), rectangle.getHeight());
        }
        System.out.printf("width: %s, height:%s", rectangle.getWidth(), rectangle.getHeight());
    }

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(20L);
        rectangle.setHeight(10L);
        resize(rectangle);

		//死循环
        Square square = new Square();
        square.setLength(10L);
        resize(square);
    }
}

当是正方形的时候,陷入死循环,违背里氏替换原则,父类替换成子类后结果不是预期。
修改代码,创建一个抽象四边形

public interface QuadRectangle {
    Long getWidth();

    Long getHeight();
}
public class RectangleCp implements QuadRectangle{

    private Long height;
    private Long width;

    public Long getHeight() {
        return height;
    }

    public Long getWidth() {
        return width;
    }

    public void setHeight(Long height) {
        this.height = height;
    }

    public void setWidth(Long width) {
        this.width = width;
    }
}
public class SquareCp implements QuadRectangle {

    private Long length;

    public Long getLength() {
        return length;
    }

    public void setLength(Long length) {
        this.length = length;
    }

    @Override
    public Long getHeight() {
        return getLength();
    }

    @Override
    public Long getWidth() {
        return getLength();
    }

}

7、合成复用原则(Composite Reuse Principle)

尽量使用对象组合(has-a)/聚合(contain-a),而不是继承达到软件复用的目的。
继承叫做“白箱复用”,把所有的实现细节暴露给子类
组合/聚合称为“黑箱复用”,对类以外的对象是无法获取到实现细节的

实例:

public class DBConnection {
    public String getConnection() {
        return "MySql连接";
    }
}
public class ProductDao {

    private DBConnection dbConnection;

    public void setDbConnection(DBConnection dbConnection){
        this.dbConnection = dbConnection;
    }

    public void addProduct(){
        String conn = dbConnection.getConnection();
        System.out.println("创建商品");
    }

}

如果这时候不只是mysql还有其他类型的数据库,违反开闭原则
修改代码:文章来源地址https://www.toymoban.com/news/detail-606819.html

public abstract class DBConnectionCp {
    public abstract String getConnection();
}
public class MysqlConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "mysql";
    }
}
public class OracleConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "Oracle";
    }
}

到了这里,关于七大设计模式原则的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 1.设计模式之七大原则和介绍

    0.为什么我要学习设计模式呢? 我发现mysql的jdbc有factory有工厂模式(编程思想,不指定语言都可以用) mq有一个QueueBuilder().setArg().xxx().build建造者模式,单例模式貌似也遇到过,前端也遇到了好几个设计模式的问题,比如prototype深拷贝和浅拷贝 所以我决定系统的学习一下设计模式…

    2024年02月11日
    浏览(58)
  • 创建型模式 (Creational Patterns) 玄子Share 设计模式 GOF 全23种 + 七大设计原则

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWLAOFtO-1691793071647)(./assets/%E7%8E%84%E5%AD%90Share%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20GOF%20%E5%85%A823%E7%A7%8D%20+%20%E4%B8%83%E5%A4%A7%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99.png)] GoF(Gang of Four)是四位计算机科学家(Erich Gamma、Ri

    2024年02月12日
    浏览(35)
  • 【Java 设计模式】设计原则之开放封闭原则

    在软件开发中,设计原则是创建灵活、可维护和可扩展软件的基础。 这些原则为我们提供了指导方针,帮助我们构建高质量、易理解的代码。 ✨单一职责原则(SRP) ✨开放/封闭原则(OCP) ✨里氏替换原则(LSP) ✨依赖倒置原则(DIP) ✨接口隔离原则(ISP) ✨合成/聚合复

    2024年02月02日
    浏览(49)
  • 【Java 设计模式】设计原则之里氏替换原则

    在软件开发中,设计原则是创建灵活、可维护和可扩展软件的基础。 这些原则为我们提供了指导方针,帮助我们构建高质量、易理解的代码。 ✨单一职责原则(SRP) ✨开放/封闭原则(OCP) ✨里氏替换原则(LSP) ✨依赖倒置原则(DIP) ✨接口隔离原则(ISP) ✨合成/聚合复

    2024年01月20日
    浏览(44)
  • Java设计模式_概述(设计模式类型和基本原则)

    设计模式(Design pattern)代表了最佳的实践,是软件开发人员在软件开发过程中面临一般问题的解决方案,是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。是优秀程序猿的经验结晶。 但不推荐刚入门的开发者学习,哪怕把代码搞的一塌糊涂,也要先将功

    2024年04月29日
    浏览(35)
  • 设计模式之7大设计原则-Java版

    软件设计模式是前辈们代码设计经验的总结,可以反复使用。设计模式共分为3大类,创建者模式(5种)、结构型模式(7种)、行为型模式(11种),一共23种设计模式,软件设计一般需要满足7大基本原则。下面通过5章的学习一起来看看设计模式的魅力吧。 目录 1.1、设计模式概述

    2024年01月20日
    浏览(40)
  • (学习打卡2)重学Java设计模式之六大设计原则

       前言:听说有本很牛的关于Java设计模式的书——重学Java设计模式,然后买了(*^▽^*) 开始跟着小傅哥学Java设计模式吧,本文主要记录笔者的学习笔记和心得。 打卡!打卡! 单一职责原则、开闭原则、里氏替换原则、迪米特法则、接口隔离原则、依赖倒置原则。 (引读:

    2024年02月03日
    浏览(51)
  • 一网打尽java注解-克隆-面向对象设计原则-设计模式

    注解 :也叫标注,用于包、类、变量、方法、参数上。可以通过反射获取标注。可以在编译期间使用,也可以被编译到字节码文件中,运行时生效。 内置注解 :Java语言已经定义好的注解。 @Overread :用于方法重写。 @Deprecated :标记过时方法。 @SuppressWarnings :指示编译器去

    2024年02月11日
    浏览(46)
  • 【设计模式】设计原则-开闭原则

    定义 作用 1、方便测试;测试时只需要对扩展的代码进行测试。 2、提高代码的可复用性;粒度越小,被复用的可能性就越大。 3、提高软件的稳定性和延续性,易于扩展和维护。 实现方式 通过“抽象约束、封装变化”来实现开闭原则。通过接口或者抽象类为软件实体定义一

    2024年02月15日
    浏览(37)
  • 【设计模式】设计原则-里氏替换原则

    定义 任何基类可以出现的地方,子类一定可以出现。 通俗理解:子类可以扩展父类的功能,但不能改变父类原有的功能。 换句话说,子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。 针对的问题 主要作用就是规范继承时子类的一些书写规则。

    2024年02月14日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包