【每天一个java设计模式(完)】 - 四万字实现23种设计模式(附示例源码)

25 篇文章 23 订阅
14 篇文章 1 订阅

创建型模式

结构型模型

行为型模式

实例源码地址

码云: https://gitee.com/wy666666/design_pattern
Github:https://github.com/Bryant6/design_pattern

什么是设计模式

设计模式概述

设计模式是什么?

  • 它是软件开发人员在软件开发过程中经过相当长的一段时间的试验和错误总结出来的面临的一般问题的解决方案;
  • 它是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结;
  • 它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。

设计模式能干什么?

  • 实现代码的可重用性
  • 增加代码的可维护性
  • 减低代码的被理解难度
  • 保证代码的可靠性
  • 增加系统的健壮性
  • 易修改可扩展

设计模式七大设计原则
1. 开闭原则
对扩展开放,对修改关闭。当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。它使软件实体拥有一定的适应性和灵活性的同时具备稳定性和延续性。
2. 单一职责原则
单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。

也就是说,单一职责原则就是自己只负责自己的事,不需要理会别人的事。在面对对象编程中,每个对象只负责自己的任务,这样的开发方式代码耦合度较低,较灵活,易扩展。
3. 里氏替换原则
里氏替换原则是面向对象设计的基本原则之一。里氏替换原则规定继承必须确保超类所拥有的性质在子类中仍然成立。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对实现抽象化的具体步骤的规范,是实现开闭原则的方式之一。
4. 依赖倒转原则
依赖倒转原则规定针对接口编程,依赖于抽象而不依赖于具体,要面向接口编程,不要面向实现编程。
依赖倒转原则是实现开闭原则的重要途径之一,它降低了用户与实现模块之间的耦合度。
5. 接口隔离原则
接口隔离原则要求开发者尽量将庞大的接口拆分成更小的更具体的接口,一个类对另一个类的依赖应该建立在最小的接口上。要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
6. 合成复用原则
在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。如果要使用继承关系,则必须严格遵循里氏替换原则(继承必须确保超类所拥有的性质在子类中仍然成立)。
7. 迪米特原则
迪米特法则又叫作最少知识原则,一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。

一句话总结设计原则就是要降低对象的耦合度,增加程序的可复用、扩展和维护性。

23种设计模式
根据模式是用来完成什么工作来划分,可分为创建型模式、结构型模式和行为型模式 3 种类型。
在这里插入图片描述
其中工厂方法模式、适配器模式、模板方法模式、解释器模式四种模式,是用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来了。其他的模式都是用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的。

工厂模式

工厂模式是 Java 中最常用的设计模式之一。它属于创建型模式,提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,即定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

使用工厂模式,用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

可以通过以下步骤来实现一个工厂模式:

  1. 创建一个接口
  2. 创建实现接口的实现类
  3. 创建一个工厂,生成基于给定信息的实体类的对象。
  4. 使用该工厂,通过传递类型信息来获取实体类的对象。

下面的例子中,我们假设一个工厂可以生产手机、电脑和飞机三种产品,我们使用工厂模式来实现手机、电脑、飞机的创建。

1. 创建一个接口
这个接口表示一种产品,但具体是什么我们并不知道。
接口中声明一个方法,表示生产一个产品。

// 表示一种产品
public interface Product {
    //表示生产一件产品的方法
    void product();
}

2. 创建实现接口的实现类
假设目前只有手机、电脑和飞机三种产品,分别创建手机、电脑和飞机三个实现类实现产品接口,并实现其中常见产品的的方法。

//手机
public class Phone implements Product {
    @Override
    public void product() {
        System.out.println("生产了一个牛逼的智能手机");
    }
}
//电脑
public class Computer implements Product {
    @Override
    public void product() {
        System.out.println("生产了一台程序员都想要的电脑");
    }
}
//飞机
public class Plane implements Product {
    @Override
    public void product() {
        System.out.println("生产了一架飞机,随时带你起飞");
    }
}

3. 创建一个工厂,生成基于给定信息的实体类的对象。
工厂类,用于生产出具体的产品。

//工厂类
public class Factory {
    //通过productType获取产品对象
    public Product getProduct(String productType){
        if(productType.equals("手机")){
            return new Phone();
        }else if(productType.equals("电脑")){
            return new Computer();
        }else if(productType.equals("飞机")){
            return new Plane();
        }else {
            System.out.println("传入产品类型有误!");
        }
        return null;
    }
}

4. 使用该工厂,通过传递类型信息来获取实体类的对象。
使用工厂,生产出产品。

