设计模式起手式:介面(Interface)

在阅读经典书籍《设计模式 Design Patterns》中,如果你跳过第 1 章引言,那你可能就错过了设计模式的核心概念了!作者在引言中花了大篇幅讲解 介面 在物件导向设计中的定位,以及设计模式如何透过 介面 来解决问题。

介面 可以说是物件导向设计用来处理 软体複杂度 的利器,因此本文将会讲解 介面 在物件导向设计中所扮演的角色为何,以及实务开发中会如何利用介面让程式码适应变化!

介面是什么?

类别(Class)可以宣告的公开方法(Public Method),供使用者从外部操作类别的功能。类别的所有公开方法集合起来被称为「类别的介面」。

介面是物件导向的基本元素,外部环境只能透过介面向类别请求执行功能或存取类别内部的资源。若没有介面,类别将没办法与外部环境互动,外部环境也没办法得知类别的内容。

介面可以和实作分离

介面的存在,造就了 外部视角与内部视角。介面暴露了类别的对外公开资讯形成外部视角。外部环境只能从外部视角观察一个类别的基本行为,无法得知类别内部(内部视角)是如何实现介面的行为。外部环境只关注介面的特性,使得介面可以和实现内容分离。因此,一个介面可以被多个不同的类别实现;实现相同介面的两个类别,可以对介面实现完全不同的行为。

外部环境只能与介面互动,且介面可以与实现内容分离。

利用介面达到多型(Polymorphism)

虽然说介面与实现内容是分离的,但程式码运行中,介面的行为是由具体的实现内容组成。向一个介面调用同一个方法,会因为不同的具体实现而有不同的行为。程式码有办法在调用介面的瞬间,连接到介面当下的具体实现,这个能力被称为动态绑定(Dynamic binding)。

动态绑定让程式码能在调用介面的瞬间才受到具体实现的影响,这种弹性让开发人员有办法在系统运行的过程中,动态替换相同介面的具体实现。这种可替换性就被称为 多型(Polymorphism)。

程式码能在调用介面的瞬间,连接到当下的具体实作

「设计」要适应变化

以上面的购物车线上付费功能(Pay)为例,若不使用多型来实践,则所有付款商的连线(connect)、购物(purchase)与付款(send)的实现细节,都将暴露在购物车的付费程式码中。届时,程式码不但变得很长,还会充满一堆 switch case 或 if else,最惨的是付款商之间的程式码互相耦合了!一但程式码依赖实现内容就会出现很多问题,维护起来会变得困难。这也是为什么,设计模式的作者呼吁开发人员应该要:

Program to an interface, not an implementation.
让程式码关注于介面,而不是实现内容。

开发人员应该要 利用介面来对实现细节进行抽象简化,将实作细节隐藏在类别的内部。并且利用介面动态替换具体实现的机制(多型),让程式码变得容易扩充与适应变化。

当然,需求在一开始的分析阶段并不知道会有这么多种细节,但需求会随着时间不断变化和增长。因此程式码的设计必须随着需求异动而改变,这也是《设计模式》的目的:提供一系列的良好的「设计」,使程式码易于管理,亦是系统重构的目标。当系统变得越来越複杂时,开发人员可以不断地透过重构调整程式码的「设计」,让程式码适应变化!

注:上面购物车付费功能是引入 State 模式 来管理程式码。

延伸阅读

物件导向设计原则:开放封闭原则物件导向设计原则:里氏替换原则

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章