V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hakunamatata11
V2EX  ›  推广

如何学习设计模式?

  •  
  •   hakunamatata11 · 2020-10-19 17:37:32 +08:00 · 983 次点击
    这是一个创建于 1277 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,设计模式( Design Pattern )是指面向对象设计模式,是“年迈”程序员对代码开放经验的总结,解决特定问题的一系列套路。目的是用来提高代码可复用性、可维护性、可读性、稳健性以及安全性。

    所以设计模式不是什么理论,也不是语法规定,没有对与错,只有合不合适或者好与不好。

    另外不能为了使用设计模式而去做架构,而是有了做架构的需求,这种架构层次在进行基本展开后发现它符合某一类设计模式的结构,再将两者结合。

    时间充裕的话可以来看下 P8 工程师的干货分享:大厂高频设计模式应用及分析

    要正确地使用设计模式,首先要了解有哪些设计模式及其使用场景。

    设计模式按使用场景可以分为三大类

    • 创建型模式:对象实例化的模式,用于对象的创建对业务或应用逻辑是强依赖,或者创建的创景比较复杂的场景。
    • 结构型模式:把类或对象结合在一起形成一个更大的结构。一般是解决不同的类之间有不同关系的情况。
    • 行为型模式:类和对象如何交互,及划分责任和算法。

    3 大类之下又可以分出 23 种设计模式,这里就不一一赘述了。学习设计模式,死记硬背是没用的,还是要在实践中来理解。

    下面我结合实例来讲下如何使用设计模式——用适配器模式扩展我们的架构

    首先,要知道适配器模式的目的是**重用,**重用在工程实践中往往比编程更有价值。

    其次,适用场景:现有的对象(类)有和当前场景相似的能力,但又有明显差异时运用。

    基本思想就是**“封装”和“继承”:封装差异、继承能力。**

    假设,现在我们有这样一个 class,拥有底层的显示商城 Banner 的能力:

    我们期望编写这样一个类:CreateBannerView,其中实现两个方法:

    ①showBannerOnCell - 在手机设备上显示 Banner

    ②showBannerOnPc - 在 PC 设备上显示 Banner

    所以我们可以找到这里存在的 Gap:实际需要是实现在不同设备上的显示 Banner,我们拥有按尺寸进行显示 Banner 的能力。

    初学者的写法一般是这样的:

    缺点是上游对象必须去感知下游对象的实现方式(耦合),BannerSize 的参数被硬编码了,如果要去 pad 上实现呢?

    我们的策略可以用一句话来概括:**“间接”是程序员解决架构问题的钥匙。**具体来说继承方式是扩展一个抽象子类,增加一个确定 BannerSize 的能力:

    这样我们的子类中,就被强制要求实现这样一种能力:

    这里有个问题:抽象方法里面放一个类似“设备类型”的参数不好么?

    回答:底层不应该主动感知上层怎么用,无论是设备类型还是 APP 类型,这个变化都不应该穿透到底层。

    那么这个继承方式能否进一步优化?其实是可以的

    就单一方法来看,无疑已经很简单了,但是我们仍然希望构造 Banner 使用参数的行为不要在这一个层次中出现,这样就需要适配器模式出场了。

    继续利用好抽象类这一层次

    子类只需要感知它应该感知的部分

    现在我们介绍适配器模式的一种实现——委托

    委托即把适配、调用底层的而工作交给别的对象来做。

    委托的目的在于进一步解耦,即将场景感知与底层能力进一步隔离。

    委托的实现有两个关键点:

    1. 接口规约底层要提供给上层的能力
    2. 委托类的实现

    通过接口,定义底层适配后开放两个接口:

    改造 CreateBannerView 为委托类,委托类实现整体接口能力。

    真正的子类,严格匹配场景,通过委托对象调用适配后的底层能力。

    以上,用一张 UML 图概括一下:

    最后总结一下

    • 适配器模式的意义:避免上层和底层之间互相感知。
    • 适配器模式的用途:系统垂直层次架构的利器。
    • 适配层沉淀抽象后的适配逻辑
    • 接口规约适配后的底层系统能力
    • 适配层开放抽象方法给子类实现适配策略的定制
    • 委托类将沉淀下来的适配层通过接口实现为子类提供标准接口能力

    为什么要使用适配器模式?

    将一些“现存的对象”放到新的环境钟,而新环境要求的接口是现对象不能满足的,使用适配器模式让他满足。

    适配器模式的优缺点?

    优点:

    • 可以让任何两个没有关联的类一起运行
    • 提高了类的复用
    • 增加了类的透明度
    • 灵活性好

    缺点:

    • 过多地使用适配器,会让系统非常零乱;
    • 由于 Java 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

    适配器模式的使用场景

    1. Java JDK1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式
    2. Java 中的 jdbc 。

    以上这些也是 Java 高级工程师面试中经常出现的问题,在 P8 技术专家主讲的《Java 高级工程师 P6+》会有详尽的讲解,内容涵盖 Java 技术栈的通透讲授、源码的分析导读、贴近实际的工程实践以及大厂思维的架构升级。有兴趣的同学,可以来看看~

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3243 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 13:27 · PVG 21:27 · LAX 06:27 · JFK 09:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.