设计模式

2020-04-21 09:55 更新

笔者能力有限,总结有误的地方,请读者协作更正。需要了解更多,请阅读相关书籍。

能说出来解释清楚,最好能写出伪代码

23种设计模式分3类:创建型5种,结构型分7种,行为型11种

设计模式的6大原则:

  • 总原则:开闭原则,对扩展开放,对修改关闭

  • 单一职责,里氏替换,依赖倒转,接口隔离,最少知道,合成复用

1.单例模式8种

基本实现思路:保证JVM中只能创建一个该对象的实例。对频繁创建和销毁对象时使用;工具类使用;

实现步骤:

私有静态变量;私有构造方法;

静态方法,调用该方法,持有对象引用,返回该引用;引用为空,创建实例。

1)饿汉模式(静态常量)可用

    public class Singleton {
        private final static Singleton INSTANCE = new Singleton();
        private Singleton(){}
        public static Singleton getInstance(){
            return INSTANCE;
        }

优点:避免线程同步

缺点:类加载之后,对象就创建出来在哪里放着,不管用不用,没有懒加载效果,内存浪费。

2)饿汉式(静态代码块)可用

把对象的创建放在静态代码块中,优缺点和上面一样。

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

3)懒汉模式(线程不安全)不可用

把对象的创建放在方法中,需要用的时候在创建;能实现懒加载,存在线程不安全。

    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }

4)懒汉模式(线程安全,同步方法)可用,不推荐

加锁,懒加载,线程安全,但是效率低

   public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static synchronized Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }

5)懒汉模式(线程安全,同步代码块)不可用

    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    singleton = new Singleton();
                }
            }

线程安全,但是会产生多个实例;

6)双重检查(推荐用)

    public class Singleton {
        private static volatile Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    } } }
            return singleton;
        }
    }

进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。

优点:线程安全;延迟加载;效率较高。

7)静态内部类(推荐用)

    public class Singleton 
        private Singleton() {}
        private static class SingletonInstance {
            private static final Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance() {
            return SingletonInstance.INSTANCE;
        }
    }

类的静态属性只会在第一次加载类的时候进行初始化,JVM能够帮我们保证线程安全,在进行初始化的时候,别的线程无法进入。

优点:线程安全,延迟加载,效率高。

8)枚举(推荐用)

     public enum Singleton{
    Instance;
    private void  EvenMethod(){
        }
    }

JDK1.5中添加的枚举来实现单例模式。

不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

2.工厂方法

简单工厂方法

不同的类实现同一个接口,创建一个简单工厂来为这些类创建实例;

例如:发送短信,发送邮件,将发送抽取出来作为接口,建一个简单工厂来实现发送的实例,当然还有其它的写法。

工厂方法

简单工厂存在的问题,类的创建依赖于工厂类,想要修改程序就需要修改工厂,违背了闭包原则

工厂方法,扩展功能,直接增加工厂类。

3.抽象工厂

工厂方法中,一个工厂只能生产一种产品。重点在于产品,如果一个方法需要有大量的实现细节,很多代码需要围绕这个产品展开,推荐使用工厂方法。

抽象工厂中,一个工厂可以创建多种产品类,因为抽象工厂中有一堆的工厂方法,一个工厂方法返回对应的数据类型。重点在于数量,如果要求不同的产品线,保持接口一致,推荐使用抽象工厂方法。

4.代理模式

1)就是用另外一个类代替目标类的操作,同时能够提供额外的操作;

比如:房地产中介,客户,和房东就是一个代理模式;

  • -地产中介 卖房,带客户看房,收取中介费
  • -房东 卖房
  • -客户 买房

2)分类:静态代理,和动态代理 spring中AOP应用了两种代理模式,ciglib动态代理,jdk动态代理 详解Spring的AOP?

1.1 静态代理

特点:实现和被代理这相同的接口,能够执行代理者相同的方法,添加额外的功能操作

缺点:一个目标对象就需要一个代理类,一个明星就需要一个经济人

复用性不高,不通用

1.2 动态代理

分为-->JDK代理 CGlib代理 -jdk动态代理

特点:实现相同的接口,执行目标对象的方法,能做额外的操作,

优点:一个代理类,能为很多目标类服务,解耦,高复用

缺点:只能处理事务,不具备通用性(日志,安全,权限等)

-CGlib动态代理

特点:执行目标对象的方法,能做额外的操作

优点:一个代理类,能为很多目标类服务,解耦,高复用,而且不需要实现接口,

1.3 Spring 生成代理对象

Spring整合了JDK代理和Cglib代理,

Jdk代理实现的是invocationHandler接口;Cglib实现的是MethodInterceptor接口

实现着两个接口,spring代理模式内部能够的自由切换。让代理模式复用性更高,使用更方便。

5.装饰器模式

装饰模式和代理模式很像,都是为了扩展功能,

装饰模式要求给一个对象动态的增加一些新的功能,要求装饰对象和被装饰对象实现共同的接口,装饰对象持有被装饰对象的引用。

6.策略模式

就是定义一系列的算法族,将每一个算法封装成独立的类,然后所有的类实现统一的接口,这些算法之间可以相互替换,每一个算法的变化不会影响到用户的使用。

需要设计一个接口,为一序列类提供统一的方法,多个实现类实现该接口,设计一个抽象类,提供辅助函数。

7.观察者模式

是一种一队多的关系,就像公众号和粉丝的关系;

当一个对象发生变化时候,其它依赖于该对象的类都会收到通知;

8.责任链模式

就是,有多个对象,每一个对象持有下一个对象的引用,形成一条链,请求在这条链上传递,直到被某一对象被处理,但是请求并不知道是哪一个对象处理了这个请求。

比喻:我去拜访元首,第一道安检,让我初始通行证;第二道安全,搜身;第三道安检,是否预约;每一次安检负责每一次安检的工作,所有的安检形成一条链,我作为一个对象在这条链上传递,安检不通过,抛异常。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号