Java“老兵”浅谈源码的七大设计模式

https://www.shengchulai.com/blog-9sFmIzthaZ.htm

一个专业的程序员,总是把代码的清晰性,兼容性,可移植性放在很重要的位置。他们总是通过定义大量的宏,来增强代码的清晰度和可读性,而又不增加编译后的代码长度和代码的运行效率。

他们总是在编码的同时,就考虑到了以后的代码维护和升级。甚至,只要分析百分之一的代码后,你就会深刻地体会到,什么样的代码才是一个专业的程序员写的,什么样的代码是一个业余爱好者写的。

而这一点是任何没有真正分析过标准代码的人都无法体会到的。

本文会介绍一些经典的设计模式思想:

常用设计模式

Proxy代理模式

代理模式:为其他对象提供一种代理以便控制对这个对象的访问。

可以详细控制访问某个类(对象)的方法,在调用这个方法前作的前置处理(统一的流程代码放到代理中处理)。调用这个方法后做后置处理。

代理模式分类:

1.静态代理(静态定义代理类,我们自己静态定义的代理类。比如我们自己定义一个明星的经纪人类)

2.动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成)比较重要!!

  • JDK自带的动态代理

  • javaassist字节码操作库实现

  • CGLIB

  • ASM(底层使用指令,可维护性较差)

结构组成

代理模式主要涉及到三个角色:抽象角色、代理角色、真实角色(被代理的角色)。

抽象角色:声明真实对象和代理对象的共同接口。即真实对象和代理对象共同要实现的行为动作(好比房东和中介都要能够实现租房的行为,都能把房子租给你)。

代理角色:代理角色内部含有对真实角色的引用,从而可以去操作真实对象,同时代理对象提供与真实对象的接口,以便在任何时候都能代替真实对象。同时,代理对象在执行真实对象的操作时,也能附加它自己的操作,相当于对真实对象的封装

真实角色:代理角色所代理的对象,亦即我们最终要引用的对象。

Factory工厂模式

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

工厂模式可以分为三类:

  • 简单工厂模式(Simple Factory)

  • 工厂方法模式(Factory Method)

  • 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

区别:

工厂方法模式:

  • 一个抽象产品类,可以派生出多个具体产品类。

  • 一个抽象工厂类,可以派生出多个具体工厂类。

每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:

  • 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。

  • 一个抽象工厂类,可以派生出多个具体工厂类。

  • 每个具体工厂类可以创建多个具体产品类的实例。

区别:

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。

工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

Singleton 单例模式

  • 单例模式只能有一个实例。

  • 单例类必须创建自己的唯一实例。

  • 单例类必须向其他对象提供这一实例。

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式结构图

单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,通过上图我们知道它包含的角色只有一个,就是Singleton,它拥有一个私有构造函数,这确保用户无法通过new直接实例它。

除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()方法负责检验并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建。

使用Singleton模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式。反之,如果一个类可以有几个实例共存,就不要使用单例模式。

不要使用单例模式存取全局变量。这违背了单例模式的用意,最好放到对应类的静态成员中。

不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放,带来问题。

Delegate 委派模式

委派模式(Delegate)是面向对象设计模式中常用的一种模式。这种模式的原理为类B和类A是两个互相没有任何关系的类,B具有和A一模一样的方法和属性;并且调用B中的方法,属性就是调用A中同名的方法和属性。

B好像就是一个受A授权委托的中介。第三方的代码不需要知道A的存在,也不需要和A发生直接的联系,通过B就可以直接使用A的功能,这样既能够使用到A的各种公能,又能够很好的将A保护起来了。

委派模式的优点:

  • 单一一个类无法表现复杂的设计

  • 设计拆分

  • 方便重用

  • 相对独立

  • 功能定义清晰,行为界面分离

  • 松散耦合,容易扩展

strategy 策略模式

定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it. )

策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。

策略模式结构

当存在以下情况时使用Strategy模式

  • 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。

  • 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。

  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。

  • 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

Prototype 原型模式

原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对象的副本,这种创建对象的方式,相比我们之前说的几类创建型模式还是有区别的,之前的讲述的工厂模式与抽象工厂都是通过工厂封装具体的new操作的过程,返回一个新的对象,有的时候我们通过这样的创建工厂创建对象不值得,特别是以下的几个场景的时候,可能使用原型模式更简单也效率更高。

  • 当一个系统应该独立于它的产品创建、构成和表示时,要使用 Prototype模式

  • 当要实例化的类是在运行时刻指定时,例如,通过动态装载;

  • 为了避免创建一个与产品类层次平行的工厂类层次时

  • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。(也就是当我们在处理一些对象比较简单,并且对象之间的区别很小,可能只是很固定的几个属性不同的时候,可能我们使用原型模式更合适)。

原型模式结构

Template 模板模式

  • 模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。

  • 板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。

  • 在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

