设计模式-学习总结

学习总结

    • 本文仅供自我学习使用
    • 设计模式
      • 一.创建型模式
        • 1.单例模式
          • (1).饿汉式
          • (2).懒汉式,双检锁
          • (3).静态内部类
          • (4).枚举
        • 2.原型模式
        • 3.工厂模式
          • (1).简单工厂模式
        • 4.抽象工厂模式
        • 5.建造者模式
      • 二.结构型模式
        • 6.适配器模式
        • 7.组合模式
        • 8.装饰器模式
        • 9.外观模式
        • 10.享元模式
        • 11.代理模式
          • (1).静态代理
          • (2).jdk动态代理
          • (3).cglib动态代理
        • 12.桥接模式
      • 三.行为型模式
        • 13.责任链模式
        • 14.命令模式
        • 15.解释器模式
        • 16.迭代器模式
        • 17.观察者模式
        • 18.状态模式
        • 19.模板模式
        • 20.中介者模式
        • 21.备忘录模式
        • 22.访问者模式
        • 23.策略模式
      • 四.其他
        • 24.过滤器模式
        • 25.空对象模式

本文仅供自我学习使用

最近一直在看鱼皮的是视频,也在学习新的知识,当然还没有加入知识星球,原因很简单一个字穷呗,前段时间看了鱼皮分享的一个自己的7个工作成长技巧打算尝试一下

1.每天读2-3篇的文章,可以是行业去世,技术类(自己工作有关的方向),一年接近1000篇
(1).大厂的技术博客,纯技术类,美团技术类,阿里技术团队等
(2).科技资讯类:量子位,差评,新智元,无敌信息差
(3).经验分享,编程趋势,技术干货:鱼皮,小林coding,java guide,程序喵,神光的编程笔记,小白debug,古时的风筝,苏三,阿秀(求职类)
2.持续学习新技术,每天抽不到一小时,看2-3集教程,坚持一个月,看完一整套的课程
3.复盘总结
(1).每天记录自己完成的工作,贴一个文档啥的都可以
(2).每月记录自己这个月重点的在做的事情,以及完成的工作,学习的情况等
(3).每半年/每完成一个大事,做一个复盘总结,记录自己做这件事的经历,过程,结果,好和不好的地方
4.整理属于自己的弹药库
经验积累很重要
(1).整理属于自己的dug库(你解决过的问题)
(2).整理属于自己的经验库(你踩过的坑)
(3).知识的积累:把你学过的所有的知识点,以碎片的形式进行记录整理,碎片整理起来更简单可复用
(4).软件库(工具库):整理自己的常用软件
5.分享
(1).分享自己的复盘总结和精力
(2).分享自己的弹药库
(3).分享自己学过的知识
(4).帮助别人答疑解惑
6.工作(目标)的拆解

