Java 中的基本设计模式

news2024/11/15 22:41:19

设计模式是针对常见软件设计问题的可重用解决方案。它们提供了一种以一致且高效的方式组织和构建代码的方法。一些常见的设计模式包括:

  • 工厂模式是一种创建型设计模式,它提供用于在超类中创建对象的接口,但允许子类更改将要创建的对象的类型。

  • 抽象工厂模式是一种创建型设计模式,它提供了一个接口来创建相关或依赖对象的系列,而无需指定它们的具体类。

  • Builder模式是一种创建型设计模式,它将复杂对象的构造与其表示分离,允许相同的构造过程创建不同的表示。

  • 策略模式是一种行为设计模式,可以在运行时选择算法的行为。

  • Decorator模式是一种结构设计模式,允许将行为静态或动态地添加到单个对象,而不影响同一类中其他对象的行为。

  • Singleton模式是一种创建型设计模式,可确保一个类只有一个实例,同时还提供了对该实例的全局访问点。

  • 观察者模式是一种行为设计模式,允许一个对象(主体)在其状态发生变化时通知其他对象(观察者)。

这些模式很有用,因为它们为开发人员提供了一种通用语言,并且可以使代码更易于维护和理解。

下面是 6 种最常用的设计模式以及 Java 中的示例。

工厂模式

工厂模式是一种创建型设计模式,它提供了一种创建对象的方法,而无需指定将要创建的对象的确切类。它允许一个类将创建对象的责任委托给它的子类。

下面是如何在 Java 中实现工厂模式的示例:

interface Shape {
    void draw();
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a square");
    }
}

class ShapeFactory {
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

在上面的示例中,ShapeFactory类是根据客户端提供的输入创建不同具体类( RectangleSquare )对象的工厂类。客户端使用工厂类来创建对象,不需要知道将要创建的对象的具体类。

下面是客户端代码如何使用工厂模式创建对象的示例:

ShapeFactory shapeFactory = new ShapeFactory();

//get an object of Rectangle and call its draw method.
Shape shape1 = shapeFactory.getShape("RECTANGLE");

//call draw method of Rectangle
shape1.draw();

//get an object of Square and call its draw method.
Shape shape2 = shapeFactory.getShape("SQUARE");

//call draw method of square
shape2.draw();

在此示例中,客户端可以通过向工厂类提供不同的输入来创建不同的形状对象,而无需知道将要创建的对象的具体类。这允许代码的灵活性,并使得在不修改现有代码的情况下添加新类变得更加容易。

建造者模式

建造者模式是一种创造型设计模式,允许以清晰和有组织的方式逐步完成复杂对象的构造。它将对象的构造与其表示分离,使得在不影响客户端代码的情况下更容易更改对象的内部表示。

以下是如何在 Java 中实现构建器模式的示例:

class Computer {
    private String CPU;
    private String RAM;
    private String GPU;
    private String storage;

    private Computer(ComputerBuilder builder) {
        this.CPU = builder.CPU;
        this.RAM = builder.RAM;
        this.GPU = builder.GPU;
        this.storage = builder.storage;
    }

    public String getCPU() {
        return CPU;
    }

    public String getRAM() {
        return RAM;
    }

    public String getGPU() {
        return GPU;
    }

    public String getStorage() {
        return storage;
    }

    public static class ComputerBuilder {
        private String CPU;
        private String RAM;
        private String GPU;
        private String storage;

        public ComputerBuilder setCPU(String CPU) {
            this.CPU = CPU;
            return this;
        }

        public ComputerBuilder setRAM(String RAM) {
            this.RAM = RAM;
            return this;
        }

        public ComputerBuilder setGPU(String GPU) {
            this.GPU = GPU;
            return this;
        }

        public ComputerBuilder setStorage(String storage) {
            this.storage = storage;
            return this;
        }

