java常用的设计模式


在这里插入图片描述

1、类图

类图:类与其他类之间的关系
在这里插入图片描述
一个简单的类图就可以这么画
在这里插入图片描述
在这里插入图片描述

1、类与类的关联关系表示方式

1、关联关系

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、聚合关系

在这里插入图片描述

3、组合关系

在这里插入图片描述

4、依赖关系

在这里插入图片描述

5、继承关系

在这里插入图片描述

6、实现关系

在这里插入图片描述

2、软件设计原则

2.1、开闭原则

在这里插入图片描述
类图:
在这里插入图片描述
一个抽象皮肤类,子类为默认的皮肤和黑马皮肤。搜狗输入法引用抽象皮肤类
AbstractSkin

package org.example.demo;

/**
 * 抽象皮肤类
 */
public abstract class AbstractSkin {

    /**
     * 显示皮肤
     */
    public abstract void display();
}

DefaultSkin

package org.example.demo;

/**
 * 默认皮肤类
 */
public class DefaultSkin extends AbstractSkin{
    @Override
    public void display() {
        System.out.println("默认皮肤");
    }
}

HeimaSkin

package org.example.demo;

public class HeimaSkin extends AbstractSkin{
    @Override
    public void display() {
        System.out.println("黑马皮肤");
    }
}

SougouInput

package org.example.demo;

/**
 * 搜狗输入法
 */
public class SougouInput {
    /**
     * 聚合
     */
    private AbstractSkin skin;

    /**
     * 提供setter方法
     */
    public void setSkin(AbstractSkin skin) {
        this.skin = skin;
    }

    /**
     * 调用皮肤的显示方法
     */
    public void display(){
        skin.display();
    }
}

Client

package org.example.demo;

/**
 * 测试类
 */
public class Client {
    public static void main(String[] args) {
        // 1、创建搜狗输入法对象
        SougouInput input = new SougouInput();
        // 2、创建皮肤对象
        HeimaSkin skin = new HeimaSkin();
        // 3、设值
        input.setSkin(skin);
        // 4、调用display方法
        input.display();
    }
}

每次只需修改第二步就能实现对扩展开放,对修改关闭

2.2、里氏替换原则

子类扩展父类的功能,但不重写父类的方法
在这里插入图片描述
Rectangle

package org.spring.designer.demo2;

/**
 * 长方形类
 */
public class Rectangle {
    private double length;

    private double width;

    public double getLength() {
        return length;
    }

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

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }
}

Square

package org.spring.designer.demo2;

/**
 * 正方体类
 */
public class Square extends Rectangle {

    @Override
    public void setLength(double length) {
        super.setLength(length);
        super.setWidth(length);
    }

    @Override
    public void setWidth(double width) {
        super.setWidth(width);
        super.setLength(width);
    }
}

RectangleDemo

package org.spring.designer.demo2;

public class RectangleDemo {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(10);
        rectangle.setLength(20);
        resize(rectangle);
        printLengthAndWidth(rectangle);
        System.out.println("==============================================");
        Square square = new Square();
        square.setLength(10);
        square.setWidth(10);
        resize(square);
        printLengthAndWidth(square);
    }

    // 扩宽方法
    public static void resize(Rectangle rectangle){
        while (rectangle.getWidth() <= rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
        }
    }

    // 打印长宽方法
    public static void printLengthAndWidth(Rectangle rectangle){
        System.out.println(rectangle.getLength());
        System.out.println(rectangle.getWidth());
    }
}

执行以后发现长方形满足这段代码,正方形不满足。会死循环
在这里插入图片描述

在这里插入图片描述
则正方形不是长方形

在这里插入图片描述
改进后代码:
Quadrilateral

package org.spring.designer.demo2.after;

/**
 * 四边形接口
 */
public interface Quadrilateral {

    // 获取长
    double getLength();

    // 获取宽
    double getWidth();
}

Square

package org.spring.designer.demo2.after;

public class Square implements Quadrilateral {

    private double size;

    public void setSize(double size) {
        this.size = size;
    }

    @Override
    public double getLength() {
        return size;
    }

    @Override
    public double getWidth() {
        return size;
    }
}

