首页 > 编程语言 >Java面向对象六大设计原则总结1

Java面向对象六大设计原则总结1

时间:2024-10-15 21:47:01浏览次数:9  
标签:fly 六大 Java 原则 double void class 面向对象 public

简介

         在Java面向对象设计中,遵循六大原则是确保代码质量、可维护性和可扩展性的关键。这六大原则分别是:单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)、依赖倒置原则(DIP)和迪米特法则(LOD)。以下是对这六大原则的详细解释,并结合实例进行说明。

  • 单一职责原则。对类来说,即一个类应该只负责一项职责。

  • 开闭原则。对扩展开放,对修改关闭。在程序需要进行扩展的时候,不能去修改原有代码,使用接口和抽象类实现一个热插拔的效果。

  • 里氏替换原则。任何基类可以出现的地方,子类一定可以出现。实现抽象的规范,实现子父类相互替换。

  • 依赖倒置原则。针对接口编程,依赖于抽象而不依赖于具体。

  • 接口隔离原则。降低耦合度,接口单独设计,相互隔离。

  • 最少知道原则(迪米特法则)。一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

1. 单一职责原则(SRP)

单一职责原则要求一个类只负责一个功能或者职责。这意味着一个类应该只有一个引起它变化的原因。

例子: 假设我们有一个User类,它负责用户的所有操作,包括用户信息的获取、更新和删除。如果我们将这些操作分散到不同的类中,每个类只负责一个职责,那么代码将更加清晰和易于维护。

// 原始设计
class User {
    void getUserInfo() {}
    void updateUser() {}
    void deleteUser() {}
}

// 遵循单一职责原则
class UserInfoService {
    void getUserInfo() {}
}

class UserService {
    void updateUser() {}
    void deleteUser() {}
}

2. 开闭原则(OCP)

开闭原则要求软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要增加新功能时,应该通过扩展现有代码来实现,而不是修改现有代码。

例子: 假设我们有一个Shape接口和一个Circle类实现该接口。如果需要添加新的形状(如Square),我们可以通过扩展Shape接口和添加新的实现类来实现,而不需要修改现有的代码。

interface Shape {
    double calculateArea();
}

class Circle implements Shape {
    private double radius;
    public Circle(double radius) { this.radius = radius; }
    @Override
    public double calculateArea() { return Math.PI * radius * radius; }
}

// 添加新的形状
class Square implements Shape {
    private double side;
    public Square(double side) { this.side = side; }
    @Override
    public double calculateArea() { return side * side; }
}

3. 里氏替换原则(LSP)

里氏替换原则要求所有引用基类的地方,必须能透明地使用其子类。这意味着子类应该能够替换其基类而不影响程序的正确性。

例子: 假设我们有一个Bird类和一个Ostrich类继承自BirdOstrichBird的一种特殊类型,但它不能飞行。如果我们在代码中使用了Bird类型的变量,那么它可以指向Ostrich对象,而不会影响程序的正确性。

class Bird {
    void fly() { System.out.println("Flying"); }
}

class Ostrich extends Bird {
    @Override
    void fly() { throw new UnsupportedOperationException("Ostrich cannot fly"); }
}

// 使用里氏替换原则
Bird bird = new Ostrich();
bird.fly(); // 这里会抛出异常

4. 接口隔离原则(ISP)

接口隔离原则要求客户端不应该依赖它不需要的接口。也就是说,接口应该尽可能小,只包含客户端需要的方法。

例子: 假设我们有一个Animal接口,包含eat()fly()方法。如果某些动物(如Dog)不需要飞行能力,那么它们不应该实现fly()方法。

interface Animal {
    void eat();
    void fly(); // 这个方法对某些动物来说是多余的
}

// 遵循接口隔离原则
interface Eater {
    void eat();
}

interface Flyer {
    void fly();
}

class Dog implements Eater {
    @Override
    public void eat() {}
}

class Bird implements Eater, Flyer {
    @Override
    public void eat() {}
    @Override
    public void fly() {}
}

5. 依赖倒置原则(DIP)

依赖倒置原则要求高层模块不应该依赖低层模块,两者都应该依赖其抽象。抽象不应该依赖细节;细节应该依赖抽象。

例子: 假设我们有一个OrderService类依赖于PaymentProcessor类。我们可以将PaymentProcessor抽象为一个接口,并让具体的支付处理器实现该接口,从而降低耦合度。

interface PaymentProcessor {
    void processPayment(double amount);
}

