设计模式概述(复习)--持续更新

1 设计模式七大原则

1.1 单一职责原则

1.1.1 含义

  • 降低类的复杂度,一个类只负责一项职责
  • 降低代码更改的影响
  • 提供可读性、可维护性
  • 通常都需要遵守单一职责原则,逻辑足够简单才可以违反;只有类中方法比较少,可以在方法级别遵守单一职责原则

1.2 开闭原则

  • 对提供方开放扩展,对使用方关闭修改
  • 尽量通过扩展而不是修改实现功能
  • 使用设计模式的目的就是遵守开闭原则

1.3 迪米特原则

  • 最小知道法则
  • 方法入参、方法返回值和成员变量成为直接朋友,而局部变量称为间接朋友
  • 被依赖的类不管逻辑多复杂,都尽量封装到类的内部
  • 迪米特法则的核心是:降低类与类之间的耦合,并不是完全没有依赖

1.4 接口隔离原则

  • 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上.
  • 示例:如果C依赖1~3方法,而A依赖1、4、5方法,那么依赖关系应该从图1改为图2
    AC都依赖接口1
    在这里插入图片描述

1.5 依赖转置原则

1.5.2 特征

  • 高层模块不应该依赖底层模块
  • 抽象不应该依赖细节
  • 中心思想是:面向接口编程
  • 理念:抽象的东西相对于细节更稳定
  • 接口和抽象类主要是用来搭建规范,细节有具体的实现类来实现

1.5.2 依赖传递的方式

  • 接口方式
  • 构造器方式
  • setter方式

1.5.3 注意事项和细节

  • 低层代码尽量要有抽象类和接口
  • 变量的声明类型尽量是抽象类或接口
  • 继承时遵循里氏替换原则

1.6 里氏替换原则

  • 所有的父类都可以透明的使用子类的对象
  • 子类尽量不要修改父类的非抽象方法,尽量不要重写父类的方法
  • 迫不得已使用聚合、组合和依赖来解决问题,或者抽象个更加基础的类

1.7 合成复用原则

  • 尽量使用合成/聚合的方式,而不是使用继承
  • 依赖、组合和聚合的区别
    • 依赖: 方法入参传入接口等,关联、继承与实现是依赖关系的特例
    • 组合:成员变量,通过set方法传入,是关联关系的特例
    • 聚合:成员变量,直接new对象,是关联关系的特例

2 UML中类图的简单介绍

2.1 依赖关系

只要用到了,就拥有依赖关系

2.2 泛化关系(继承关系)

泛化关系实际就是继承关系,是依赖关系的特殊情况
比较常见的形式:子类继承了父类,接口继承另一个接口

2.3 实现关系

接口实现等,是依赖关系的特殊情况
比较常见的形式:实现类实现某个接口

2.4 关联关系

类与类的关系,具有导航性和多重性,是依赖关系的特殊情况

2.5 聚合关系

整体与部分的关系,但部分可以与整体分离,是关联关系的特殊情况
比较常见的形式:成员变量中,没有进行初始化,而是使用set方法进行初始化

2.6 组合关系

整体与部分的关系,部分与整体共生死,是关联关系的特殊情况
比较常见的形式:成员变量中,使用new进行了初始化

2.7 UML示意图

在这里插入图片描述

3 设计模式分类

模式不是代码,而是通用的解决方案

3.1 创建型设计模式(5种)

  • 单例模式
  • 工厂模式
  • 抽象工厂
  • 原型模式
  • 建造者模式

3.2 结构型设计模式(7种)

主要是站在类与类关系的角度进行设计

  • 适配器模式
  • 桥接模式
  • 代理模式
  • 装饰模式
  • 组合模式
  • 外观模式
  • 享元模式

3.3 行为型设计模式(11种)

主要是站在方法调用的角度上面进行设计

  • 策略模式
  • 观察者模式
  • 中介者模式
  • 责任链模式
  • 状态模式
  • 命令模式
  • 模板方法模式
  • 备忘录模式
  • 解释器模式(拦截器模式)
  • 访问者模式
  • 迭代器模式

4 创建型设计模式

4.1 单例模式

目的:只允许存在一个实例
实现:

  • 饿汉式:静态常量
  • 饿汉式:静态代码块
  • 懒汉式:线程不安全
  • 懒汉式:线程安全,同步方法
  • 懒汉式:线程安全,同步代码块
  • 双重检查
  • 静态内部类
  • 枚举类

4.1.1 饿汉式:静态常量

