vrmlpad家居场景实例代码_设计模式使⽤场景、优缺点汇总创建型
1、单例模式:
Singleton Design Pattern
⼀个类只允许创建⼀个对象(或者实例),这个类就是⼀个单例类
单例的实现:饿汉式、懒汉式、双重检查、静态内部类、枚举
作⽤:避免频繁创建和销毁系统全局使⽤的对象
应⽤场景:全局唯⼀类,如 系统配置类、系统硬件资源访问类;公共服务类:如 servlet、springmvc 中的 bean、数据库连接池;
Web 计数器、序列号⽣成器
缺陷:对 OOP 特性的⽀持不友好、隐藏类之间的依赖关系、对代码的扩展性不友好、对代码的可测试性不友好、不⽀持有参数的构造函数
替代⽅案:程序员控制、⼯⼚模式、IOC 容器
扩展:线程纬度的单例、集环境下的单例、多例模式
2、⼯⼚模式:
Factory Design Pattern
分为:简单⼯⼚、⼯⼚⽅法和抽象⼯⼚。简单⼯⼚可以看作是⼯⼚⽅法的⼀种特例
作⽤:封装变化(创建逻辑有可能变化,封装成⼯⼚类之后,创建逻辑的变更对调⽤者透明)、代码复⽤(创建代码抽离到独⽴的⼯⼚类之后可以复⽤)、隔离复杂性(封装复杂的创建逻辑,调⽤者⽆需了解如何创建对象)、控制复杂度(将创建代码抽离出来,让原本的函数或类职责更单⼀,代码更简洁)
简单⼯⼚适⽤场景:对象的创建逻辑⽐较简单,if-else 并不多
⼯⼚⽅法适⽤场景:对象的创建逻辑⽐较复杂,不只是简单的 new ⼀下就可以,⽽是要组合其他类对象,做各种初始化操作;避免 if-else
抽象⼯⼚适⽤场景:可以创建多种不同类型的⼯⼚,能够创建⼀簇对象,减少了⼯⼚类
简单⼯⼚、⼯⼚⽅法、抽象⼯⼚之间的关系与选择:如果实例对象的创建逻辑并发不复杂、实例对象
的种类并不多即 if 分⽀不多,且基本不会有太⼤变动,使⽤简单⼯⼚模式;需要创建的实例化对象种类较多、变动可能性⼤、对象的创建逻辑⽐较复杂,使⽤⼯⼚⽅法,可以去除 if 多分⽀、将复杂的对象创建逻辑封装到每个具体⼯⼚中;抽象⼯⼚的使⽤并不多,适⽤于实例对象的层级逻辑⽐较复杂,抽象出多个实例对象组,每个⼯⼚创建⼀组实例对象
3、建造者:
Builder Design Pattern
应⽤场景:能够解决构造⽅法的参数很多传错参数的问题;可以保证类属性字段安全,不⽤提供 public setter ⽅法;可以进⾏属性字段间的校验、计算、填充等
缺点:创建对象前必须创建 Builder 对象,多⼀些性能开销,对性能要求极⾼的的场景下慎⽤;代码有点啰嗦
4、原型模式:
Prototype Design Pattern
作⽤:对象的创建成本⽐较⼤,同⼀个类的不同对象之间的⼤部分字段相同,可以对已有对象进⾏拷贝的⽅式创建新对象,达到节省新对象的创建时间的⽬的
⽅式:浅拷贝(仅复制基本类型、引⽤类型的属性变量、引⽤类型变量的指针;并不复制引⽤类型变量指向的堆内存中的对象,⽽是指向同⼀个对象)、深拷贝(复制基本类型、应⽤类型的属性变量、引⽤类型变量的指针、引⽤类型指向的堆内存中对象,获得⼀个完全独⽴的对象)
实现:浅拷贝(实现 Cloneable 接⼝,重写 clone ⽅法)、深拷贝(实现 Cloneable 接⼝,递归 clone 引⽤对象或 new 新对象;借助序列化完成深拷贝)
结构型
1、代理模式:
Proxy Design Pattern
作⽤:在不改变原始类(或叫被代理类)代码的情况下,通过引⼊代理类来给原始类附加功能。使⽤代理对象完成⽤户请求,屏蔽⽤户对真实对象的访问
⽅式:静态代理、动态代理(JDK ⾃带、cglib、Javassist 可实现)
应⽤场景:代理模式常⽤在业务系统中开发⼀些⾮功能性需求,⽐如:监控、统计、鉴权、限流、事务、幂等、⽇志。将这些附加功能与业务功能解耦,放到代理类统⼀处理,程序员只需要关注业务⽅⾯的开发;远程代理、虚拟代理、安全代理...;框架开发,如Spring AOP 功能(JDK动态代理、cglib)
缺点与注意:静态代理需要⼀个代理类对应⼀个被代理类,容易造成类⽂件增加很多,增加⼤量的维护⼯作;JDK 动态代理,需要满⾜⼀个条件,就是被代理类需要实现接⼝,否则会抛出 java.lang.ClassCastException 异常;随着 JVM 的优化,JDK 1.8 开始 JDK 动态代理的性能赶上并超越 cglib;cglib 采⽤动态创建⼦类的⽅法,final 修饰的⽅法⽆法进⾏代理;cglib 创建代理对象时所花费的时间却⽐ JDK 动态代理要多
2、桥接模式:
Bridge Design Pattern
作⽤:将抽象和实现解耦,让它们可以独⽴变化;让⼀个类拥有两个或多个独⽴变化的维度,通过组合的⽅式,让这两个或多个维度可以独⽴进⾏扩展
实际应⽤:JDBC 驱动程序的加载、JVM 在多操作系统间的实现、GUI 在多操作系统间的实现
优点:分离抽象接⼝与实现、类似多继承但⽐多继承灵活、可扩展性强、功能对⽤户透明,隐藏了实现细节
缺点:需要抽象出变化的维度,对业务理解程度要求较⾼、对系统的设计能⼒要求较⾼、代码较难理解
3、装饰器模式:
Decorator Design Pattern
作⽤:能够动态地给⼀个对象添加额外的职责,灵活地⽣成⼦类;主要解决了原始类在多个⽅向上功能扩展的问题;原始类可以嵌套使⽤多个装饰器类,装饰器类需要跟原始类继承相同的抽象类或实现相同的接⼝;装饰器类具有 is-a 和 has-a 的双重关系
⾓⾊:被修饰对象的基类、具体被装饰的类、装饰者的抽象类、具体的装饰类
优点:可以动态扩展⼀个实现类的功能,装饰类和被装饰类可以独⽴扩展,不会相互耦合
缺点:层次关系⽐较复杂
4、适配器模式:
Adapter Design Pattern
作⽤:适配,将不兼容的接⼝转换为可兼容的接⼝,让原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作
应⽤场景:对有缺陷的接⼝设计进⾏再次封装、统⼀多个类的接⼝设计、替换依赖的系统、兼容⽼版本接⼝、适配不同格式的数据实际例⼦:JDK Iterator 适配 Enumeration;slf4j 对不同的⽇志框架进⾏了适配
优点:适配器模式是⼀种补充模式,可以⽤来系统的后期扩展与修改
缺点:不适合过多使⽤,否则代码中的⽅法调⽤⽐较乱
5、门⾯模式:
Facade Design Pattern
门⾯模式为⼦系统提供⼀组统⼀的接⼝,定义⼀组⾼层接⼝让⼦系统更易⽤
作⽤:封装系统的底层实现,隐藏系统的复杂性,提供⼀组更加简单易⽤、更⾼层的接⼝;客户端原本对多个⼦系统接⼝的调⽤,改为调⽤门⾯的⼀个接⼝,较少交互,提升性能;解决事务问题
6、组合模式:
Composite Design Pattern
作⽤:将⼀组对象组织成树状结构,以表⽰部分和整体的层次结构,让客户端可以统⼀单个对象和组合对象的逻辑;更像是⼀种树形结构数据场景下的数据结构与算法的抽象
使⽤场景:主要⽤来处理树形结构的数据。如部门、⼈员组成树状结构,计算薪资
优点:灵活增加节点、调⽤简单、代码简洁
缺点:适⽤场景⾮常单⼀
7、享元模式:
Flyweight Design Pattern
作⽤:复⽤对象,节省内存。(前提是享元对象是不可变对象)
应⽤场景:当⼀个系统中存在⼤量重复对象的时候,可以利⽤享元模式,将对象设计成享元,在内存中只保留⼀份实例,供多处代码引⽤,减少内存中对象的数量,节省内存。如JDK 中 Integer 类就使⽤了享元模式缓存了 -128 ~ 127 范围的整数
实现:主要是通过⼯⼚模式,在⼯⼚类中,通过⼀个 Map 或者 List 来缓存已经创建好的享元对象,以达到复⽤的⽬的
⾏为型
1、观察者模式:
Observer Design Pattern
定义:在对象之间定义⼀个⼀对多的依赖,当⼀个对象状态改变的时候,所有依赖的对象都会⾃动收到通知
优点:降低了⽬标与观察者之间的耦合关系、⽬标与观察者之间建⽴了⼀套触发机制
缺点:当观察者对象很多时,通知的发布会花费很长时间
抽象类的使用应⽤场景:对象间存在⼀对多关系,⼀个对象的状态发⽣改变会影响其他对象
实际应⽤:邮件订阅、RSS Feeds、MQ 消息发布与订阅
2、模板模式:
Template Method Design Pattern
定义:模板⽅法模式在⼀个⽅法中定义⼀个算法⾻架,并将某些步骤推迟到⼦类中实现。模板⽅法模式可以让⼦类在不改变算法整体结构的情况下,重新定义算法中的某些步骤
实际应⽤:Java InputStream、Java AbstractList、Java Servlet、JUnit TestCase
作⽤:代码复⽤(⼦类可以复⽤⽗类中提供的模板⽅法的代码)和扩展(提供功能扩展点,可以在不修改框架源码的情况下,基于扩展点定制化框架的功能)
缺点:某种实现都需要⼦类,类的数量增多;代码可读性变差
3、策略模式:
Strategy Design Pattern
定义:定义了⼀系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使⽤算法的客户
理解:包含策略的定义、实现类的创建、静态或者动态使⽤不同策略
应⽤场景:替代根据类型进⾏多层 if -else 判断
优点:避免使⽤多重条件语句;避免重复代码;提供相同⾏为的不同实现;符合开闭原则,灵活增加新算法
缺点:策略实现类会⽐较多
4、职责链模式:
Chain of Responsibility Design Pattern
作⽤:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成⼀条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为⽌
优点:将请求的发送者和接收者解耦;增强了系统的可扩展性,根据需要增加新的请求处理类,满⾜开闭原则;责任分担,每个类只需要处理⾃⼰该处理的⼯作,明确责任范围,符合单⼀职责原则
缺点:不能保证每个请求⼀定被处理
使⽤场景:可动态指定⼀组对象处理请求
实际应⽤:Servlet Filter、Spring Interceptor、Dubbo Filter、 Netty ChannelPipeline
5、状态模式:
State Design Pattern
定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发⽣改变时改变其⾏为
应⽤场景:当⼀个对象的⾏为取决于它的状态,并且它必须在运⾏时根据状态改变它的⾏为;⼀个操作中含有庞⼤的分⽀结构,并且这些分⽀决定于对象的状态
实际应⽤:状态机、游戏中不同⼈物⾓⾊的切换
优点:封装状态变化、减少对象间的相互依赖、利于程序的扩展
缺点:结构与实现都较为复杂
6、迭代器模式:
Iterator Design Pattern
定义:提供⼀个对象来顺序访问聚合对象中的⼀系列数据,⽽不暴露聚合对象的内部表⽰
实际应⽤:JDK 中 Iterator 接⼝
优点:封装集合内部的复杂数据结构,;将集合对象的遍历操作从集合类中拆分出来,职责单⼀;添加新的遍历算法更加容易,更符合开闭原则
7、访问者模式:
Visitor Design Pattern
定义:允许⼀个或者多个操作应⽤到⼀组对象上,解耦操作和对象本⾝
作⽤:在被访问的类⾥⾯加⼀个对外提供接待访问者的接⼝,解决稳定的数据结构和易变的操作耦合问题
应⽤场景:对象结构相对稳定,但其操作算法经常变化;对象提供多种不同且不相关的操作,避免对结构的影响;
优点:不修改对象结构,为对象结构中的元素添加新的功能,扩展性好;通过访问者来定义整个对象结构通⽤的功能,提⾼复⽤性;将数据结构与作⽤于结构上的操作解耦,灵活性好;访问者模式把相关的⾏为封装在⼀起,符合单⼀职责原则
缺点:增加新的元素类很困难,违反开闭原则;具体元素对访问者公布细节,这破坏了对象的封装性;依赖了具体类,违反了依赖倒置原则;难理解、难实现
8、备忘录模式:
Memento Design Pattern
定义:在不违背封装原则的前提下,捕获⼀个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态作⽤:提供了恢复状态的机制;实现了内部状态的封装,满⾜单⼀职责原则
实际场景:游戏存档、编辑器和 IDE 的 ctrl+Z 回滚、数据库回滚
缺点:内容过多或者过频繁备份,资源消耗⼤;适⽤场景单⼀
9、命令模式:
Command Design Pattern
定义:将请求(命令)封装为⼀个对象,这样可以使⽤不同的请求参数化其他对象(将不同请求依赖注⼊到其他对象),并且能够⽀持请求(命令)的排队执⾏、记录⽇志、撤销等(附加控制)功能
作⽤:将调⽤操作的对象与实现该操作的对象解耦;增加或删除命令⾮常⽅便,不影响其他类,符合开闭原则
实际应⽤:游戏开发中将把请求包含的数据和处理逻辑封装为命令对象执⾏;与备忘录模式组合,实现 redo、undo 功能
缺点:产⽣⼤量具体命令类
10、解释器模式:
Interpreter Design Pattern
定义:为某个语⾔定义它的语法(或者叫⽂法)表⽰,并定义⼀个解释器⽤来处理这个语法
作⽤:构建固定⽂法的句⼦的解释器
缺点:通常使⽤⼤量的循环和递归调⽤,当要解释的句⼦较复杂时,其运⾏速度很慢;较难调试;包含的⽂法规则很多时会引起类膨胀;适⽤场景单⼀
11、中介模式:
Mediator Design Pattern
定义:定义了⼀个单独的(中介)对象,来封装⼀组对象之间的交互。将这组对象之间的交互委派给与中介对象交互,来避免对象之间的直接交互
作⽤:引⼊中介这个中间层,将对象间的⼀对多关联转变为⼀对⼀的关联,只需要跟中介对象交互即可
优点:降低了代码的复杂度,提⾼了代码的可读性和可维护性
缺点:中介者的职责很⼤时,代码将复杂,可维护性降低
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论