Java设计模式

本文围绕设计模式展开,介绍了其定义、分类、基本要素和优点。阐述了面向对象设计的七大原则,还详细讲解了简单工厂、工厂方法、原型、单例等多种设计模式,包括定义、角色、优缺点及适用环境,为软件开发提供了实用的设计思路。

 

目录 

设计模式

面向对象设计原则

简单工厂模式/静态工厂方法模式

工厂方法模式/虚拟构造器模式/多态工厂模式

原型模式

单例模式

桥接模式/柄体模式/接口模式

适配器模式/包装器模式

装饰模式

代理模式

命令模式

观察者模式


设计模式

1、软件模式定义:是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。P-3

2、设计模式是一套被反复使用的多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且提高代码的可靠性。P-5

3、设计模式的分类;P-7

①根据目的可分为创建型、结构性和行为型

创建型模式主要用于创建对象

结构型模式主要用于处理类或对象的组合

行为型模式主要用于描述类或对象如何交互和怎样分配职责

        类行为型模式:使用继承关系在几个类之间分配行为,主要通过多态等方式来分配父类与子类的职责

        对象行为型模式:使用对象的关联关系来分配行为,主要通过对象关联等方式来分配两个或多个类的职责

创建型

结构型

行为型

简单工厂模式---根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

桥接模式--将抽象部分和实现部分解耦,使得两者都能够独立变化

命令模式--将一个请求封装为一个对象,从而让你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。

工厂方法模式--一个用于创建对象的接口,但是让子类决定将哪一个类实例化。让一个类的实例化延迟到其子类。

适配器模式--解决了供需双方不兼容的矛盾将一个类的接口转换成客户希望的另一个接口。

观察者模式--定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。

原型模式--指定要创建对象的类型,并且通过复制这个原型来创建新的对象。

装饰模式--动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案

单例模式--确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例

代理模式--给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

②根据范围可分为类模式和对象模式

类模式处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,是一种静态关系;

对象模式处理对象间的关系,这些关系在运行时变化,更具动态

4、GoF共描述了23种设计模式P-8

5、设计模式的基本要素:模式名称,问题,解决方案,效果

6、设计模式的优点:P-9

①融合了众多专家的经验,设计方案更加通俗易懂

②提供了一套通用的设计词汇和一种通用的语言

③设计方案更加灵活,且易于修改

④提高软件系统的开发效率和软件质量

⑤有助于初学者更深入地理解面向对象思想

面向对象设计原则

--简答P-13

1、单一职责原则:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中

2、开闭原则:软件实体应当对扩展开放,对修改关闭

3、里氏代换原则:所用引用基类的地方必须能透明地使用其子类的对象

4、依赖倒装原则:高层模块都不应该依赖底层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象

5、接口隔离原则:客户端不应该依赖那些它不需要的接口

6、合成复用原则:优先使用对象组合,而不是通过继承来达到复用目的

7、迪米特法则:每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位

名称缩写形式含义
Public+        可从所有其他类型访问
Private-只能由此类型的内部定义访问
Package~只能在包含次类型的包以及显示导入次类型的所有包中访问
Protected#只能由此类型以及从其继承的类型访问

简单工厂模式/静态工厂方法模式

1、定义:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

2、3个角色:Factory(工厂角色);Produce(抽象产品角色);ConcreteProduce(具体产品角色)

3、模式优点:

①实现了对象使用和创建的分离

②客户端无需知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数

③一定程度上提高了系统的灵活性

4、简单工厂模式缺点:

①职责过重

②增加了系统的复杂度和理解难度

③扩展困难,不利于系统的扩展和维护

④无法形成基于继承的等级结构

5、使用环境:

①工厂类创建的对象比较少

②客户端只知道传入工厂类的参数,对于如何创建对象并不关心

工厂方法模式/虚拟构造器模式/多态工厂模式

1、定义:一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

2、4个角色:

Produce(抽象产品);ConcreteProduce(具体产品角色)

Factory(工厂角色);ConcreteFactory(具体工厂)

3、工厂模式优点:

①用户只需要关心所需产品对应的工厂,无需关心创建细节

②让工厂自主确定创建何种产品对象

③扩展性变得很好,完全符合开闭原则

4、工厂方法缺点:

①增加了系统复杂度,带来了额外的开销

②增加了系统的抽象性和理解难度

5、适用环境:

①客户端不知道它所需要的对象的类

②抽象工厂类通过其子类来指定创建哪个对象

原型模式

1、定义:使用原型实例指定带创建对象的类型,并且通过复制这个原型来创建新的对象。

2、3个角色:Prototype(抽象原型类);ConcretePrototype(具体原型类);Client(用户角色)

3、浅克隆和深克隆:

①浅克隆:当原型角色被复制只复制它本身和其中包含的值类型的成员变量,引用类型的成员变量并没有复制

②深克隆:将原型对象的所有引用对象都复制

4、原型模式的优点:

①简化创建过程

②扩展性好

③提供了简化的创建结构

④可以用深克隆的方式保存对象的状态

5、原型模式的缺点:

①当对已有的类进行改造时需要修改源代码,违背了开闭原则

②在实现深克隆时需要编写较为复制的代码

6、适用环境:

①创建新对象成本较大

②系统要保存对象的状态,而对象的状态变化很小

③需要避免使用分层次的工厂类来创建分层次的对象

注意:原型模式的角色分析不难明白:原型类就是产品类,只不过是与工厂合二为一的产品类

单例模式

1、定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例

2、单例模式有3个要点:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供整个实例

3、1个角色:Singleton(单例)

4、饿汉式单例类与懒汉式单例类比较

饿汉式单例类:无须考虑多个线程同时访问的问题,调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长;

懒汉式单例:实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能收到一定影响。

4、单例模式优点:

①提供了对唯一实例的受控访问

②节约系统资源

③允许可变数目的实例

5、缺点:

①扩展困难

②职责过重,一定程度上违背了单一职责原则

③共享的单例对象状态丢失

6、适用环境:

①系统只需要一个实例对象

②客户调用类的单个实例只允许使用一个公共访问点

桥接模式/柄体模式/接口模式

1、在规定的功能架构下对功能参数(效果)进行选择、置换、或取消参数(效果)

2、结构型模式

类结构型模式:关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系

对象结构型模式:关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法

3、定义:将抽象部分和实现部分解耦,使得两者都能够独立变化

4、4个角色:Abstraction(抽象类);RefinedAbstraction(扩充抽象类);Implementor(实现类接口);ConcreteImplementor(具体实现类);

5、桥接模式的优点:

①分离抽象接口及其实现部分

②取代多层继承方案,减少了子类的个数

③提高了系统的可扩展性,符合开闭原则

6、缺点:

①会增加系统的理解与设计难度

②正确识别出系统中两个独立变化的维度,有难度,使用范围有局限性

7、适用环境:

①系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次间建立静态的继承关系

②抽象部分和实现部分可以用继承的方式独立扩展而互不影响

③一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展

④对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统

适配器模式/包装器模式

适配器解决了供需双方不兼容的矛盾,其中需求方是目标角色,提供方是适配者角色

在对象适配器模式中,适配器与适配者是关联关系

在类适配器模式中,适配器与适配者之间是继承(实现)关系

1、定义:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

2、3个角色:Target(目标抽象类);Adapter(适配器类);Adaptee(适配者类)

3、适配器模式的优点:

共同优点①将目标类和适配者类解耦,无需修改原有结构

②增加了类的透明性和复用性

③灵活性和扩张性都非常好

类适配器优点:置换一些适配者的方法更方便

对象适配者的优点:可以把多个不同的适配者适配到同一个目标;还可以适配一个适配者的子类

4、适配器模式的缺点:

类适配器的缺点:

①一次只能适配一个适配者类

②适配者类不能为最终类

③目标抽象类只能为接口,不能为类

对象适配器的缺点:

        适配器中置换适配者的某些方法比较麻烦

5、适用环境:

①系统需要一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码

②想创建一些可以重复使用的类

装饰模式