Rectangle

package org.spring.designer.demo2.after;

public class Rectangle implements Quadrilateral {

    private double length;

    private double width;

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

    public void setWidth(double width) {
        this.width = width;
    }

    @Override
    public double getLength() {
        return length;
    }

    @Override
    public double getWidth() {
        return width;
    }
}

RectangleDemo

package org.spring.designer.demo2.after;

public class RectangleDemo {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.setWidth(10);
        rectangle.setLength(20);
        resize(rectangle);
        printLengthAndWidth(rectangle);
        System.out.println("==============================================");
    }

    // 扩宽方法
    public static void resize(Rectangle rectangle){
        while (rectangle.getWidth() <= rectangle.getLength()){
            rectangle.setWidth(rectangle.getWidth()+1);
        }
    }

    // 打印长宽方法
    public static void printLengthAndWidth(Rectangle rectangle){
        System.out.println(rectangle.getLength());
        System.out.println(rectangle.getWidth());
    }
}

2.3、依赖翻转原则

在这里插入图片描述
XiJieHardDisk

package org.spring.designer.demo3.before;

/**
 * 希捷硬盘类
 */
public class XiJieHardDisk {
    public void save(String data){
        System.out.println("使用希捷硬盘保存数据:"+data);
    }

    public String get(){
        System.out.println("使用希捷硬盘读取数据");
        return "数据";
    }
}

InterCpu

package org.spring.designer.demo3.before;

public class InterCpu {

    public void run(){
        System.out.println("使用inter处理器");
    }
}

KingstonMemory

package org.spring.designer.demo3.before;

public class KingstonMemory {

    public void save(){
        System.out.println("使用金士顿内存条");
    }
}

Computer

package org.spring.designer.demo3.before;

public class Computer {

    private XiJieHardDisk hardDisk;

    private InterCpu cpu;

    private KingstonMemory memory;

    public XiJieHardDisk getHardDisk() {
        return hardDisk;
    }

    public void setHardDisk(XiJieHardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public InterCpu getCpu() {
        return cpu;
    }

    public void setCpu(InterCpu cpu) {
        this.cpu = cpu;
    }

    public KingstonMemory getMemory() {
        return memory;
    }

    public void setMemory(KingstonMemory memory) {
        this.memory = memory;
    }

    public void run(){
        System.out.println("开始计算机");
        String data = hardDisk.get();
        System.out.println("从硬盘上获取的是:"+data);
        cpu.run();
        memory.save();
    }
}

ComputerDemo

package org.spring.designer.demo3.before;

public class ComputerDemo {
    public static void main(String[] args) {
        // 创建组件对象
        InterCpu cpu = new InterCpu();
        KingstonMemory memory = new KingstonMemory();
        XiJieHardDisk hardDisk = new XiJieHardDisk();

        Computer computer = new Computer();
        // 组装电脑
        computer.setHardDisk(hardDisk);
        computer.setMemory(memory);
        computer.setCpu(cpu);

        computer.run();
    }


}

在这里插入图片描述
在这里插入图片描述
优化后的,使用依赖翻转原则:
HardDisk

package org.spring.designer.demo3.after;

public interface HardDisk {
    // 保存数据
    public void save(String data);

    // 获取数据
    public String get();
}

Cpu

package org.spring.designer.demo3.after;

public interface Cpu {
    public void run();
}

Memory

package org.spring.designer.demo3.after;

public interface Memory {
    public void save();
}

XiJieHardDisk

package org.spring.designer.demo3.after;

/**
 * 希捷硬盘类
 */
public class XiJieHardDisk implements HardDisk {
    public void save(String data){
        System.out.println("使用希捷硬盘保存数据:"+data);
    }

    public String get(){
        System.out.println("使用希捷硬盘读取数据");
        return "数据";
    }
}

InterCpu

package org.spring.designer.demo3.after;

public class InterCpu implements Cpu{

    public void run(){
        System.out.println("使用inter处理器");
    }
}

KingstonMemory

package org.spring.designer.demo3.after;

public class KingstonMemory implements Memory {

    public void save(){
        System.out.println("使用金士顿内存条");
    }
}

Computer

package org.spring.designer.demo3.after;

public class Computer {
    private HardDisk hardDisk;

