1、单一职责原则:
public class SingletonClass {
private static volatile SingletonClass instance;
private SingletonClass() {
// 私有构造函数,防止外部实例化
}
public static SingletonClass getInstance() {
if(instance == null) {
synchronized (SingletonClass.class) {
if(instance == null) {
instance = new SingletonClass();
}
}
}
return instance;
}
public void doTaskA() {
System.out.println("执行任务A");
}
public void doTaskB() {
System.out.println("执行任务B");
}
}
package com.single.duty;
public class SingletonDemo {
public static void main(String[] args) {
SingletonClass singleton = SingletonClass.getInstance();
singleton.doTaskA();
singleton.doTaskB();
}
}
2、开闭原则:
package com.openclose.duty;
//定义一个接口Shape,它包含一个计算面积的方法calculateArea().
public interface Shape {
double calculateArea();
}
package com.openclose.duty;
//定义圆形类,实现Shape接口,并实现计算面积的方法
public class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double calculateArea() {
return Math.PI * radius * radius;
}
}
package com.openclose.duty;
//定义矩形类,实现Shape接口,并实现计算面积的方法。
public class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double calculateArea() {
return width * height;
}
}
package com.openclose.duty;
//创建各种形状的对象,并计算它们的总面积.
//当我们需要新增其他形状的时候,只需要创建一个新的形状类,并让实现接口Shape的calculateArea()方法,
//不需要修改已有的代码,就可以实现对系统的扩展。
public class Main {
public static void main(String[] args) {
// 创建两个不同的形状对象
Shape rectangle = new Rectangle(3, 4);
Shape circle = new Circle(5);
// 计算并输出形状的面积
System.out.println("矩形的面积:" + rectangle.calculateArea());
System.out.println("圆形的面积:" + circle.calculateArea());
}
}
3、里氏替换原则:
package com.replacement.duty;
//定义一个基类,表示动物
class Animal {
public void eat() {
System.out.println("动物正在进食...");
}
}
package com.replacement.duty;
//定义一个子类,表示鸟
class Bird extends Animal {
// 子类可以扩展基类的功能
public void fly() {
System.out.println("鸟正在飞行...");
}
}
package com.replacement.duty;
//在主程序中使用上述类
//子类对象 bird 可以替代基类对象 animal,并且都可以使用 eat() 方法。这就是里氏替换原则的体现。
public class Main {
public static void main(String[] args) {
// 创建基类对象和子类对象
Animal animal = new Animal();
Bird bird = new Bird();
// 使用基类对象的方法
animal.eat();
// 使用子类对象的方法
bird.eat();
bird.fly();
}
}
4、依赖倒置原则:
package com.yinaidaozhi.duty;
//定义一个抽象接口
interface IMessage {
void sendMessage();
}
package com.yinaidaozhi.duty;
// 定义一个实现类,实现抽象接口
class EmailMessage implements IMessage {
public void sendMessage() {
System.out.println("发送电子邮件消息");
}
}
package com.yinaidaozhi.duty;
//定义另一个实现类,实现抽象接口
class SmsMessage implements IMessage {
public void sendMessage() {
System.out.println("发送短信消息");
}
}
ackage com.yinaidaozhi.duty;
//高层模块,通过构造函数传递依赖对象
class MessageSender {
private IMessage message;
public MessageSender(IMessage message) {
this.message = message;
}
public void send() {
message.sendMessage();
}
}
package com.yinaidaozhi.duty;
//在主程序中使用上述类
//在高层模块 MessageSender中,通过构造函数传递依赖对象 IMessage,
//而不是直接依赖于具体的实现类。
//这样,高层模块就不会依赖于低层模块的具体实现了,而是依赖于抽象接口。
//高层模块和低层模块都应该依赖于抽象的接口或类,而不是依赖于具体的实现类SmsMessage/EmailMessage。
public class Main {
public static void main(String[] args) {
// 创建依赖对象
IMessage emailMessage = new EmailMessage();
IMessage smsMessage = new SmsMessage();
// 创建高层模块,传递依赖对象
MessageSender sender1 = new MessageSender(emailMessage);
MessageSender sender2 = new MessageSender(smsMessage);
// 调用高层模块方法,实现相应的功能
sender1.send();
sender2.send();
}
}
5、接口隔离原则:
package com.Interfaceisolation.duty;
//定义一个接口,包含多个方法
interface IWorker {
void work();
void eat();
}
package com.Interfaceisolation.duty;
//定义一个工人类,实现接口中的方法
class Worker implements IWorker {
public void work() {
System.out.println("工人工作");
}
public void eat() {
System.out.println("工人吃饭");
}
}
package com.Interfaceisolation.duty;
//定义一个服务员类,只需要实现一个方法
class Waiter implements IWorker {
public void work() {
System.out.println("服务员工作");
}
public void eat() {
// 空实现,服务员不需要吃饭
}
}
package com.Interfaceisolation.duty;
//高层模块,依赖于接口中的方法
class Manager {
public void manage(IWorker worker) {
worker.work();
}
}
package com.Interfaceisolation.duty;
//在高层模块 Manager 中,只依赖于接口中的 work() 方法,而不依赖于 eat() 方法。
//这样,即使后续新增了其他实现类,只要实现了 work() 方法即可,不需要强迫实现 eat() 方法。
//接口隔离原则的核心思想是,类和接口应该只关注自己需要使用的方法。
//一个类或者模块不应该依赖于它不需要的接口,即不应该强迫实现不必要的方法。
public class Main {
public static void main(String[] args) {
// 创建依赖对象
IWorker worker1 = new Worker();
IWorker worker2 = new Waiter();
// 创建高层模块,传递依赖对象
Manager manager = new Manager();
// 调用高层模块方法,实现相应的功能
manager.manage(worker1);
manager.manage(worker2);
}
}
6、迪米特法则:
package com.dimiters.duty;
//定义学生类
class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.dimiters.duty;
import java.util.ArrayList;
import java.util.List;
//定义班级类
class Classroom {
private List<Student> students;
public Classroom() {
students = new ArrayList<>();
}
public void addStudent(Student student) {
students.add(student);
}
public List<Student> getStudents() {
return students;
}
}
package com.dimiters.duty;
import java.util.ArrayList;
import java.util.List;
//定义学校类
class School {
private List<Classroom> classrooms;
public School() {
classrooms = new ArrayList<>();
}
public void addClassroom(Classroom classroom) {
classrooms.add(classroom);
}
// 学校不需要了解班级内部的学生信息,只返回班级数量
public int getClassroomCount() {
return classrooms.size();
}
// 学校不需要了解班级内部的学生信息,只返回学生总数
public int getStudentCount() {
int count = 0;
for (Classroom classroom : classrooms) {
count += classroom.getStudents().size();
}
return count;
}
}
package com.dimiters.duty;
//学校只调用班级类的方法来获取班级数量和学生总数,而不需要了解班级内部的学生信息。
//迪米特法则的核心思想是,一个对象应该对其他对象保持最少的了解。
//它要求我们限制一个对象对其他对象的引用,只与直接的朋友(成员变量、方法参数、方法返回值)发生交互,
//而避免和非直接的朋友(其他类/对象的内部属性、方法参数、局部变量)发生直接交互。
public class Main {
public static void main(String[] args) {
// 创建学生对象
Student student1 = new Student("Tom");
Student student2 = new Student("Mary");
// 创建班级对象,并添加学生
Classroom classroom1 = new Classroom();
classroom1.addStudent(student1);
classroom1.addStudent(student2);
// 创建学校对象,并添加班级
School school = new School();
school.addClassroom(classroom1);
// 调用学校方法,获取班级数量和学生总数
int classroomCount = school.getClassroomCount();
int studentCount = school.getStudentCount();
System.out.println("班级数量:" + classroomCount);
System.out.println("学生总数:" + studentCount);
}
}
7、单一职责原则的另一种写法:
package com.single.duty;
//定义接口,明确定义类的职责
interface FileOperation {
void readFile(String filepath);
void writeFile(String filepath, String content);
}
package com.single.duty;
//实现接口,专门处理文件读取和写入的类
class FileManager implements FileOperation {
@Override
public void readFile(String filepath) {
// 实现文件读取的逻辑
}
@Override
public void writeFile(String filepath, String content) {
// 实现文件写入的逻辑
}
}
package com.single.duty;
//定义另一个接口,明确定义类的职责
interface DataOperation {
void processData(String data);
}
package com.single.duty;
//实现接口,专门处理数据的类
class DataManager implements DataOperation {
@Override
public void processData(String data) {
// 实现数据处理的逻辑
}
}
package com.single.duty;
public class Main {
public static void main(String[] args) {
// 文件操作
FileOperation fileManager = new FileManager();
fileManager.readFile("file.txt");
fileManager.writeFile("file.txt", "Hello World!");
// 数据处理
DataOperation dataManager = new DataManager();
dataManager.processData("data");
}
}