组合关系是为了保留原图(装饰之前的图),继承关系是为了组合装饰(进行多次装饰)。

1、定义:动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。

2、4个角色:Component(抽象构建);ConcreteComponent(具体构建);Decorator(抽象装饰类);ConcreteDecorator(具体装饰类)

3、装饰模式优点:

①对于扩展一个对象的功能,装饰者模式比继承更加灵活,不会导致类的个数急剧增加

②可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰者类,从而实现不同的行为

③可以对一个对象进行多次装饰者

④具体构件类与具体装饰者类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰者类,且原有类库代码无须改变,符合开闭原则

4、装饰模式缺点:

①使用装饰者模式进行系统设计时将产生很多小对像,大量小对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能

比继承更加易于出错,排错也更困难,对于多次装饰者的对象,调试时寻找错误可能需要逐级排查,较为繁琐

5、装饰模式适用环境

①在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责

②当不能采用继承的方式对系统进行扩展或采用继承不利于系统扩展和维护时可以使用装饰模式

代理模式

1、定义:给某个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问

2、3个角色:Subject(抽象主题角色)、Proxy(代理主题角色)、RealSubject(真实主题角色)

3、代理模式优点:

①能够协调调用者和被调用者,在一定程度上降低了系统的耦合度

②客户端可以针对抽象主题角色进行编程,增加和更换代理类无需修源代码,符合开闭原则,系统具有较好的灵活性和可扩展性

4、代理模式缺点:

①由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢(例如保护代理)

②实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂(例如远程代理)

5、模式的适用环境:

①当客户对象需要访问远程主机中的对象时可以使用远程代理

②当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理

③当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理

④当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限可以使用保护代理

⑤当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理

5、几种常见的代理模式

远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以在同一台主机中,也可以在另一台主机中,远程代理又称为大使(Ambassador),比如翻墙软件

虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建,比如比赛获奖的代表上台领奖

保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限,比如防火墙

缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果,比如视频播放用于缓冲的临时文件

智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,比如统计网址访问次数

命令模式

1、定义:将一个请求封装为一个对象,从而让你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作

2、4个角色:Command(抽象命令类)、ConcreteCommand(具体命令类)、Invoker(调用者)、Receiver(接收者)

3、实现思路: 

①命令模式的本质是对请求进行封装

一个请求对应于一个命令,将发出命令的责任和执行命令的责任分开

③命令模式允许请求的一方和接受的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行

4、命令模式优点:

降低了系统耦合度

②新的命令可以很容易地加入到系统中,符合开闭原则

③可以比较容易地设计一个命令队列或宏命令(组合命令)

④为请求的撤销(Undo)和恢复(Redo)操作提供了一种设计和实现方案

5、命令模式缺点:

①使用命令模式可能会导致某些系统有过多的具体命令类(针对每一个对请求接收者的调用操作都需要设计一个具体命令类)

6、命令模式适用环境

①系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互

②系统需要在不同的时间指定请求将请求排队和执行请求

③系统需要支持命令的撤销(Undo)和恢复(Redo)操作

④系统需要将一组操作组合在一起形成宏命令

观察者模式

又名:发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式、从属者(Dependents)模式

1、定义:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。

2、四个角色:Subject(目标)、 ConcreteSubject(具体目标)、 Observer(观察者)、 ConcreteObserver(具体观察者)

3、观察者模式优点:

①可以实现表示层和数据逻辑层的分离

②在观察目标和观察者之间建立一个抽象的耦合

③支持广播通信,简化了一对多系统设计的难度

符合开闭原则,增加新的具体观察者无需修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便

4、观察者模式缺点:

①将所有的观察者都通知到会花费很多时间

②如果存在循环依赖可能导致系统崩溃

没有相应的机制让观察者知道所观察的目标对象是怎样发生变化的,而只是知道观察目标发生了变化

5、观察者模式适用环境:

①一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用

一个对象的改变将导致一个或多个其他对象发生改变,并且不知道具体有多少对象将发生改变,也不知道这些对象是谁

③需要在系统中创建一个触发链

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值