    private Cpu cpu;

    private Memory memory;

    public HardDisk getHardDisk() {
        return hardDisk;
    }

    public void setHardDisk(HardDisk hardDisk) {
        this.hardDisk = hardDisk;
    }

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    public Memory getMemory() {
        return memory;
    }

    public void setMemory(Memory memory) {
        this.memory = memory;
    }

    public void run(){
        System.out.println("开始计算机");
        String data = hardDisk.get();
        System.out.println("从硬盘上获取的是:"+data);
        cpu.run();
        memory.save();
    }
}

ComputerDemo

package org.spring.designer.demo3.after;



public class ComputerDemo {
    public static void main(String[] args) {
        // 创建组件对象
        Cpu cpu = new InterCpu();
        Memory memory = new KingstonMemory();
        HardDisk hardDisk = new XiJieHardDisk();

        Computer computer = new Computer();
        // 组装电脑
        computer.setHardDisk(hardDisk);
        computer.setMemory(memory);
        computer.setCpu(cpu);

        computer.run();
    }
}

在这里插入图片描述

2.4、单一职责原则

在这里插入图片描述
单一职责:一个类不要承担多个职责。
1、类依赖过多的其他类。
导致修改一个类,其他类跟着受影响。不符合高内聚低耦合思想
2、类的名称和实际功能关联不大:
像用户和短信类。不是一回事可以不用放在一个类
3、类的代码行数过多,方法较大,应该拆分
比如需求如下:
后端需求:列表查询
在这里插入图片描述
前端需求
在这里插入图片描述

在这里插入图片描述
一个类有一个接口:通过参数的不同来区分前端查询接口,后端查询接口。(违背了单一职责原则)

怎么改变? 拆分接口(2个api)是最简单的改变方式
在这里插入图片描述

2.5、接口隔离原则

在这里插入图片描述
当用户类既可以删除和发送短信的时候,如果有两个团队同时开发。那很容易误操作
在这里插入图片描述

重构方式:
1、将user里的短信发送方法提取出来
在这里插入图片描述

2、单独写一个接口和实现类
在这里插入图片描述

3、下层注入MsgSender而不是注入User。User只负责注册。删除。不负责发送短信。

3、设计模式

3.1、单例模式(懒汉/饿汉模式)

懒汉模式:

package org.spring.designer.single;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {
       
    }
}

class LazySingleton {
    private static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        return lazySingleton;
    }
}

直接返回实例不合理进行改进

package org.spring.designer.single;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {

    }
}