        public Computer build() {
            return new Computer(this);
        }
    }
}

在此示例中,Computer类表示正在构建的复杂对象,而ComputerBuilder类是逐步构建Computer对象的构建器类。ComputerBuilder类具有用于Computer类中每个字段的setter 方法,以及一个返回构造的Computer对象的build()方法。

下面是客户端代码如何使用构建器模式创建Computer对象的示例:

Computer computer = new Computer.ComputerBuilder()
                .setCPU("i7")
                .setRAM("16GB")
                .setGPU("GTX 1080")
                .setStorage("1TB")
                .build();

在此示例中,客户端可以通过使用构建器类以逐步的方式为每个字段提供不同的值来创建Computer对象。这使代码更具可读性和易于理解,因为客户端不必担心Computer对象的内部表示。

策略设计模式

策略模式是一种行为设计模式,允许在运行时选择算法。它定义了一系列算法,封装了每一个算法,并使它们可以互换。这允许算法独立于使用它的客户端而变化。

以下是如何在 Java 中实现策略模式的示例:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardStrategy implements PaymentStrategy {
    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;

    public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
        this.name=nm;
        this.cardNumber=ccNum;
        this.cvv=cvv;
        this.dateOfExpiry=expiryDate;
    }
    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit/debit card");
    }
}

class PayPalStrategy implements PaymentStrategy {
    private String emailId;
    private String password;

    public PayPalStrategy(String email, String pwd){
        this.emailId=email;
        this.password=pwd;
    }
    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using PayPal.");
    }
}

class ShoppingCart {
    List<Item> items;
    PaymentStrategy paymentStrategy;

    public ShoppingCart(){
        this.items=new ArrayList<Item>();
    }

    public void addItem(Item item){
        this.items.add(item);
    }

    public void removeItem(Item item){
        this.items.remove(item);
    }

    public int calculateTotal(){
        int sum = 0;
        for(Item item : items){
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(){
        int amount = calculateTotal();
        paymentStrategy.pay(amount);
    }

    public void setPaymentStrategy(PaymentStrategy paymentMethod){
        this.paymentStrategy=paymentMethod;
    }
}

在此示例中,PaymentStrategy接口定义了用于进行支付的支付方法。CreditCardStrategyPayPalStrategy类是此接口的具体实现,它们提供不同的支付方式(即使用信用卡/借记卡或 PayPal)。ShoppingCart类是使用PaymentStrategy接口进行支付的客户端。ShoppingCart类可以使用setPaymentStrategy方法在运行时设置支付策略。

下面是客户端代码如何使用策略模式的示例:

ShoppingCart cart = new ShoppingCart();
cart.addItem(new Item("item1", 100));
cart.addItem(new Item("item2", 50));

// Selecting the CreditCardStrategy
cart.setPaymentStrategy(new CreditCardStrategy("John Doe","1234567890123456", "123", "12/2022"));
cart.pay();

// Selecting the PayPalStrategy
cart.setPaymentStrategy(new PayPalStrategy("test@example.com", "password"));
cart.pay();

在此示例中,客户端创建了ShoppingCart类的实例并向其中添加了一些项目。然后,客户端通过使用setPaymentStrategy方法在ShoppingCart对象上设置来选择支付策略。这可以在运行时完成,因此客户端可以根据需要在不同的支付策略之间切换。最后,客户端调用ShoppingCart对象的 pay() 方法以使用选定的策略进行支付。

在此示例中,客户端代码可以在信用卡和 PayPal 支付方式之间切换,但也可以包括其他类型的支付方式,例如银行转账等。使用此模式,客户端代码无需担心每次支付的细节方法,它只需要知道公共的PaymentStrategy接口和实现它的具体类就可以支付。

装饰者模式

装饰器模式是一种结构设计模式,它允许通过用装饰器对象包装它或通过使用附加功能扩展它来动态地向单个对象添加行为。装饰器模式允许创建灵活且可重用的代码。

下面是如何在 Java 中实现装饰器模式的示例:

interface Shape {
    void draw();
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape){
        this.decoratedShape = decoratedShape;
    }

    public void draw(){
        decoratedShape.draw();
    }
}

class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape){
        System.out.println("Border Color: Red");
    }
}