class CreditCardPayment implements PaymentProcessor {
    @Override
    public void processPayment(double amount) {}
}

class OrderService {
    private PaymentProcessor paymentProcessor;

    public OrderService(PaymentProcessor paymentProcessor) {
        this.paymentProcessor = paymentProcessor;
    }

    public void processOrder(double amount) {
        paymentProcessor.processPayment(amount);
    }
}

6. 迪米特法则(LOD)

迪米特法则要求一个对象应该对其他对象有尽可能少的了解。也就是说,一个类应该只与它的直接朋友通信,而不应该知道它的朋友的朋友。

例子: 假设我们有一个Department类和一个Employee类。Department类不应该直接访问Employee类的内部细节,而是应该通过公共接口进行交互。

class Employee {
    private String name;
    public String getName() { return name; }
}

class Department {
    private List<Employee> employees = new ArrayList<>();

    public void addEmployee(Employee employee) { employees.add(employee); }

    public void printEmployeeNames() {
        for (Employee employee : employees) {
            System.out.println(employee.getName());
        }
    }
}

标签:fly,六大,Java,原则,double,void,class,面向对象,public
From: https://blog.csdn.net/2301_79847249/article/details/142965372

相关文章

  • 【Java SE 题库】递归的魅力之--> 青蛙跳台阶问题(秒了)
     ......
  • Java毕业生就业推荐系统
    开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9浏览器:谷歌浏览器后台路径地址:localhost:8080/项目名称/admin/dist/index.html前台路径地址:localhost:80......
  • Java基础面试题
    一、Java八大基本数据类型byteshortcharintlongdoublefloatboolean项目中一般用在各种变量如传参入参、分页等,一般用包装类二、面向对象的三大特性封装:把类的属性私有化并封装到公共方法内,使用方法才能对属性进行获取和修改,隐藏代码实现细节,提高程序安全性继承:子......
  • java程池状态
    在Java中,线程池的状态是由java.util.concurrent.ThreadPoolExecutor类管理的。ThreadPoolExecutor是ExecutorService的一个实现,提供了对线程池的详细控制。线程池的状态可以通过getPoolSize、getActiveCount、getTaskCount、getCompletedTaskCount等方法来获取。线程池的......
  • 【JavaWeb】一文读懂Cookie、Session&Token 的区别和联系
    大佬精心打造:JavaWeb进阶学习资料》》点击免费获取【javaWeb】Cookie&Session&SpringSession原理分析简介Cookie、Session、Token这三者是不同发展阶段的产物,都是为了解决无状态的HTTP协议,提升网站的交互体验。但是他们各有优缺点,三者也没有明显的对立关系,反而常常......
  • 【JavaWeb】Spring Boot中@Import多种使用方式
    @Import是一个非常有用的注解,它的长处在于你可以通过配置来控制是否注入该Bean,也可以通过条件来控制注入哪些Bean到Spring容器中。比如我们熟悉的:@EnableAsync 、@EnableCaching、@EnableScheduling等等统一采用的都是借助@Import注解来实现的。  需要注意的是:ImportSele......
  • 学习java第八天
    一.方法重写/方法覆盖/Override为什么要进行方法重写/覆盖?子类不满足父类的逻辑,进行重写方法重写的注意事项:1.方法重写前提是必须要继承2.所继承的方法名必须一致,方法参数也要一致举例说明一个方法的三部分publicvoideat(){}第一部分头部 访问权限修饰符publicp......
  • java解决就简单的亮灯问题
    100个房间每个房间1盏灯   这些灯都是灭的   //123456789   100个人coming      第1个人   来到每个房间前         如果房间编号能够整除1(人的编号)         拉一下灯      第2个人   来到每......
  • Java的引擎效验报错-java.lang.VerifyError
    java包直接修改bytecode,经常会报错java.lang.VerifyError,包含非常多种的检查直接修改引擎dll文件去除效验jvm.dll-X64-V21.0.0.0.text:000000018084438F488D0DDA422100learcx,aVerifyingMetho;"Verifyingmethod%s".text:00000001......
  • 图文深入理解java对象从创建到回收都经历了什么
    1.前言:每个java对象都是有生命周期的,就像一个人的生命一样,从孕育到出生到成长变老最后由归于自然。笔者认为,Java对象的整个生命周期可以分为两个大的阶段:即创建阶段和运行阶段(包含对象的回收和消亡)。本篇将会图文深入介绍java对象的整个生命过程。一般人平时看到java其实......