public class FactoryMain {
    public static void main(String[] args) {
        //创建一个工厂
        Factory factory = new Factory();

        //通过工厂获取手机对象,并创建一个手机
        Product phone = factory.getProduct("手机");
        phone.product();

        //通过工厂获取电脑对象,并创建一个电脑
        Product computer = factory.getProduct("电脑");
        computer.product();

        //通过工厂获取飞机对象,并创建一个飞机
        Product plane = factory.getProduct("飞机");
        plane.product();
    }

在这里插入图片描述

在这个例子中,我们可以看到用户只需要知道产品的名称,就可以得到想要的产品,而不需要关心它具体是怎样实现的。比如,用户想要得到一架飞机,他只需要通过工厂Factory,然后调用它的getProduct方法,就可以得到一架飞机,然后就可以带他起飞了,他并不需要知道飞机师怎么创建出来的。

抽象工厂模式

工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品。抽象工厂模式是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

下面给出抽象工厂的实例:

假设现在有一个工厂可以生产一些产品(手机、电脑、飞机),另一个工厂可以对生产出来的产品上色(红色、绿色、彩虹色)。我们通过抽象工厂的方式来实现具体工厂的创建,以及产品的生产。

1. 创建一个接口Product
这个接口表示一种产品(手机、电脑、飞机),但具体是什么我们并不知道。
接口中声明一个方法,表示生产一个产品。

//产品接口
public interface Product {
    void product();
}

2. 创建Product接口的实现类
三个实现类Phone、Computer、Plane分别表示手机、电脑、飞机这三种产品。

//手机类
public class Phone implements Product {
    @Override
    public void product() {
        System.out.println("生产了一个牛逼的智能手机");
    }
}
//电脑类
public class Computer implements Product {
    @Override
    public void product() {
        System.out.println("生产了一台程序员都想要的电脑");
    }
}
//飞机类
public class Plane implements Product {
    @Override
    public void product() {
        System.out.println("生产了一架飞机,随时带你起飞");
    }
}

3. 创建另一个接口Color
这个接口表示不同的颜色(红色、绿色、彩色),
接口中声明一个方法表示给产品赋予一种颜色。

//颜色接口
public interface Color {
    void coloring();
}

4. 创建Color接口的实现类
三个实现类Red、Green、Rainbow分别表示三种不同的颜色(红色、绿色、彩色)。

//红色
public class Red implements Color {
    @Override
    public void coloring() {
        System.out.println("为产品增添了一层中国红");
    }
}
//绿色
public class Green implements Color {
    @Override
    public void coloring() {
        System.out.println("为产品赋予大自然之绿");
    }
}
//彩虹色
public class Rainbow implements Color {
    @Override
    public void coloring() {
        System.out.println("五彩斑斓,那是彩虹的颜色");
    }
}

5. 为 Color 和 Product对象创建抽象工厂AbstractFactory 来获取工厂
可以通过抽象工厂获取具体的产品工厂和颜色工厂

//抽象工厂类
public abstract class AbstractFactory {
    //生产产品的工厂
    public abstract Product createProduct(String productType);

    //为产品上色的工厂
    public abstract Color drawColor(String colorType);
}

6. 创建抽象工厂 AbstractFactory 的实现类,基于给定的信息生成实体类的对象。
ProductFactory是生产产品的工厂,用户生产出手机、电脑和飞机。
ColorFactory 是颜色工厂,用来给产品上色。

//生产产品的工厂
public class ProductFactory extends AbstractFactory {
    @Override
    public Product createProduct(String productType) {
        if(productType.equals("手机")){
            return new Phone();
        }else if(productType.equals("电脑")){
            return new Computer();
        }else if(productType.equals("飞机")){
            return new Plane();
        }else {
            System.out.println("传入产品类型有误!");
        }
        return null;
    }

    @Override
    public Color drawColor(String colorType) {
        return null;
    }
}
//产品上色的工厂
public class ColorFactory extends AbstractFactory {
    @Override
    public Product createProduct(String productType) {
        return null;
    }

    @Override
    public Color drawColor(String colorType) {
        if(colorType.equals("红色")){
            return new Red();
        }else if(colorType.equals("绿色")){
            return new Green();
        }else if(colorType.equals("彩虹色")){
            return new Rainbow();
        }else {
            System.out.println("传入产品类型有误!");
        }
        return null;
    }
}

7. 创建一个工厂创造器/生成器类,来获取具体工厂。

//工厂生成器
public class FactoryProducer {
    public static AbstractFactory getFactory(String type){
        if(type.equals("产品厂")){
            return new ProductFactory();
        } else if(type.equals("颜色厂")){
            return new ColorFactory();
        }
        return null;
    }
}

8. 使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
用过抽象工厂创建出两个具体工厂,在通过具体工厂生产出产品和颜色对象。

public class FactoryMain {
    public static void main(String[] args) {
        //获取生产产品的工厂
        AbstractFactory product = FactoryProducer.getFactory("产品厂");
        //获取增加颜色的工厂
        AbstractFactory color = FactoryProducer.getFactory("颜色厂");

        //生产一部手机
        Product phone = product.createProduct("手机");
        phone.product();
        //为手机上色
        Color red = color.drawColor("红色");
        red.coloring();

    }
}

便于理解,下面给出几个类的关系图:
在这里插入图片描述

单例模式

单例模式是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,指一个类只有一个实例,且该类能自行创建这个实例的一种模式。

单例模式有 3 个特点:

  • 单例类只有一个实例对象;
  • 该单例对象必须由单例类自行创建;
  • 单例类对外提供一个访问该单例的全局访问点。

通常有两种方式用来实现单例模式:懒汉式、饿汉式

懒汉式
懒汉式不在类加载的时候生成实例,只有当第一次调用 getlnstance 方法时才去创建这个单例。

//懒汉式
public class LazySingle {
    private static LazySingle instance;

    private LazySingle(){}

    public static synchronized LazySingle getInstance(){
        if (instance == null){
            instance = new LazySingle();
        }

        return instance;
    }
}

饿汉式
饿汉式中类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。

//饿汉式
public class HungrySingle {

    private final static HungrySingle instance = new HungrySingle();

    private HungrySingle(){}

    public static HungrySingle getInstance(){
        return instance;
    }
}

测试

public class SingleMain {
    public static void main(String[] args) {
        LazySingle lazySingle1 = LazySingle.getInstance();
        LazySingle lazySingle2 = LazySingle.getInstance();

        System.out.println("懒汉式创建的第一个对象:" + lazySingle1);
        System.out.println("懒汉式创建的第二个对象:" + lazySingle2);
        System.out.println(lazySingle1 == lazySingle2);

        HungrySingle hungrySingle1 = HungrySingle.getInstance();
        HungrySingle hungrySingle2 = HungrySingle.getInstance();

        System.out.println("饿汉式创建的第一个对象:" + hungrySingle1);
        System.out.println("饿汉式创建的第二个对象:" + hungrySingle2);
        System.out.println(hungrySingle1 == hungrySingle2);

    }
}

在这里插入图片描述
可以看到,不管是懒汉式还是饿汉式多次创建的都是对象完全一样,这也就体现了单例模式只会创建一个实例的特点。

原型模式

原型模式是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式。

它是用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,不需要知道对象创建的细节。

Java中提供了对象的 clone() 方法,所以实现原型模式很简单。他主要就包括了深克隆和浅克隆两种方式。

如果中java中的克隆不能很了解的话,可以参考我写的这篇文章:java中浅克隆与深克隆解析

原型模式的实现

  1. 创建一个原型类
public class Product implements Cloneable {

    Product(){
        System.out.println("创建一个原型对象");
    }

    public Object clone() throws CloneNotSupportedException {
        System.out.println("克隆一个原型对象");
        return super.clone();
    }
}
  1. 通过浅克隆实现对象的拷贝
public class PrototypeMain {
    public static void main(String[] args) throws CloneNotSupportedException {
        Product product = new Product();
        System.out.println(product);

        Product productCloned = (Product) product.clone();

        System.out.println(productCloned);
    }
}

在这里插入图片描述

浅克隆和深克隆的实现请参考:java中浅克隆与深克隆解析

建造者模式

在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

建造者模式的实现

假设我们要构造一台电脑,包括主机、显示器、键鼠套装三个部分。那么我们可以通过以下方式来实现建造者模式。

1. 创建一个电脑类
类中包括主机、显示器、键鼠套装三个属性,以及他们的set方法和一个show方法。

//电脑类
public class Computer {
    private String mainFrame;   //主机
    private String display;     //显示器
    private String keyboard;     //键鼠套装

    public void setMainFrame(String mainFrame) {
        this.mainFrame = mainFrame;
    }

    public void setDisplay(String display) {
        this.display = display;
    }

    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }

    public void showMessage(){
        System.out.println("这是一台电脑。");
    }
}

2. 创建建造者类
类中包含创建产品各个子部件的方法。

public class Builder extends AbstractBuilder {
    @Override
    public void buildMainFrame() {
        computer.setMainFrame("建造好了主机");
    }

    @Override
    public void buildDisplay() {
        computer.setDisplay("建造好了显示器");
    }

    @Override
    public void buildKeyboard() {
        computer.setKeyboard("建造好了键鼠套装");
    }
}

abstract class AbstractBuilder {
    //创建一个电脑对象
    Computer computer = new Computer();

    //构造主机
    public abstract void buildMainFrame();

    //构造显示器
    public abstract void buildDisplay();

    //构造键鼠套装
    public abstract void buildKeyboard();

    //返回电脑对象
    public Computer returnComputer(){
        return computer;
    }
}

3. 创建指挥者类
调用建造者中的方法完成复杂对象的创建。

public class Leader {
    private Builder builder;

    public Leader(Builder builder){
        this.builder = builder;
    }

    public Computer build(){
        builder.buildMainFrame();
        builder.buildDisplay();
        builder.buildKeyboard();
        return builder.returnComputer();
    }
}

4. 使用

public class BuilderMain {
    public static void main(String[] args) {
        Builder builder = new Builder();
        Leader leader = new Leader(builder);

        Computer computer = leader.build();
        computer.showMessage();
    }
}

适配器模式

当某种业务功能已经实现,但它们与当前系统的接口不兼容,如果重新开发成本又很高,这时用适配器模式能很好地解决这些问题。

适配器模式是作为两个不兼容的接口之间的桥梁,属于结构型模式,它结合了两个独立接口的功能。

将一个类的接口转换成需要的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

适配器模式的实现:

假设有两款不同年代的电脑,一台功率100W,另一台功率200W。但是现在只有一个100W的充电器,我们要让它为200W的电脑充电,这时候我们就需要创建一个适配器来完成这个工作。

1. 创建一个充电接口
该提供一个按类型充电的方法。

//提供一个按类型充电的方法
public interface Charge {
    public void charge(String type);
}

2. 创建100W充电器接口
在这个接口中,提供一个方法可以为100W的电脑充电。

//100W充电器接口
public interface W100 {
    public void charge100W();
}

3. 创建100W充电接口的实现类

//100W充电的实现类
public class W100Impl implements W100 {
    @Override
    public void charge100W() {
        System.out.println("使用100W充电器给电脑充电");
    }
}

4. 创建适配器

//适配器
public class ChargeAdapter implements Charge {
    W100 w100;

    public ChargeAdapter(String type){
        if(type.equals("100w")){
            w100 = new W100Impl();
        }
    }

    @Override
    public void charge(String type) {
        w100.charge100W();
    }
}

5. 创建200W充电器实体

//适配器
//200w充电器
public class W200 implements Charge {

    ChargeAdapter chargeAdapter;
    @Override
    public void charge(String type) {
        if(type.equals("200w")){
            System.out.println("200W充电器正常充电");
        }else if(type.equals("100w")) {
            chargeAdapter = new ChargeAdapter(type);
            chargeAdapter.charge(type);
        }else{
            System.out.println("功率不兼容,充电失败!!!");
        }
    }
}

6. 测试充电结果

public class AdapterMain {
    public static void main(String[] args) {
        W200 w200 = new W200();

        //通过适配器使用100w充电器给200w电脑充电
        System.out.print("过适配器使用100w充电器给200w电脑充电:");
        w200.charge("100w");
        //通过适配器使用300w充电器给200w电脑充电
        System.out.print("过适配器使用300w充电器给200w电脑充电:");
        w200.charge("300w");
    }
}

在这里插入图片描述
从打印结果中我们可以看到,当使用100w充电器给200w电脑充电时,充电成功了;而使用300W充电器时,提示我们功率不兼容,这是因为我们只提供了100W的适配器,没有300W的适配器。如果想让300W的充电器给200W的电脑充电,那么就只需要按照上述步骤再添加一个300W适配器即可。

到此,我们实现了适配器模式,成功通过使用适配器让200W电脑兼容100W充电器,即使原本由于接口不兼容而不能一起工作的那些类能一起工作。

代理模式

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

在代理模式中,一个类代表另一个类的功能,为其他对象提供一种代理以控制对这个对象的访问。这种类型的设计模式属于结构型模式。

代理模式的实现

1. 创建一个接口

//接口
public interface Product {
    void show();
}

2. 创建接口的实体类

//接口的实体类
public class RealProduct implements Product {
    @Override
    public void show() {
        System.out.println("获取到一个真实产品RealProduct!");
    }
}

3. 创建接口的代理类
代理类提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。在代码中,一般代理会被理解为代码增强,实际上就是在原代码逻辑前后增加一些代码逻辑,而使调用者无感知。

//接口的代理类
public class ProxyProduct implements Product {
    private RealProduct realProduct;

    @Override
    public void show() {
        if(realProduct == null){
            realProduct = new RealProduct();
        }


        pre();          //代理增强方法,处理代理之前要做的事情
        realProduct.show();
        post();         //代理增强方法,处理代理之后要做的事情
    }

    public void pre(){
        System.out.println("代理之前要做的事情");
    }

    public void post(){
        System.out.println("代理之后要做的事情");
    }
}

4. 使用代理类来获取实体类的对象

public class ProxyMain {
    public static void main(String[] args) {
        ProxyProduct proxyProduct = new ProxyProduct();
        proxyProduct.show();
    }
}

在这里插入图片描述

桥接模式

在现实生活中,某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分。

桥接模式将抽象部分与它的实现部分分离开来,使他们都可以独立变化,它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

下面我们就通过桥接模式来创建不同颜色不同形状的图形。

桥接模式的实现:

1. 创建一个颜色接口

//颜色接口
public interface Color {
    //对传入的图形上色
    public void colorByShape();
}

2. 创建三种颜色

//红色
public class Red implements Color {
    @Override
    public void colorByShape() {
        System.out.print("红色的");
    }
}
//绿色
public class Green implements Color {
    @Override
    public void colorByShape() {
        System.out.print("绿色的");
    }
}
//彩色
public class Rainbow implements Color {
    @Override
    public void colorByShape() {
        System.out.print("彩色的");
    }
}

3. 创建形状抽象类

//形状抽象类
public abstract class Shape {
    Color color;

    public abstract void draw();    //画形状

    public void setColor(Color color) {
        this.color = color;
    }
}

4. 创建三种具体的形状

//圆形
public class Circle extends Shape {
    @Override
    public void draw() {
        this.color.colorByShape();
        System.out.println("圆形的");
    }
}
//三角形
public class Triangle extends Shape {
    @Override
    public void draw() {
        this.color.colorByShape();
        System.out.println("三角形的");
    }
}
//矩形
public class Rectangle extends Shape {
    @Override
    public void draw() {
        this.color.colorByShape();
        System.out.println("矩形的");
    }
}