在此示例中,Shape接口定义了用于绘制形状的draw()方法。Circle类是此接口的具体实现,它提供绘制圆的行为。ShapeDecorator是一个抽象类,也实现了 Shape 接口,但它有一个附加的decoratedShape属性,该属性引用它正在装饰的形状。RedShapeDecorator类是一个具体的装饰器,向它装饰的形状添加一个红色边框。

下面是客户端代码如何使用装饰器模式的示例:

Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());

circle.draw();
redCircle.draw();

在此示例中,客户端创建Circle类的实例,然后创建RedShapeDecorator类的实例,将Circle实例作为参数传递。RedShapeDecorator包装了Circle实例并添加了绘制红色边框的附加行为。然后,客户端可以对circleredCircle对象调用draw()方法, Circle类的行为将使用RedShapeDecorator类提供的附加行为进行修饰。

在此示例中,我们使用装饰器模式向形状添加红色边框,但您可以使用此模式向装饰对象添加或修改其他功能或行为。这种模式的关键是客户端不需要知道装饰类,只需要知道被装饰对象的接口即可。

单例模式

单例模式是一种创建型设计模式,它确保一个类只有一个实例,同时也为这个实例提供一个全局访问点。单例模式用于类的单个实例必须在整个执行过程中控制操作的情况。

下面是如何在 Java 中实现单例模式的示例:

class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public void doSomething() {
        // some code
    }
}

在这个例子中,Singleton类有一个私有构造函数,这意味着该类不能从类外部实例化。该类还有一个静态实例属性,它将保存该类的单个实例。getInstance()方法用于获取类的单个实例,它使用惰性初始化仅在第一次需要实例时才创建实例。

下面是客户端代码如何使用单例模式的示例:

Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();

System.out.println(singleton1 == singleton2); // true

在本例中,客户端代码调用了两次getInstance()方法,但它只获得了Singleton类的一个实例。== 运算符用于比较两个实例的引用,它返回 true,因为它们是同一个实例。

当你想确保一个类只被实例化一次并且有一个全局可访问的实例时,单例模式很有用。当您想要控制资源或类实例的数量并且想要对其实施单点控制时,它也很有用。

重要的是要注意单例模式默认情况下不是线程安全的。如果多个线程同时访问getInstance()方法,则可能会创建 Singleton 类的多个实例。要使单例模式线程安全,您可以在getInstance方法上使用 synchronized 关键字,或者可以使用双重检查锁定模式。

观察者模式

观察者模式是一种行为设计模式,允许对象(主体)在其状态发生变化时通知其他对象(观察者)。观察者模式用于需要通知一个对象另一个对象的状态更改的情况,而两个对象之间没有直接引用。

以下是如何在 Java 中实现观察者模式的示例:

interface Observer {
    void update(String message);
}

class ConcreteObserver implements Observer {
    public void update(String message) {
        System.out.println("Received message: " + message);
    }
}

interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String message;

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}

在此示例中,Observer接口定义了update()方法,当主体的状态发生变化时将调用该方法。ConcreteObserver类是 Observer 接口的具体实现,它提供处理更新的行为。

Subject接口定义了注册和移除观察者的方法,以及在主题状态发生变化时通知所有注册观察者的方法。ConcreteSubject类是 Subject 接口的具体实现,它维护一个观察者列表并提供注册和删除观察者的方法,以及在主题状态发生变化时通知所有注册观察者的方法。

下面是客户端代码如何使用观察者模式的示例:

ConcreteSubject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver();

subject.registerObserver(observer);
subject.setMessage("Hello World!");

在此示例中,客户端代码创建了一个ConcreteSubject类的实例和一个ConcreteObserver类的实例。然后使用registerObserver()方法向主题注册观察者。客户端然后使用setMessage()设置主题的消息