模板方法应用于下列情况:

  • 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。全文中源码分析可以在群619881427免费学习。感兴趣的可以加入进来。

  • 控制子类扩展。模板方法只在特定点调用“ hook”操作 ,这样就只允许在这些点进行扩展。

模板模式结构

(0)

相关推荐

  • PHP设计模式之享元模式

    PHP设计模式之享元模式 享元模式,"享元"这两个字在中文里其实并没有什么特殊的意思,所以我们要把它拆分来看."享"就是共享,"元"就是元素 ...

  • Python设计模式是什么?Python入门

    设计模式想必大家都比较熟悉,它是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式可以让代码更容易被他人理解.保证代码的可靠性,而且使用设计模式还需要遵循一定的原则.那么P ...

  • 【重温设计模式】之002简单工厂模式

    [重温设计模式系列源码] 简单工厂模式 基本原理 含义 简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法). 在现实生活中,工厂是生产产品的, 同样的,在设计模式中,一个负责生产" ...

  • 前端5大常见设计模式、代码一看你就懂!

    原创IT实战联盟2019-04-02 08:15:00 前言 今天主要介绍一下我们平常会经常用到的设计模式,设计模式总的来说有23种,而设计模式在前端中又该怎么运用呢,接下来主要对比较前端中常见的设计 ...

  • 创建型设计模式总结

    Intro 前面几篇文章已经把创建型设计模式都介绍了,来做一个简单的总结. 创建型设计模式,就是用来创建对象的设计模式,根据要创建的对象的复杂度以及是否允许多实例以及是否需要容易扩展等多方面考虑去选择 ...

  • 面试连环炮系列(二十二):常用的设计模式有哪些

    常用的设计模式有哪些,作用是什么 设计模式一共23种,常用的设计模式有: 工厂模式: 构建多个对象的工厂. 单例模式:单例类负责创建自己的对象,同时确保只有单个对象被创建 代理模式:代理其他类,增强原 ...

  • PHP设计模式之代理模式

    PHP设计模式之代理模式 代理人这个职业在中国有另外一个称呼,房产经济人.保险经济人,其实这个职业在国外都是叫做房产代理或者保险代理.顾名思义,就是由他们来帮我们处理这些对我们大部分人来说都比较生疏的 ...

  • 设计模式(1) 工厂方法模式

    创建型模式 简单工厂模式 工厂方法模式 IOC与工厂方法模式的结合 泛型工厂 委托工厂 创建型模式 创建型模式可以隔离客户程序对需要实例化类型的依赖关系,这类模式一般通过将实例化具体对象的职责委托给第 ...

  • 设计模式(一)——Java单例模式(代码+源码分析)

    设计模式(一)——Java单例模式(代码+源码分析)

  • java开发之ThreadPoolExecutor源码分析

    线程池的状态 只有了解线程池的几个状态,才能读懂它的核心源码.所以先说说这几个状态 running:为线程池初始化时的默认状态,此状态会接收任务进行处理 shutdown: 该状态下的线程池不接收任何 ...

  • 浅谈微服务架构的设计模式

    微服务架构模式(MicroserviceArchitectPattern).近两年在服务的疯狂增长与云计算技术的进步,让微服务架构受到重点关注 微型服务体系结构是一种体系结构模式,它主张把单个应用分成 ...

  • 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...

  • Java高并发21-AQS在共享,独占场景下的源码介绍

    一.AQS--锁的底层支持 1.AQS是什么 AQS是AbstractQueuedSychronizer的简称,即抽象同步队列的简称,这是实现同步器的重要组件,是一个抽象类,虽然在实际工作中很烧用到它 ...

  • 李源:浅谈癌症的中医辨治思路

    中医药治疗癌症有很独特的理论体系,和丰富的临床治疗方法,传承数千年,但是,在目前的社会情况下,很难被理解.需要我们中医人深刻学习,积极的向群众们宣传中医药的特色和独特之处. <内经·经脉别论&g ...

  • 浅谈颈源性头痛治疗方法——王威勋

    颈 源 性 头 痛 颈源性头痛是由于高位颈椎病局部软组织损伤 小关节紊乱 局部筋膜挛缩增厚等诸多因素,造成了颈部神经,血管的压迫.从而引起后枕部,偏头痛一侧或者两侧等头部部位放射性疼痛.称之为颈源性头 ...

  • Java高并发16-LongAdder类源码解析(下)

    一.复习 上次连载简单的介绍了其他函数的作用以及功能 二.完整的LongAdder类源码 package com.ruigege.AtomicOperationClass4;import java.u ...

  • Java教程——LinkedHashMap源码分析

    大多企业级项目开发都会选择Java,这使得我们Java工程师们都是"全能型"人才,这使得项目经验成为了Java人面试的重头戏之一. 简介 LinkedHashMap内部维护了一个双 ...