5. 给形状上颜色(桥接)

public class BridgeMain {
    public static void main(String[] args) {
        Color red = new Red();      //红色
        Shape circle = new Circle();        //圆形
        circle.setColor(red);
        circle.draw();              //画红色的圆形

        Color rainbow = new Rainbow();      //彩色
        Shape triangle = new Triangle();    //三角形
        triangle.setColor(rainbow);
        triangle.draw();            //画彩色的三角形
    }
}

在这里插入图片描述

装饰器模式

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式属于结构型模式,它是作为现有的类的一个包装。

使用给手机添加不同的功能为例,来实现装饰器模式:

装饰器模式的实现

1. 创建一个产品接口

//产品接口
public interface Product {
    public void function();     //产品的功能
}

2. 创建一个手机类实现产品接口

//手机实体
public class Phone implements Product {
    public Phone(){
        System.out.println("创建一个手机");
    }
    @Override
    public void function() {
        System.out.println("手机可以用来打电话");
    }
}

3. 创建一个装饰器类实现产品接口

//装饰器
public class Decorator implements Product {
    private Product product;

    public Decorator(Product product){
        this.product = product;
    }
    @Override
    public void function() {
        product.function();
    }
}

4. 创建一个手机装饰器,为手机增加功能

//手机装饰器
public class PhoneDecorator extends Decorator {
    public PhoneDecorator(Product product) {
        super(product);
    }

    @Override
    public void function() {
        super.function();
        addFunction();
    }

    public void addFunction(){
        System.out.println("给手机增加一个发短信的功能");
    }
}

5. 原手机和使用手机装饰器后的手机功能比较

public class DecoratorMain {
    public static void main(String[] args) {
        Product phone = new Phone();
        phone.function();
        System.out.println("=========================");

        Product new_phone = new PhoneDecorator(phone);
        new_phone.function();
    }
}

在这里插入图片描述

外观模式

外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

外观模式的实现
假设我们解决一个问题需要经过设计、建模、运行三个阶段,我们使用外观模式来隐藏这三个阶段,只给用户提供一个解决问题的接口。

1. 创建设计类

//设计
public class Design {
    public void design(){
        System.out.println("一:设计");
    }
}

2. 创建模型类

//建模
public class Model {
    public void model(){
        System.out.println("二:建模");
    }
}

3. 创建运行类

//运行
public class Run {
    public void run(){
        System.out.println("三: 运行");
    }
}

4. 创建外观类

public class Facade {
    private Design design = new Design();
    private Model model = new Model();
    private Run run = new Run();

    public void method(){
        design.design();
        model.model();
        run.run();
        System.out.println("问题解决了");
    }
}

5. 使用外观类解决问题

public class FacadeMain {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

在这里插入图片描述

享元模式

享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

享元模式的实现:

1. 创建手机类

//手机类
public class Phone {
    private String brand;       //品牌
    private int cost;           //价格

    public Phone(String brand){
        this.brand = brand;
    }

    public void setCost(int cost) {
        this.cost = cost;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "brand='" + brand + '\'' +
                ", cost=" + cost +
                '}';
    }
}

2. 创建手机工厂类

public class PhoneFactory {
    private static final HashMap<String,Phone> pool = new HashMap<>();

    public static Phone getPhone(String brand){
        Phone phone = pool.get(brand);

        if(phone == null){
            phone = new Phone(brand);
            pool.put(brand,phone);
            System.out.println("创建了一个" + brand + "手机");
        }

        return phone;

    }
}

3. 使用享元模式

public class FlyWeightMain {
    public static void main(String[] args) {
        String[] brands = {"华为","vivo","oppo","小米","华为","vivo","oppo","小米","华为"};
        for(int i=0;i<brands.length;i++){
            Phone phone = PhoneFactory.getPhone(brands[i]);
            phone.setCost((int) (Math.random() * 5000));
            System.out.println(phone.toString());
        }

    }
}

在这里插入图片描述
可以看到我们好像创建和很多手机实例,但是只真正创建了4个对象,其他的都是对对象的重复使用。

组合模式

组合模式,又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

我们通过下面的实例来演示组合模式的用法。

组合模式的实现:
假设现在有一个学校,学校中校长管理一些老师,老师管理一些学生,我们通过实例演示了这个学校中人员的层次结构。

  1. 创建一个Person类
//表示一个人
public class Person {
    private String type;        //职位
    private String name;        //姓名
    private List<Person> person_list;       //管理的人员

    public Person(String type, String name) {
        this.type = type;
        this.name = name;
        person_list = new ArrayList<>();
    }

    public void add(Person person){
        person_list.add(person);
    }

    public void remove(Person person){
        person_list.remove(person);
    }

    public List<Person> getPerson_list(){
        return person_list;
    }

