java设计模式

目录

一、设计模式概述

1、软件设计模式的产⽣背景。

2、软件设计模式的概念

3、学习设计模式的必要性

4. 设计模式分类‒记住

创建型模式:

结构型模式:

⾏为型模式:

⼆、软件设计原则

1. 开闭原则

2. ⾥⽒代换原则

3. 依赖倒转原则

4. 接口隔离原则

5. 迪⽶特法则

6. 合成复用原则

三、单例设计模式

1. 单例模式的结构

2. 单例模式的实现

3. 单例模式优点和缺点

4. 懒汉模式和饿汉模式区别 面试题

四、工厂模式

1. 简单工厂模式

2. 工厂方法模式

1)工厂方法优缺点

2)适用场景

五、适配器模式(Adapter)  

1. 适配器模式的定义

2. 适配器模式优点

1)优点

3. 类适配器:

1)优点

2)缺点

4. 对象适配器:

1)优点:

2)缺点:

5. 接口适配器:

六、代理模式(Proxy Pattern)重点

1. 代理模式的定义

2. 为什么使⽤代理模式

3. 代理模式优缺点

4. 代理模式的结构与实现

1. 静态代理

5. 动态代理

1. 动态代理

 2. 动态代理(CGLIB动态代理)

七、观察者模式(Observer)

1. 模式的定义与特点

 2. 观察者模式优缺点

3. 观察者模式的实现

4. 观察者模式的应⽤场景

⼋、装饰模式(Decorator)

1. 装饰模式的定义

2. 装饰模式优缺点 装饰(Decorator)

3. 装饰模式的实现

4. 装饰模式的应⽤场景

九、模板⽅法模式(Template Method)

1. 模板⽅法模式的定义与特点

2. 模板⽅法模式优缺点

3. 模板⽅法模式的实现

4. 模板⽅法模式的应⽤场景


 

一、设计模式概述

1、软件设计模式的产⽣背景。

       在此不会赘述,感兴趣的可自行搜索

2、软件设计模式的概念

            软件设计模式(Software Design Pattern),⼜称设计模式,是⼀套被 反复使⽤ 、多数⼈知晓的 、代码设计经验的总 结 。它描述了在软件设计过程中的⼀些不断重复发⽣的问题,以及该问题的解决⽅案。也就是说,它是解决特定问题 的⼀系列套路,是 前辈们的代码设计经验的总结 ,具有⼀定的普遍性,可以反复使⽤。

3、学习设计模式的必要性

       设计模式的本质是 ⾯向对象设计原则 的实际运⽤,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

       正确使⽤设计模式具有以下优点:

♠ 可以提⾼程序员的思维能⼒、编程能⼒和设计能⼒。

♠ 使程序设计更加标准化、代码编制更加⼯程化,使软件开发效率⼤⼤提⾼,从而缩短软件的开发周期。

♠ 使设计的代码可重⽤性⾼、可读性强、可靠性⾼、灵活性好、可维护性强。

4. 设计模式分类‒记住

创建型模式:

      ⽤于描述“怎样创建对象”,它的主要特点是“ 将对象的创建与使⽤分离 ”。GoF(四⼈组)书中提供了 单例、原 型、⼯⼚⽅法、抽象⼯⼚、建造者 等 5 种创建型模式。

结构型模式:

       ⽤于描述如何将类或对象按某种布局组成更⼤的结构,GoF(四⼈组)书中提供了 代理、适配器、桥接、装饰、外 观、享元、组合 等 7 种结构型模式。

行为型模式:

       ⽤于描述类或对象之间怎样相互协作共同完成单个对象⽆法单独完成的任务,以及怎样分配职责。GoF(四⼈ 组)书中提供了 模板⽅法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器 等 11 种 ⾏为型模式。

⼆、软件设计原则

       在软件开发中,为了提⾼软件系统的可维护性和可复⽤性,增加软件的可扩展性和灵活性,程序员要 尽量 根据6条原 则来开发程序,从而提⾼软件开发效率、节约软件开发成本和维护成本。

1. 开闭原则

       就是说对扩展开放,对修改关闭。在程序需要进⾏拓展的时候,不能去修改原有的代码 ,而是要扩展原有代码,实现 ⼀个热插拔的效果。对扩展开放,意味着有新的需求或变化时,可以对现有代码进⾏扩展,以适应新的情况。对修改 封闭,意味着类⼀旦设计完成,就可以独⽴完成其⼯作,而不要对类进⾏任何修改。

        这样的设计,能够⾯对需求改变却可以保持相对稳定,从而使系统在第⼀个版本以后不断推出新的版本;⾯对需 求,对程序的改动是通过增加新的代码进⾏的,而不是更改现有的代码 ;所以⼀句话概括就是:为了使程序的扩展性 好,易于维护和升级。想要达到这样的效果,我们需要 使⽤接口和抽象类 等。

2. ⾥⽒代换原则

       ⾥⽒代换原则是Barbara Liskov提出的,这是⼀种⾯向对象的设计原则,即如果我们调⽤⼀个⽗类的⽅法可以成 功,那么替换成⼦类调⽤也应该完全可以运⾏。【例】正⽅形不是⻓⽅形。

3. 依赖倒转原则

       ⾼层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要 求对抽象进⾏编程,不要对实现进⾏编程,这样就降低了客⼾与实现模块间的耦合。