class LazySingleton {
    private static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        if (null == lazySingleton){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

此时会出现线程不安全问题,改进方式:double check(双重加锁)

package org.spring.designer.single;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {

    }
}

class LazySingleton {
    private static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        // 当实例为空时加锁
        if (null == lazySingleton){
            synchronized (LazySingleton.class){
                // 当多个线程执行到这里时再次判断。双重加锁优化
                if (null == lazySingleton){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

但是此时线程安全问题虽然解决,但是存在空指针问题

new对象在jvm中会做以下操作:
1、开辟空间
2、初始化空间
3、给引用类型赋值

它不一定按着这个既定顺序执行
可能是这个顺序:
1、开辟空间
3、给引用类型赋值
2、初始化空间

###当t1线程执行到第三步,t2线程进来。发现实例并不为空,直接返回实例(此实例尚初始化空间),则导致空指针异常。如何避免?加关键字volatile

package org.spring.designer.single;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {

    }
}

class LazySingleton {
    private volatile static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        // 当实例为空时加锁
        if (null == lazySingleton){
            synchronized (LazySingleton.class){
                // 当多个线程执行到这里时再次判断。双重加锁优化
                if (null == lazySingleton){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

饿汉模式:

package org.spring.designer.single;

/**
 * 饿汉模式
 */
public class HungrySingletonTest {
    public static void main(String[] args) {

    }
}

class HungrySingleton{
    private static HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

package org.spring.designer.single;

/**
 * 饿汉模式
 */
public class HungrySingletonTest {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();

    }
}

class HungrySingleton{
    static {
        System.out.println("HungrySingleton class init");
    }

    private static HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

在这里插入图片描述

package org.spring.designer.single;

/**
 * 饿汉模式
 */
public class HungrySingletonTest {
    public static void main(String[] args) {
        System.out.println("name:"+HungrySingleton.name);
       // HungrySingleton hungrySingleton = HungrySingleton.getInstance();

    }
}

class HungrySingleton{
    public static String name = "ljs";

    static {
        System.out.println("HungrySingleton class init");
    }

    private static HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

在这里插入图片描述

当我们访问类的属性或方法时也会导致类的初始化
在这里插入图片描述
如何实现饿汉模式,在我们需要初始化类实例的时候,再初始化呢?
1、只初始化了外部的类

package org.spring.designer.single;

/**
 * 饿汉模式-匿名内部类(优化结构)
 */
public class InnerSingletonTest {
    public static void main(String[] args) {
        System.out.println(InnerSingleton.name);
        // System.out.println(InnerSingleton.getInstance());
    }
}

class InnerSingleton{
    public static String name = "ljs";

    static {
        System.out.println("init InnerSingleton");
    }
    private static class SingleHolder {
        static {
            System.out.println("init SingleHolder");
        }

        private static InnerSingleton instance = new InnerSingleton();

    }

    
        private InnerSingleton(){

        }

        public static InnerSingleton getInstance(){
            return SingleHolder.instance;
        }
    
}

在这里插入图片描述
2、两个类都被初始化了

package org.spring.designer.single;

/**
 * 饿汉模式-匿名内部类(优化结构)
 */
public class InnerSingletonTest {
    public static void main(String[] args) {
        //System.out.println(InnerSingleton.name);
        System.out.println(InnerSingleton.getInstance());
    }
}

class InnerSingleton{
    public static String name = "ljs";

    static {
        System.out.println("init InnerSingleton");
    }
    private static class SingleHolder {
        static {
            System.out.println("init SingleHolder");
        }

        private static InnerSingleton instance = new InnerSingleton();

    }

    
        private InnerSingleton(){

        }

        public static InnerSingleton getInstance(){
            return SingleHolder.instance;
        }

}

在这里插入图片描述
3、使用反射机制创建多实例。反射机制创建的实例与自己调用方法的实例不是同一个对象

package org.spring.designer.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 饿汉模式
 */
public class HungrySingletonTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        System.out.println("name:"+HungrySingleton.name);
       // HungrySingleton hungrySingleton = HungrySingleton.getInstance();
        // 反射机制创建多实例
        Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        HungrySingleton hungrySingleton = declaredConstructor.newInstance();
        HungrySingleton instance = HungrySingleton.getInstance();
        System.out.println(hungrySingleton == instance);
    }
}

class HungrySingleton{
    public static String name = "ljs";

    static {
        System.out.println("HungrySingleton class init");
    }

    private static HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

在这里插入图片描述
如何避免?在构造函数中进行判断

package org.spring.designer.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 饿汉模式
 */
public class HungrySingletonTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        System.out.println("name:"+HungrySingleton.name);
       // HungrySingleton hungrySingleton = HungrySingleton.getInstance();
        // 反射机制创建多实例
        Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        HungrySingleton hungrySingleton = declaredConstructor.newInstance();
        HungrySingleton instance = HungrySingleton.getInstance();
        System.out.println(hungrySingleton == instance);
    }
}

class HungrySingleton{
    public static String name = "ljs";

    static {
        System.out.println("HungrySingleton class init");
    }

    private static HungrySingleton hungrySingleton = new HungrySingleton();

    private HungrySingleton(){
        if (hungrySingleton != null){
            throw new RuntimeException("不允许多实例");
        }
    }

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

在这里插入图片描述
4、枚举类型

package org.spring.designer.single;

/**
 * 枚举类型单例模式测试
 */
public class EnumSingletonTest {
    public static void main(String[] args) {
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        EnumSingleton instance2 = EnumSingleton.INSTANCE;
        instance1.print();
        System.out.println(instance1 == instance2);
    }
}

enum EnumSingleton{
    INSTANCE;

    public void print(){
        System.out.println("xxxx");
    }
}

在这里插入图片描述

##类加载的双亲委派机制:
在这里插入图片描述

一个类加载器加载一个类时,首先会把加载动作委派给他的父加载器,如果父加载器无法完成这个加载动作时才由该类加载器进行加载。由于类加载器会向上传递加载请求,所以一个类加载时,首先尝试加载它的肯定是启动类加载器(逐级向上传递请求,直到启动类加载器,它没有父加载器),之后根据是否能加载的结果逐级让子类加载器尝试加载,直到加载成功。

###jdk1.8的Runtime类源码就是用的饿汉模式

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package java.lang;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    private Runtime() {
    }

}

###jvm的序列化,反序列化

序列化

package org.spring.designer.single;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {
        // 序列化
        LazySingleton instance = LazySingleton.getInstance();
        try {
            ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
            oos.writeObject(instance);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class LazySingleton implements Serializable {
    private volatile static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        // 当实例为空时加锁
        if (null == lazySingleton){
            synchronized (LazySingleton.class){
                // 当多个线程执行到这里时再次判断。双重加锁优化
                if (null == lazySingleton){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

在这里插入图片描述

反序列化

package org.spring.designer.single;

import java.io.*;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {
        // 序列化
        LazySingleton instance = LazySingleton.getInstance();
        /*try {
            ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
            oos.writeObject(instance);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        // 反序列化
        try(ObjectInputStream ois = new ObjectInputStream( new FileInputStream("test"))) {
            LazySingleton lazySingleton = (LazySingleton) ois.readObject();
            System.out.println(instance == lazySingleton);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class LazySingleton implements Serializable {
    private volatile static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        // 当实例为空时加锁
        if (null == lazySingleton){
            synchronized (LazySingleton.class){
                // 当多个线程执行到这里时再次判断。双重加锁优化
                if (null == lazySingleton){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

答案是false。这种反序列化方式是破坏了单例模式
如何解决呢?

需要在后面加一个方法

package org.spring.designer.single;

import java.io.*;

/**
 * 懒汉模式
 */
public class LazySingletonTest {

    public static void main(String[] args) {
        // 序列化
        LazySingleton instance = LazySingleton.getInstance();
        /*try {
            ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
            oos.writeObject(instance);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        // 反序列化
        try(ObjectInputStream ois = new ObjectInputStream( new FileInputStream("test"))) {
            LazySingleton lazySingleton = (LazySingleton) ois.readObject();
            System.out.println(instance == lazySingleton);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class LazySingleton implements Serializable {
    private volatile static LazySingleton lazySingleton;

    // 1、私有化类构造方法(避免直接创建该类实例)
    private LazySingleton() {
    }

    // 2、初始化实例方法
    public static LazySingleton getInstance() {
        // 当实例为空时加锁
        if (null == lazySingleton){
            synchronized (LazySingleton.class){
                // 当多个线程执行到这里时再次判断。双重加锁优化
                if (null == lazySingleton){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
    // 新增的方法
    Object readResolve() throws ObjectStreamException {
        return getInstance();
    }
}

但是出现了报错
在这里插入图片描述
这时候需定义一个常量

 // 避免反序列化报错
    private static final long serialVersionUID = 1577594553870516987L;

在这里插入图片描述

3.2、工厂模式

工厂模式定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类

类图
在这里插入图片描述
1、简单工厂形式:

package org.spring.designer.factory;

public class FactoryMethod{
    public static void main(String[] args) {
        Application application = new Application();
        Product product = application.getObject("0");
        product.createProduct();
    }
}

class SimpleFactory {
    public static Product createProdcut(String type) {
        if (type.equals("0")) {
            return new ProductB();
        } else if (type.equals("1")) {
            return new ProductB1();
        } else {
            return null;
        }
    }
}

interface Product{
    public void createProduct();
}

class ProductB implements Product{

    @Override
    public void createProduct() {
        System.out.println("product B createProduct");
    }
}

class ProductB1 implements Product{

    @Override
    public void createProduct() {
        System.out.println("product B1 createProduct");
    }
}

class Application{
    private Product createProduct(String type){
        return SimpleFactory.createProdcut(type);
    }

    Product getObject(String type){
        Product product = createProduct(type);
        return product;
    }
}



在这里插入图片描述
2、工厂方法模式:

package org.spring.designer.factory1;


public class FactoryMethod {
    public static void main(String[] args) {
        Application1 application1 = new ConcreteProductA1();
        Product1 object = application1.getObject();
        object.method1();
    }
}

// 稳定接口
interface Product1{
    public void method1();
}

// 具体实现
class ProductA implements Product1 {
    public void method1() {
        System.out.println("ProductA.method1 executed. ");
    }
}

class ProductA1 implements Product1 {
    public void method1() {
        System.out.println("ProductA1.method1 executed. ");
    }
}

abstract class Application1{
    abstract Product1 createProduct();

    Product1 getObject(){
        Product1 product = createProduct();
        return product;
    }
}

// 工厂方法具体实现类
class ConcreteProductA extends Application1 {
    @Override
    Product1 createProduct() {
        // ....
        return new ProductA();
    }
}

class ConcreteProductA1 extends Application1 {
    @Override
    Product1 createProduct() {
        //...
        return new ProductA1();
    }
}

在这里插入图片描述
应用场景

  1. 当你不知道改使用对象的确切类型的时候
  2. 当你希望为库或框架提供扩展其内部组件的方法时

主要优点:

  1. 将具体产品和创建者解耦

  2. 符合单一职责原则

  3. 符合开闭原则

3.3、抽象工厂模式

定义:提供一个创建一系列对象的接口,无需指定它们具体的类。

package org.spring.designer.abstractFactory;

public class AbstractFactoryTest {
    public static void main(String[] args) {
        IDatabaseUtils databaseUtils = new MysqlDataBaseUtil();
        IConnection connection = databaseUtils.getConnection();
        connection.connection();
        ICommand command = databaseUtils.getCommand();
        command.command();
    }
}

/**
 * 定义数据库连接
 */
interface IConnection{
    void connection();
}

class MysqlConnection implements IConnection{

    @Override
    public void connection() {
        System.out.println("mysql connected");
    }
}

/**
 * 定义发送
 */
interface ICommand{
    void command();
}

class MysqlCommand implements ICommand{

    @Override
    public void command() {
        System.out.println("mysql command");
    }
}


interface IDatabaseUtils{
    IConnection getConnection();

    ICommand getCommand();
}

class MysqlDataBaseUtil implements IDatabaseUtils{

    @Override
    public IConnection getConnection() {
        return new MysqlConnection();
    }

    @Override
    public ICommand getCommand() {
        return new MysqlCommand();
    }
}

在这里插入图片描述
如果要进行oracle的实现:

package org.spring.designer.abstractFactory;

public class AbstractFactoryTest {
    public static void main(String[] args) {
        IDatabaseUtils databaseUtils = new OracleDataBaseUtil();
        IConnection connection = databaseUtils.getConnection();
        connection.connection();
        ICommand command = databaseUtils.getCommand();
        command.command();
    }
}

/**
 * 定义数据库连接
 */
interface IConnection{
    void connection();
}

class MysqlConnection implements IConnection{

    @Override
    public void connection() {
        System.out.println("mysql connected");
    }
}

class OracleConnection implements IConnection{

    @Override
    public void connection() {
        System.out.println("oracle connected");
    }
}

/**
 * 定义发送
 */
interface ICommand{
    void command();
}

class MysqlCommand implements ICommand{

    @Override
    public void command() {
        System.out.println("mysql command");
    }
}

class OracleCommand implements ICommand{

    @Override
    public void command() {
        System.out.println("oracle command");
    }
}

interface IDatabaseUtils{
    IConnection getConnection();

    ICommand getCommand();
}

class MysqlDataBaseUtil implements IDatabaseUtils{

    @Override
    public IConnection getConnection() {
        return new MysqlConnection();
    }

    @Override
    public ICommand getCommand() {
        return new MysqlCommand();
    }
}

class OracleDataBaseUtil implements IDatabaseUtils{

    @Override
    public IConnection getConnection() {
        return new OracleConnection();
    }

    @Override
    public ICommand getCommand() {
        return new OracleCommand();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值