    @Override
    public String toString() {
        return "Person{" +
                "type='" + type + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
  1. 实例来演示组合模式
public class CompositeMain {
    public static void main(String[] args) {
        Person master = new Person("校长","王校长");

        Person teacher1 = new Person("老师","张老师");
        Person teacher2 = new Person("老师","李老师");

        Person student1 = new Person("学生","学生1");
        Person student2 = new Person("学生","学生2");
        Person student3 = new Person("学生","学生3");

        master.add(teacher1);
        master.add(teacher2);

        teacher1.add(student1);
        teacher1.add(student2);
        teacher1.add(student3);

        teacher2.add(student1);
        teacher2.add(student2);
        teacher2.add(student3);

        System.out.println(master);
        for(Person leadPerson:master.getPerson_list()){
            System.out.println(leadPerson);
            for(Person student:leadPerson.getPerson_list()){
                System.out.println(student);
            }
        }

    }
}

在这里插入图片描述

模板模式

模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

模板模式的实现:

  1. 创建抽象模板类
//模板类
public abstract class TemplateClass {
    public void templateMethod(){
        specificMethod();
        method1();
        method1();
    }

    public void specificMethod(){
        System.out.println("模板中规定的特殊方法");
    }

    public abstract void method1();

    public abstract void method2();
}
  1. 创建两个具体的类,实现模板的两种方式

方式一

public class ConcreteClass1 extends TemplateClass {
    @Override
    public void method1() {
        System.out.println("根据模板指定的方案一的第一步");
    }

    @Override
    public void method2() {
        System.out.println("根据模板指定的方案一的第二步");
    }
}

方式二

public class ConcreteClass2 extends TemplateClass {
    @Override
    public void method1() {
        System.out.println("根据模板指定的方案二的第一步");
    }

    @Override
    public void method2() {
        System.out.println("根据模板指定的方案二的第二步");
    }
}
  1. 测试模板模式
public class TemplateMain {
    public static void main(String[] args) {
        TemplateClass template1 = new ConcreteClass1();
        template1.templateMethod();

        TemplateClass template2 = new ConcreteClass2();
        template2.templateMethod();
    }
}

在这里插入图片描述

解释器模式

解释器模式提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。

解释器模式主要包括以下几个部分:

  • 抽象表达式角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  • 终结符表达式角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  • 环境角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  • 客户端:主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

解释器模式的实现:
假设你现在要买一台联想的16寸的电脑,其他品牌和尺寸的不考虑。我们现在使用解释器模式来表达它。

1. 抽象表达式接口

//抽象表达式接口
public interface Expression {
    public boolean interpret(String context);
}

2. 终结符表达式

//终结符表达式
public class TerminalExpression implements Expression {
    private String message;

    public TerminalExpression(String message){
        this.message = message;
    }

    @Override
    public boolean interpret(String context) {
        if(context.equals(message)){
            return true;
        }else{
            return false;
        }
    }
}

3. 非终结符表达式

public class AndExpression implements Expression {
    private Expression brand = null;
    private Expression size = null;

    public AndExpression(Expression brand, Expression size) {
        this.brand = brand;
        this.size = size;
    }

    @Override
    public boolean interpret(String context) {
        String[] info = context.split(" ");
        return brand.interpret(info[0]) && size.interpret(info[1]);     //当品牌和尺寸都满足的时候才买
    }
}

4. 环境角色

//上下文环境类
public class Context {
    private String brand = "联想";
    private String size = "16寸";
    private Expression expression = null;

    public Context(){
        Expression brand = new TerminalExpression(this.brand);
        Expression size = new TerminalExpression(this.size);
        expression = new AndExpression(brand,size);
    }

    public void result(String context){
        boolean target = expression.interpret(context);
        if(target){
            System.out.println(context + ":是我想要的电脑,买了");
        }else{
            System.out.println(context + ": 不满足我的要求");
        }
    }
}

5. 客户端

public class InterpretMain {
    public static void main(String[] args) {
        Context context = new Context();
        context.result("戴尔 13寸");
        context.result("华硕 16寸");
        context.result("联想 13寸");
        context.result("联想 16寸");
    }
}

在这里插入图片描述

命令模式

命令模式是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

命令模式也就是一个用户发送请求,调用者接收命令,再将命令发送给接受者,最后接收者作出相应的过程

命令模式的实现:

1. 创建接受者

public class Receiver {
    public void action(){
        System.out.println("接受者执行方法");
    }
}

2. 创建命令

public class Command {
    private Receiver receiver;

    public Command(){
        receiver = new Receiver();
    }

    public void execute(){
        System.out.println("命令传到了接收者");
        receiver.action();
    }
}

3. 创建调用者

public class Invoker {
    private Command command;
    public Invoker(Command command){
        this.command = command;
    }

    public void send(){
        System.out.println("调用者收到命令");
        command.execute();
    }
}

4. 用户发出请求

public class CommandMain {
    public static void main(String[] args) {
        Command command = new Command();
        Invoker invoker = new Invoker(command);
        System.out.println("用户发起请求");
        invoker.send();
    }
}

在这里插入图片描述

策略模式

策略模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

下面我们通过加减乘的运算来实现策略模式。

策略模式的实现;

1. 创建一个策略接口

public interface Strategy {
    public int operate(int x,int y);
}

2. 创建策略接口的三个实现类,分别表示加减乘运算

public class AddStrategy implements Strategy {
    @Override
    public int operate(int x, int y) {
        return x + y;
    }
}
public class SubStrategy implements Strategy {
    @Override
    public int operate(int x, int y) {
        return x - y;
    }
}
public class MultStrategy implements Strategy {
    @Override
    public int operate(int x, int y) {
        return x * y;
    }
}

3. 使用 Context 来查看当它改变策略 时的行为变化。

public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int execute(int x,int y){
        return strategy.operate(x,y);
    }
}

4. 使用策略模式完成加减乘运算

public class StrategyMain {
    public static void main(String[] args) {
        int x = 24;
        int y = 8;
        Context context1 = new Context(new AddStrategy());
        int add = context1.execute(x,y);
        System.out.println("x = 24, y = 8, x+y=" + add);

        Context context2 = new Context(new SubStrategy());
        int sub = context2.execute(x,y);
        System.out.println("x = 24, y = 8, x-y=" + sub);

        Context context3 = new Context(new MultStrategy());
        int mult = context3.execute(x,y);
        System.out.println("x = 24, y = 8, x*y=" + mult);
    }
}

在这里插入图片描述

状态模式

状态模式中,类的行为是基于它的状态改变的,允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。这种类型的设计模式属于行为型模式。

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

状态模式的实现:

1. 创建状态的抽象类

//抽象状态类
public abstract class State {
   public abstract void handle(Context context);
}

2. 创建抽象类的两个具体状态

//状态A
public class Astate extends State {
   @Override
   public void handle(Context context) {
       System.out.println("当前状态为A,A状态执行结束,改变状态为B");
       context.setState(new Bstate());
   }
}
//状态B
public class Bstate extends State {
   @Override
   public void handle(Context context) {
       System.out.println("当前状态为B,B状态执行结束,改变状态为A");
       context.setState(new Astate());
   }
}

3. 创建Context

public class Context {
   private State state;