4. 接口隔离原则

       客⼾端不应该被迫依赖于它不使⽤的⽅法 ;⼀个类对另⼀个类的依赖应该建⽴在最小的接口上。

5. 迪⽶特法则

       迪⽶特法则⼜叫最少知识原则。

       只和你的直接朋友交谈,不跟“陌⽣⼈”说话(Talk only to your immediate friends and not to strangers)。 其含义是:如果两个软件实体⽆须直接通信,那么就不应当发⽣直接的相互调⽤ ,可以通过第三⽅转发该调⽤。其⽬ 的是降低类之间的耦合度,提⾼模块的相对独⽴性。

       迪⽶特法则中的“朋友”是指:当前对象本⾝、当前对象的成员对象、当前对象所创建的对象、当前对象的⽅法参数等, 这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的⽅法。

6. 合成复用原则

       尽量使⽤合成/聚合,避免继承 ,在新类中应该尽量使⽤关联关系采⽤现有的对象,使之成为新对象的⼀部分,达到 现有功能复⽤的⽬的。通过合成聚合的原则可以降低类于类之间的依赖关系,被依赖的类的修改对其他类的影响相 对小⼀些。合成/聚合原则是动态的,可以⾃由选择使⽤现有类的那些⽅法,而继承是静态的失去了灵活性,如果⽗类 改变有可能会影响⼦类的修改,同时破坏了⽗类的封装性,⽗类将会暴露不相关的⽅法给⼦类。

三、单例设计模式

       单例模式(Singleton Pattern)是 Java 中最简单的设计模式之⼀。这种类型的设计模式属于 创建型模式 ,它提供了 ⼀种 创建对象的最佳⽅式 。

       这种模式涉及到⼀个单⼀的类,该类负责创建⾃⼰的对象 ,同时 确保只有单个对象被创建 。这个类提供了⼀种访问 其唯⼀的对象的⽅式,可以直接访问,不需要实例化该类的对象。

1. 单例模式的结构

♠ 单例类。只能创建⼀个实例的类

♠ 访问类。使⽤单例类

2. 单例模式的实现

   单例设计模式分类两种:

   饿汉式:类加载就会导致该单实例对象被创建

   懒汉式:类加载不会导致该单实例对象被创建,而是⾸次使⽤该对象时才会创

1)饿汉式-⽅式1(静态变量⽅式)

/**
 * 饿汉式
 * 静态变量创建类的对象
 */
public class Singleton {
    //私有构造⽅法
    private Singleton() {
    }

    //在成员位置创建该类的对象
    private static Singleton instance = new Singleton();

    //对外提供静态⽅法获取该对象
    public static Singleton getInstance() {
        return instance;
    }
}

说明: 该⽅式在成员位置声明Singleton类型的静态变量,并创建Singleton类的对象instance。instance对象是随 着类的加载而创建的。如果该对象⾜够⼤的话,而⼀直没有使⽤就会造成内存的浪费。

2) 饿汉式-⽅式2(静态代码块⽅式)

/**
 * 饿汉式
 * 在静态代码块中创建该类对象
 */
public class Singleton {
    //私有构造⽅法
    private Singleton() {
    }

    //在成员位置创建该类的对象
    private static Singleton instance;

    static {
        instance = new Singleton();
    }

    //对外提供静态⽅法获取该对象
    public static Singleton getInstance() {
        return instance;
    }
}

说明: 该⽅式在成员位置声明Singleton类型的静态变量,而对象的创建是在静态代码块中,也是对着类的加载而 创建。所以和饿汉式的⽅式1基本上⼀样,当然该⽅式也存在内存浪费问题。

3)懒汉式-⽅式1(线程不安全)

/**
 * 懒汉式
 * 线程不安全
 */
public class Singleton {
    //私有构造⽅法
    private Singleton() {
    }

    //在成员位置创建该类的对象
    private static Singleton instance;

    //对外提供静态⽅法获取该对象
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

说明: 从上⾯代码我们可以看出该⽅式在成员位置声明Singleton类型的静态变量,并没有进⾏对象的赋值操作, 那么什么时候赋值的呢?当调⽤getInstance()⽅法获取Singleton类的对象的时候才创建Singleton类的对 象,这样就实现了懒加载的效果。但是,如果是多线程环境,会出现线程安全问题。

4)懒汉式-⽅式2(线程安全)

/**
 * 懒汉式
 * 线程安全
 */
public class Singleton {
    //私有构造⽅法
    private Singleton() {
    }

    //在成员位置创建该类的对象
    private static Singleton instance;

    //对外提供静态⽅法获取该对象
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

     说明: 该⽅式也实现了懒加载效果,同时⼜解决了线程安全问题。但是在getInstance()⽅法上添加了 synchronized关键字,导致该⽅法的执⾏效果特别低。从上⾯代码我们可以看出,其实就是在初始化 instance的时候才会出现线程安全问题,⼀旦初始化完成就不存在了。

5)懒汉式-⽅式3(双重检查锁)

     对于 getInstance() ⽅法来说,绝⼤部分的操作都是读操作,读操作是 线程安全的,所以我们没必要让每个线程必须持有锁才能调⽤该⽅法,我们需要调整加锁的时机。由此也产⽣ 了⼀种新的实现模式:双重检查锁模式 

/**
 * 双重检查⽅式
 */
public class Singleton {
    //私有构造⽅法
    private Singleton() {
    }

    private static Singleton instance;

    //对外提供静态⽅法获取该对象
    public static Singleton ge
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值