总之,设计模式是软件开发的重要组成部分,它们帮助开发人员解决常见问题并使代码更易于维护、可重用和可扩展。理解和使用设计模式可以帮助开发人员编写更好、更高效的代码。重要的是要注意,设计模式不是一种放之四海而皆准的解决方案,在应用特定模式之前了解问题和上下文至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/193051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构趣味多】优先级队列——堆

1. 优先级队列 概念&#xff1a; 队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队列时&#xff0c;可能需要优先级高的元素先出队列&#xff0c;该中场景下&#xff0c;使用队列显然不合适&#xff0c;比…

前端打包后生成的dist 或 build目录,如何在本地启动服务运行

前端打包后生成的dist/build目录&#xff0c;如何在本地启动服务运行 运行npn run build&#xff0c;会打包后会产生 dist 或 build 目录 一般情况下&#xff0c;直接打开dist 或 build 目录下的 index.html会在浏览器看到内容。 然而发现网页一片空白&#xff0c;打开了控制台…

C++基础入门(引用补充)

1、使用场景做参数void Swap(int& left, int& right) {int temp left;left right;right temp; }做返回值int& Count() {static int n 0;n;// ...return n; }c语言内&#xff0c;出了count函数&#xff0c;n被销毁&#xff0c;会创建临时变量存储其值&#xff0…

DETR——使用Transformer进行端到端目标检测的开端之作

深度学习知识点总结 专栏链接: https://blog.csdn.net/qq_39707285/article/details/124005405 此专栏主要总结深度学习中的知识点&#xff0c;从各大数据集比赛开始&#xff0c;介绍历年冠军算法&#xff1b;同时总结深度学习中重要的知识点&#xff0c;包括损失函数、优化器…

寻根究底,为什么Docker中的Alpine Linux镜像能这么小

去年我发表了文章对Docker基础镜像的思考&#xff0c;该不该选择alpine&#xff0c;其中对于Alpine Linux镜像如此之小的原因我解释为它使用了musl而不是glibc 有人发现并指出了我的这个错误&#xff0c;说musl与glibc的大小差别不足以造成如此大的差距&#xff0c;应该别有原…

C++-静态局部变量

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 特征&#xff1a; 1.需添加关键字static。 2.在静态存储区分配内存&#xff0c;始终存在直到程序结束。 3.作用域为局部&#…

阿⾥云Apsara Clouder云计算专项技能认证:云服务器ECS⼊门【 个⼈所得税年度应纳税额抵扣 3600(0成本)】

文章目录 引言I 云服务器ECS⼊门II 考试III 个⼈所得税app填写专项附加扣除引言 适合⼈群:需要交个⼈所得税的上班族,有⼀定计算机基础结果:⼯资年收⼊10-20万的,能省下360元(3600*10%)I 云服务器ECS⼊门 云服务器(Elastic Compute Service, 简称ECS),是一种简单高效,…

PDPS教程:机器人气动点焊焊枪大开与小开运动状态自动切换设置

目录 概述 气动点焊焊枪运动状态设置 机器人气动点焊焊枪工具类型定义 气动点焊焊枪运动状态切换原理 气动点焊焊枪大开与小开状态切换设置 机器人仿真运行 概述 工业机器人点焊焊接过程中&#xff0c;为了提高焊接效率、优化焊接节拍、降低能源消耗&#xff0c;通常会在…

2022尚硅谷SSM框架跟学(八)Spring MVC基础三

2022尚硅谷SSM框架跟学 八 Spring MVC基础三8.RESTful案例8.1准备工作8.2功能清单8.3.具体功能&#xff1a;访问首页(1).配置view-controller(2).创建页面8.4具体功能&#xff1a;查询所有员工数据(1).控制器方法(2).创建employee_list.html8.5具体功能&#xff1a;删除(1).创建…

企业电子招投标采购系统源码之功能模块功能描述

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…

激光焊接/点焊的特性及优势分析?

目前应用于生产的点焊方式大多为电阻点焊、电弧点焊、激光点焊和胶接点焊等多种点焊方法。其中激光焊接是激光材料加工技术应用的重要方面之一。 激光点焊机主要由激光器、电源及控制、冷却机、导光及调焦、双目体视显微观察几部分构成&#xff0c;结构紧凑&#xff0c;体积小…

Android中对图片的操作,移动、缩放、涂鸦和保存到图库

一、实现方法 监听用户手势&#xff0c;提取用户操作 &#xff08;1&#xff09;移动&#xff1a; 分别计算X,Y轴的结束与初始之间移动偏移的量 &#xff08;2&#xff09;缩放&#xff1a;&#xff08;结束两指间距离伸缩比例&#xff09;/ 初始两指间距离&#xff0c;scaleX…

云计算|OpenStack|社区版OpenStack安装部署文档(五 --- 计算服务nova安装部署---Rocky版)

前言&#xff1a; nova服务是openstack最重要的一个组件&#xff0c;没有之一&#xff0c;该组件是云计算的计算核心&#xff0c;大体组件如下&#xff1a; OpenStack Docs: Compute service overview 挑些重点&#xff0c;nova-api&#xff0c;libvirt&#xff0c;nova-pla…

最小生成树与最短路径

目录 一.最小生成树 1.1概念 1.2Kruskal算法 1.3Prim算法 二.最短路径 2.11单源最短路径--Dijkstra算法 2.1.2单源最短路径--Bellman-Ford算法 一.最小生成树 1.1概念 连通图中的每一棵生成树&#xff0c;都是原图的一个极大无环子图&#xff0c;即&#xff1a;从其中删去…

虹科分享|论企业网络安全的重要性

拥有有效的企业网络安全不仅仅是让你的员工创建一个不是他们宠物名字的密码--除非他们的猫的名字至少有12个字符长&#xff0c;由大小写字母和符号组成。无论是经过充分研究的鱼叉式钓鱼尝试&#xff0c;还是绕过MFA&#xff0c;威胁者都变得更加大胆。随着全球各行业数据泄露事…

判断是否为平衡树

对二叉树有困惑的小伙伴可以看一下我之前的文章&#xff1a;二叉树&#xff08;一&#xff09;_染柒_GRQ的博客-CSDN博客二叉树&#xff08;二&#xff09;_染柒_GRQ的博客-CSDN博客二叉树&#xff08;三&#xff09;_染柒_GRQ的博客-CSDN博客点击上方链接即可查看。题目110. 平…

Ext2explore查看ext2/ext3/ext4 file

比如想查看Android system.img&#xff0c;file看起来是ext2文件&#xff0c;file system.img system.img: Linux rev 1.0 ext2 filesystem data, UUID49e89c77-3dc4-553f-a392-7d11ff348228 (extents) (large files) (huge files)2、windows下怎么看呢&#xff0c;Ext2explore…

Springboot——常用注解及实例

一、常用注解解释&#xff1a;ConfigurationBeanResourceSpringBootApplicationRestControllerRestController 注解包含了原来的 Controller 和 ResponseBody 注解&#xff0c;使用过 Spring 的朋友对 Controller 注解已经非常了解了&#xff0c;这里不再赘述&#xff0c; Resp…

【BSV应用范例】区块链上的自我主权身份

发表时间&#xff1a;2022年6月27日 信息来源&#xff1a;bsvblockchain.org 自我主权身份&#xff08;SSI&#xff09;只是一个空想吗&#xff1f; &#xff08;全球区块链组织联合创始人&#xff09;Jorge Sebastio对此表示&#xff1a;“并非如此&#xff01;” 更重要的是…

OS 学习笔记(7) 虚拟机

OS 学习笔记(7) 虚拟机 这篇笔记对应的王道OS 1.6 虚拟机&#xff0c;同时参考了 《Operating System Concepts, Ninth Edition》和 俗称ostep的《 Operating Systems: Three Easy Pieces》还有 《Operating Systems: Principles and Practice》 文章目录OS 学习笔记(7) 虚拟机…