   public Context() {
       this.state = new Astate();
   }

   public void setState(State state) {
       this.state = state;
   }

   public State getState() {
       return (state);
   }

   public void handle() {
       state.handle(this);
   }
}

4. 状态模式测试

public class StateMain {
   public static void main(String[] args) {
       Context context = new Context();
       context.handle();
       context.handle();
       context.handle();
       context.handle();
       context.handle();
   }
}

在这里插入图片描述

观察者模式

观察者模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

观察者模式存在一个控制主体,和许多的观察者,当控制主体状态改变时,所有观察者也都会做出反应。

观察者模式的实现;

1. 创建观察者抽象类

//抽象观察者
public abstract class Observer {
    public abstract void update();
}

2. 创建三个具体观察者

//观察者A
public class AObserver extends Observer {
    @Override
    public void update() {
        System.out.println("观察者A做出反应");
    }
}
//观察者B
public class BObserver extends Observer {
    @Override
    public void update() {
        System.out.println("观察者B做出反应");
    }
}
//观察者A
public class CObserver extends Observer {
    @Override
    public void update() {
        System.out.println("观察者C做出反应");
    }
}

3. 创建控制主体

public class Subject {
    private List<Observer> observers = new ArrayList<>();

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        notifyAllObservers();
    }

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

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

观察者模式测试

public class VisitorMain {
    public static void main(String[] args) {
        Subject subject = new Subject();

        subject.add(new AObserver());
        subject.add(new BObserver());
        subject.add(new CObserver());

        System.out.println("主体状态改变");
        subject.setState("change");
    }
}

在这里插入图片描述

责任链模式

责任链模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。

责任链的实现:

1. 创建一个处理者抽象类

//处理者抽象类
public abstract class Handler {
    private Handler nextHandler;

    public Handler getNextHandler() {
        return nextHandler;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handle(String request);
}

2. 创建三个具体的处理者

//处理者A
public class AHandler extends Handler {
    @Override
    public void handle(String request) {
        if (request.equals("A")){
            System.out.println("A号处理者处理了这个问题");
        }else{
            if (this.getNextHandler() != null){
                this.getNextHandler().handle(request);
            }else{
                System.out.println("这个问题没有人处理");
            }
        }
    }
}
//处理者B
public class BHandler extends Handler {
    @Override
    public void handle(String request) {
        if (request.equals("B")){
            System.out.println("B号处理者处理了这个问题");
        }else{
            if (this.getNextHandler() != null){
                this.getNextHandler().handle(request);
            }else{
                System.out.println("这个问题没有人处理");
            }
        }
    }
}
//处理者C
public class CHandler extends Handler {
    @Override
    public void handle(String request) {
        if (request.equals("C")){
            System.out.println("C号处理者处理了这个问题");
        }else{
            if (this.getNextHandler() != null){
                this.getNextHandler().handle(request);
            }else{
                System.out.println("这个问题没有人处理");
            }
        }
    }
}

3. 构建责任链处理问题

public class ChainMain {
    public static void main(String[] args) {
        Handler A = new AHandler();
        Handler B = new BHandler();
        Handler C = new CHandler();

        A.setNextHandler(B);
        B.setNextHandler(C);

        A.handle("A");
        A.handle("B");
        A.handle("C");
        A.handle("D");

    }
}

在这里插入图片描述

备忘录模式

备忘录模式保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

备忘录模式的实现:

备忘录模式的主要角色如下:

  • 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
  • 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
  • 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

1. 创建备忘录类

//备忘录类
public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

2. 创建发起人类

//获取备忘录状态
public class Originator {
    private String state;

    public void setState(String state){
        this.state = state;
    }

    public String getState(){
        return state;
    }

    public Memento saveStateToMemento(){
        return new Memento(state);
    }

    public void getStateFromMemento(Memento Memento){
        state = Memento.getState();
    }
}

3. 创建管理者类

//获取备忘录状态
//恢复备忘录状态
public class Caretaker {
    private List<Memento> mementoList = new ArrayList<Memento>();

    public void add(Memento state){
        mementoList.add(state);
    }

    public Memento get(int index){
        return mementoList.get(index);
    }
}

4. 备忘录模式测试

public class MementoMain {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker careTaker = new Caretaker();
        originator.setState("状态:S1");
        originator.setState("状态:S2");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("状态:S3");
        careTaker.add(originator.saveStateToMemento());
        originator.setState("状态:S4");

        System.out.println("当前状态" + originator.getState());
        originator.getStateFromMemento(careTaker.get(0));
        System.out.println("第一次保存的状态" + originator.getState());
        originator.getStateFromMemento(careTaker.get(1));
        System.out.println("第二次保存的状态" + originator.getState());
    }
}

在这里插入图片描述

中介者模式

中介者模式定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介者模式的实现:

1. 创建一个Person类

//一个用户
public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(String name){
        this.name  = name;
    }

    public void sendMessage(String message){
        Mediator.send(this,message);
    }
}

创建一个中介类

//中介类
public class Mediator {
    public static void send(Person person,String message){
        System.out.println(new Date().toString() + " | " + person.getName() + ":" + message);
    }
}

模拟聊天

public class MediatorMain {
    public static void main(String[] args) {
        Person person1 = new Person("张三");
        Person person2 = new Person("李四");

        person1.sendMessage("你好啊,李四,最近怎么样");
        person2.sendMessage("我很好,张三你呢");
    }
}

在这里插入图片描述

迭代器模式

迭代器模式的定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式。

迭代器模式的实现:

1. 创建一个迭代器接口

//迭代器
public interface Iterator {
    public boolean hasNext();
    public Object next();
}

2. 创建一个容器类,并创建内部类实现迭代器接口

public class Container {

    public String[] names;

    public Container(String[] names) {
        this.names = names;
    }

    public Iterator getIterator(){
        return new PersonIterator();
    }

    private class PersonIterator implements Iterator{

        int index;

        @Override
        public boolean hasNext() {
            if(index< names.length){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names[index++];
            }
            return null;
        }
    }
}

3. 使用迭代器输出所有内容

public class IteratorMain {
    public static void main(String[] args) {
        String[] names = {"张三","李四","王五","赵六","小七","老八"};
        Container container = new Container(names);
        Iterator iterator = container.getIterator();

        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

在这里插入图片描述

访问者模式

访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

访问者模式包含以下主要角色。

  • 抽象访问者角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素。
  • 具体访问者角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。
  • 抽象元素角色:声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数。
  • 具体元素角色:实现抽象元素角色提供的 accept() 操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。
  • 对象结构角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。

访问者模式的实现:

1. 创建访问者接口

public interface Visitor {
    void visit(Element element);
}

2. 创建具体访问者

public class AVisitor implements Visitor {
    @Override
    public void visit(Element element) {
        System.out.println(this.getClass().getName() + "访问了" + element.getClass().getName());
    }
}
public class BVisitor implements Visitor {
    @Override
    public void visit(Element element) {
        System.out.println(this.getClass().getName() + "访问了" + element.getClass().getName());
    }
}

3. 创建元素接口

public interface Element {
    void accept(Visitor visitor);
}

4. 创建具体元素

public class AElement implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
public class BElement implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

5. 创建对象结构类

public class Structure {
    private List<Element> elements = new ArrayList<>();

    public void add(Element element){
        elements.add(element);
    }

    public void remove(Element element){
        elements.remove(element);
    }

    public void accept(Visitor visitor){
        for(Element element:elements){
            visitor.visit(element);
        }
    }
}

6. 访问者模式测试

public class VisitorMain {
    public static void main(String[] args) {
        Structure structure = new Structure();
        structure.add(new AElement());
        structure.add(new BElement());

        Visitor visitor_A = new AVisitor();
        structure.accept(visitor_A);

        Visitor visitor_B = new BVisitor();
        structure.accept(visitor_B);
    }
}

在这里插入图片描述

  • 36
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1 + 1=王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值