设计模式

  • 创建型模式用于以灵活和高效的方式创建对象。包括Singleton模式、工厂模式和抽象工厂模式等。
  • 结构型模式用于组合类和对象以形成更大的结构。包括适配器模式、桥接模式和装饰器模式等。
  • 行为型模式用于处理类或对象之间的通信和控制流。包括观察者模式、策略模式和模板方法模式。
  • 设计模式的六大原则
  • 单一职责原则(SRP):一个类只应该有一个引起它变化的原因。
  • 开放封闭原则(OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  • 里氏替换原则(LSP):子类型必须能够替换掉它们的父类型。
  • 依赖倒置原则(DIP):高层模块不应该依赖于低层模块,两者都应该依赖于抽象接口;抽象接口不应该依赖于具体实现,具体实现应该依赖于抽象接口。
  • 接口隔离原则(ISP):不应该强迫一个类实现它不需要的接口,应该将接口拆分成更小和更具体的部分,以便客户端只需要知道它们感兴趣的部分。
  • 迪米特法则(LOD):一个对象应该对其他对象有尽可能少的了解,通常称为“最少知识原则”。

一.创建型模式

创建型模式用于以灵活和高效的方式创建对象

1.单例模式
(1).饿汉式

类在初始化的时候就实现实例化

public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {

    }

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

(2).懒汉式,双检锁

类在第一次调用的时候进行的实例化加载a

/**
 * 在懒汉式基础上加入双重检验锁,保证线程安全和性能。
 */
public class Singleton {
    private volatile static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
/**
 * 普通懒汉式
 */
public class Singleton2{
    //私有的默认构造子
    private Singleton2(){
        
    }
    //注意,这里没有final
    private static Singleton2 single=null;
    //静态工厂方法
    public synchronized static Singleton2 getInstance(){
        if(single==null){
            single=new Singleton2();
        }
        return single;
    }
}
(3).静态内部类
/**
 * 使用静态内部类来实现懒汉式单例模式,保证线程安全和性能。这种方式能达到双检锁方式一样的功效,但实现更简单。
 */
public class Singleton {
    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
(4).枚举
public enum Singleton {
    INSTANCE;

    private Singleton() {
        // 私有构造方法
        //
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

1.线程安全:
枚举单例模式是线程安全的。由于枚举常量只会被实例化一次,所以无论多少个线程并发访问,都能
保证只有一个实例被创建。
2.防止反射攻击
枚举单例模式天然地防止了反射攻击。在Java中,通过反射可以获取类的私有构造器,并强制创建实
例。但是,对于枚举类来说,私有构造器是无法被反射调用的,因此无法通过反射来创建枚举类的实
例。
3.防止序列化和反序列化问题
枚举单例模式也能防止序列化和反序列化问题。当一个枚举类型被序列化时,只会将枚举常量的名称
写入到序列化流中,而不会序列化枚举常量本身。当枚举类型被反序列化时,只会通过名称来获取对
应的枚举常量。因此,无论是序列化还是反序列化,都无法破坏枚举单例的特性。
枚举单例模式的应用场景

枚举单例模式适用于以下场景:
需要实现单例的类比较简单,没有复杂的初始化过程。
需要确保线程安全。
需要防止反射攻击和序列化问题。
由于枚举单例模式的优势,建议在满足以上条件的情况下使用枚举单例。
2.原型模式

以一个实例为原型克隆出来和他一样的实例
浅克隆

public class Person implements Cloneable {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 进行浅克隆  如果克隆对象里面的值发生改变也会影响到其他对象的值
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}

深克隆(原型引用类型,并且原型和引用类型都需要实现序列化,和实现克隆接口)


public class DeepProtoType implements Serializable, Cloneable {

    public String name; //String 属性
    public DeepCloneableTarget deepCloneableTarget;// 引用类型

    public DeepProtoType() {
        super();
    }

    //深拷贝 通过对象的序列化实现
    public Object deepClone() {

        //创建流对象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); //当前这个对象以对象流的方式输出
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepProtoType copyObj = (DeepProtoType) ois.readObject();
            return copyObj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            //关闭流
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e2) {
                System.out.println(e2.getMessage());
            }
        }
    }
}
	
3.工厂模式

java的工厂模式

(1).简单工厂模式

静态工厂方法模式,可以根据参数的不同返回不同类的实例,简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都是具有共同的父类.
设计模式-学习总结_第1张图片

小知识:
在面对对象程序设计而定时候,需要遵循开闭原则(开闭原则规定:程序对于扩展是开放的,对于修改是
封闭的),打个比方现在有一个生产螺丝的生产螺丝,现在突然加了一一个任务需要生产口罩,这个时候
可以选择新增一个生产线来进行生产口罩而不是再原来的基础上将生产螺丝的机器改为生产口罩的
生产线

/**
 * SimpleFactory 工厂类
 * 优点:创建和使用分开,创建完全交给工厂类
 * 缺点:工厂类不够灵活,对象特别多的时候工厂类都需要进行改动判断--后面可以参考策略模式改进
 */
public class SimpleFactory {

    public static Product createProduct(String type) {
        if (StringUtils.isNotEmpty(type) && type.equals("A")) {
            return new ProductA();
        } else {
            return new ProductB();
        }
    }

    public static void main(String[] args) {
        SimpleFactory.createProduct("A");
        SimpleFactory.createProduct("B");
    }

}

abstract class Product {
    public abstract void print();
}

/**
 * 对象产品A
 */
class ProductA extends Product {

    @Override
    public void print() {
        System.out.println("ProductA");
    }
}

/**
 * 对象产品B
 */
class ProductB extends Product {

    @Override
    public void print() {
        System.out.println("ProductB");
    }
}
4.抽象工厂模式

一个工厂下面还有其他多个工厂,可以理解为多个复合的简单工厂合集–这里实际上是属于违反开闭原则

public class FactoryPattern {
    public static void main(String[] args) {
        Factory factory = new AppleFactory();
        Phone phone = factory.createPhone();
        phone.print();
    }
}
interface  Phone{
    void print();
}

class Iphone implements Phone{

    @Override
    public void print() {
        System.out.println("安卓手机");
    }
}

class ApplePhone implements Phone{
    @Override
    public void print() {
        System.out.println("苹果手机");
    }
}

/**
 * 抽象工厂
 */
interface Factory{
    Phone createPhone();
}

/**
 * 安卓手机工厂类
 */
class IPhoneFactory implements Factory{

    @Override
    public Phone createPhone() {
        return new Iphone();
    }
}

/**
 * 苹果手机工厂类
 */
class AppleFactory implements Factory{

    @Override
    public Phone createPhone() {
        return new ApplePhone();
    }
}
5.建造者模式

这里是引用

二.结构型模式

结构型模式用于组合类和对象以形成更大的结构

6.适配器模式

将一个类的接口变换为客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的2
个类能够一起工作
和装饰者模式的区别:是适配器原有的接口挺好用的,但是客户端不兼容,适配器只是提供一个转换的作用,相当于客户端直接访问原有的接口之间的桥梁


/**
 * @program: 
 * @description: 适配器模式
 * @author: wsw
 * @create: 2023-11-28 10:16
 **/
public class AdapterPattern {
    public static void main(String[] args) {
        new Adapter(new Speaker()).translate();
    }

}
class Speaker{
    public String speak(){
        return "我是语言英语";
    }
}
/**
 * 定义适配器的接口
 */
interface Translator{
    public String translate();
}
/**
 * 调用适配的对象
 * 可以通过类的继承,关联使用,我们这里使用的是通过关联的方式进行
 */
class Adapter implements Translator{
    /**
     * 1.我们先将关联的对象传递过来
     */
    private Speaker speaker;
    public Adapter(Speaker speaker){
        this.speaker = speaker;
    }
    /**
     * 2.通过关联对象,调用其方法
     */
    @Override
    public String translate() {
        String speak = speaker.speak();
        //对于这个方法在做一些其他的处理
        return speak;
    }
}
/**
 * 定义一个适配器,通过继承的方式,实现适配的功能
 */
class Adapter2 extends Speaker implements Translator{
    /**
     * 1.先实现接口
     */
    @Override
    public String translate() {
        return null;
    }
}
7.组合模式
8.装饰器模式

动态的给一个对象添加一些额外的功能,就增加功能来说,装饰模式比生成子类更加灵活

设计模式-学习总结_第2张图片

public class DecoratorPattern {
    public static void main(String[] args) {
        new RobotDecorator(new FirstRobot()).doMoreThing();
    }

}

interface Robot {
    void doSomething();
}

/**
 * 装饰器
 */
class FirstRobot implements Robot {

    @Override
    public void doSomething() {
        System.out.println("我会走路");
        System.out.println("我会唱歌");
    }
}

 class RobotDecorator implements Robot {
    private Robot robot;

    public RobotDecorator(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void doSomething() {
        robot.doSomething();
    }

    public void doMoreThing(){
        robot.doSomething();
        System.out.println("我新增了跳舞功能");
    }
}

9.外观模式

要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,外
观模式提供一个高层次的接口,使得子系统更加容易使用


/**
 * @program:
 * @description: 外观模式
 * @author: wsw
 * @create: 2023-11-28 14:29
 **/
public class FacadePattern {
    public static void main(String[] args) {
        boolean prove = new Facade().prove();
    }

}

class SubFlow1 {
    boolean isTrue() {
        return true;
    }
}

class SubFlow2 {
    boolean isTrue() {
        return true;
    }
}

class SubFlow3 {
    boolean isTrue() {
        return true;
    }
}

/**
 * 定义外观类
 */
class Facade {
    SubFlow1 s1 = new SubFlow1();
    SubFlow2 s2 = new SubFlow2();
    SubFlow3 s3 = new SubFlow3();

    boolean prove() {
        return s1.isTrue() && s2.isTrue() && s3.isTrue();
    }
}
10.享元模式
11.代理模式

为其他对象提供一种代理以控制对这个对象的访问


/**
 * @program: 
 * @description: 代理模式
 * @author: wsw
 * @create: 2023-11-28 16:28
 **/
public class ProxyPattern {
    public static void main(String[] args) {
        new RealSubjectProxy().doWork();
    }
}

interface Subject {
    void doWork();
}

/**
 * 代理类
 */
class RealSubject implements Subject {

    @Override
    public void doWork() {
        System.out.println("我是目标对象");
    }
}

/**
 * 建立代理类与目标类的目标关系
 */
class RealSubjectProxy implements Subject {

    private RealSubject realSubject;

    public RealSubjectProxy() {
        try {
            this.realSubject = (RealSubject) this.getClass().getClassLoader().loadClass(RealSubject.class.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void connect() {
        System.out.println("建立连接");
    }

    public void log() {
        System.out.println("记录日志");
    }

    @Override
    public void doWork() {

        connect();
        realSubject.doWork();
        log();
    }
}

(1).静态代理
(2).jdk动态代理
(3).cglib动态代理
12.桥接模式

三.行为型模式

行为型模式用于处理类或对象之间的通信和控制流

13.责任链模式

是一种处理请求的模式,他让多个处理器都有机会处理该请求,直到其中某
一个处理成功位置,责任链模式把多个处理器串成链,然后让请求在链上进
行处理


/**
 * @program:
 * @description: 责任链模式
 * @author: wsw
 * @create: 2023-11-28 16:48
 **/
public class ChainRespPattern {
    public static void main(String[] args) {
        Handler leader1 = new Leader();
        Handler leader2 = new Boss();
        leader1.setNextHandler(leader2);
        leader1.process(1);
        leader1.process(13);

    }
}

abstract class Handler {
    protected Handler nextHandler;

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

    public abstract void process(Integer info);
}

class Leader extends Handler {

    @Override
    public void process(Integer info) {
        if (info > 11) {
            System.out.println("我是leader处理");
        } else {
            nextHandler.process(info);
        }
    }
}

class Boss extends Handler {

    @Override
    public void process(Integer info) {
        System.out.println("我是Boss处理");
    }
}

14.命令模式
15.解释器模式
16.迭代器模式
17.观察者模式

定义的是一种对象之间的依赖关系,具体的可以理解为1对多依赖,也可以
理解为发布订阅模式,使得每当一个对象状态发生改变的时候,其相关的依
赖对象皆得到通知并被自动更新
设计模式-学习总结_第3张图片设计模式-学习总结_第4张图片


/**
 * @program:
 * @description: 观察者模式  这里模拟债主向亲戚借钱
 * @author: wsw
 * @create: 2023-11-28 13:57
 **/
public class ObserverPattern {
    public static void main(String[] args) {
        Debit zhangSan = new ZhangSan();
        zhangSan.borrow(new Wangwu());
        zhangSan.borrow(new Zhaoliu());
        //现在张三有钱了通知亲戚可以过来要钱了
        zhangSan.notifyCredits();
    }
}

/**
 * 定义接口--借款方
 */
interface Debit {

    /**
     * 借钱--主人公张三
     *
     * @param credit
     */
    public void borrow(Credit credit);

    /**
     * 通知贷款方--亲戚
     */
    public void notifyCredits();
}

/**
 * 贷款方
 */
interface Credit {
    /**
     * 要钱
     */
    public void takeMoney();

}

/**
 * 定义借款方张三
 */
class ZhangSan implements Debit {
    private List<Credit> allCredits = new ArrayList<>();

    private Integer state = 0;//1表示有钱 ,0表示没钱

    @Override
    public void borrow(Credit credit) {
        allCredits.add(credit);
    }

    /**
     * 通知亲戚可以来要钱了
     */
    @Override
    public void notifyCredits() {
        allCredits.forEach(e->e.takeMoney());
    }
}

class Wangwu implements Credit{

    @Override
    public void takeMoney() {
        System.out.println("王五要钱!");
    }
}

class Zhaoliu implements Credit{

    @Override
    public void takeMoney() {
        System.out.println("赵六要钱!");
    }
}

18.状态模式

再有些业务逻辑书写的时候,少用if-else方式.建议不超过三层,如果超过三
层的情况下,逻辑判断代码可以使用卫语句、策略模式、状态模式等来进
行实现.
状态模式:允许一个对象在其内部状态改变的时候改变他的行为,对象看起
来似乎修改了他的类,其别名为状态对象,状态模式是一种对象行为型模式


/**
 * @program:
 * @description: 状态模式
 * @author: wsw
 * @create: 2023-11-28 14:41
 **/
public class StatusPattern {
    public static void main(String[] args) {
        Context zhangsan = new Context();
        zhangsan.changeState(new Happy());
        zhangsan.doSomething();
    }
}

abstract class State {
    abstract void doWork();
}

class Happy extends State {

    @Override
    void doWork() {
        System.out.println("积极心态");
        return;
    }
}

class Angry extends State {

    @Override
    void doWork() {
        System.out.println("消极心态");
        return;
    }
}

class Sad extends State {

    @Override
    void doWork() {
        System.out.println("摆烂状态");
        return;
    }
}

class Context {
    
    private State state;

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

    public void doSomething() {
        state.doWork();
    }

19.模板模式
20.中介者模式
21.备忘录模式
22.访问者模式
23.策略模式

定义一组算法,将每个算法封装起来,并且使他们之间可以进行相互转换,策
略模式是让算法独立于使用他客户而变化的,也称之为政策模式

四.其他

24.过滤器模式
25.空对象模式

你可能感兴趣的:(后端,设计模式,学习,锁)