package singleton.type1;

/**
 * 饿汉式:静态常量
 * 可能会导致内存浪费
 *
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton1 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton1=Singleton.getInstance();
        System.out.println(singleton==singleton1);
        System.out.println(singleton.hashCode());
        System.out.println(singleton1.hashCode());
    }


}

class Singleton{

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }

    //2.本类内部创建一个实例
    private  static final Singleton INSTANCE=new Singleton();

    //3.对外暴露一个公共的静态方法获取实例
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

4.1.2 饿汉式:静态代码块

package singleton.type2;

/**
 * 饿汉式:静态代码块
 * 可能会导致内存浪费
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton2 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{

    private  static  Singleton instance;

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }


    //2.本类内部创建一个实例
    static {
        instance=new Singleton();
    }

    //3.对外暴露一个公共的静态方法获取实例
    public static Singleton getInstance(){
        return instance;
    }
}

4.1.3 懒汉式:线程不安全

package singleton.type3;

/**
 * 懒汉式:线程不安全 <br>
 * 线程不安全,可能会有多个线程进入if(instance==null)中,从而创建多个实例 <br>
 * 结论: 不可以使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton3 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{

    private  static  Singleton instance;

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }
    

    //2.本类内部创建一个实例
    //3.对外暴露一个公共的静态方法获取实例
    public static Singleton getInstance(){
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

4.1.4 懒汉式:同步方法

package singleton.type4;

/**
 * 懒汉式:线程安全 同步方法 <br>
 * 线程安全,但是效率太低。多个线程存在时,其他线程都必须等待,而对于getInstance这种需要频繁使用的方法显然不合适 <br>
 * 结论: 效率低,不推荐使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton4 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{

    private static Singleton instance;

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }
    

    //2.本类内部创建一个实例
    //3.对外暴露一个公共的静态方法获取实例
    public static synchronized Singleton getInstance(){
        if(instance==null){
            instance= new Singleton();
        }
        return instance;
    }
}

4.1.5 懒汉式:同步代码块

package singleton.type5;

/**
 * 懒汉式:线程安全 同步代码块 <br>
 * 线程安全,但并非单例。意图解决第四种方案效率低的问题,但实际并不能达到效果 <br>
 * 结论: 不可以使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton5 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{

    private static Singleton instance;

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }
    

    //2.本类内部创建一个实例
    //3.对外暴露一个公共的静态方法获取实例
    public static  Singleton getInstance(){
        if(instance==null){
            synchronized (Singleton.class){
                instance= new Singleton();
            }
        }
        return instance;
    }
}

4.1.6 双重检查

package singleton.type6;

/**
 * 双重检验 <br>
 * 线程安全,单例,效率比较高 <br>
 * 结论: 推荐使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton6 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{

    private static  volatile Singleton instance;

    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }
    

    //2.本类内部创建一个实例
    //3.对外暴露一个公共的静态方法获取实例
    public static  Singleton getInstance(){
        if(instance==null){
            synchronized (Singleton.class){
                if(instance==null){
                    instance= new Singleton();
                }
            }
        }
        return instance;
    }
}

4.1.7 静态内部类

package singleton.type7;

/**
 * 静态内部类 <br>
 * 利用静态内部类线程安全,且只会初始化一次的特性实现单例<br>
 * 结论: 推荐使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton7 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.getInstance();
        Singleton singleton2=Singleton.getInstance();
        System.out.println(singleton==singleton2);
    }


}

class Singleton{


    //1.构造器私有化,使得外部不能通过new创建实例
    private Singleton(){
    }
    

    //2.本类内部创建一个实例
    private static class SingletonInner{
        private static final Singleton INSTANCE=new Singleton();
    }

    //3.对外暴露一个公共的静态方法获取实例
    public static  Singleton getInstance(){
        return SingletonInner.INSTANCE;
    }
}

4.1.8 枚举单例

package singleton.type8;

/**
 * 枚举单例 <br>
 * Effective Java推荐的方式<br>
 * 结论: 推荐使用
 * @author yi qiang
 * @date 2021/5/2 22:07
 */
public class Singleton8 {

    public static void main(String[] args) {
        Singleton singleton=Singleton.INSTANCE;
        Singleton singleton2=Singleton.INSTANCE;
        System.out.println(singleton==singleton2);
    }


}

enum  Singleton{

    /**
     * 单例模式
     */
    INSTANCE;

    private Singleton(){
    }
    

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值