程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

工厂、建造者、装饰器、适配器:解密JDK设计模式的实战妙用

balukai 2025-07-17 17:17:21 文章精选 2 ℃

工厂、建造者、装饰器、适配器:解密JDK设计模式的实战妙用

本文旨在通过对Java JDK源码的典型设计模式分析,帮助移动端开发者(Swift/Kotlin)深入理解设计模式的工程应用。文章全程结合移动端实例类比,细致讲解工厂模式、建造者模式、装饰者模式、适配器模式在实际开发中的精妙之处。


一、为何要研究JDK源码中的设计模式?

Java JDK是全球最成熟、代码最优雅、模式最丰富的基础库之一。无论是工厂模式、建造者模式,还是装饰者、适配器等,都能在其中找到最原教旨的应用案例。
对于移动端开发者而言,虽然平台语言不同,但JDK源码中这些模式的思想完全可以迁移。很多Kotlin/Swift标准库、第三方框架、开源库的底层实现也借鉴了JDK的架构。

你将学到:

  • o 如何识别大型系统中的设计模式,并应用到移动端开发。
  • o 设计模式不是模板,而是解耦、可扩展、易维护的思路和工程实践。
  • o 理解JDK源码背后的设计原则,能让你的Swift/Kotlin代码更健壮、更优雅。

二、工厂模式(Factory Pattern):对象创建的“开关”

2.1 JDK中的经典工厂方法

JDK的Calendar类实例化就是典型的工厂方法:

public static Calendar getInstance(Locale aLocale)
  • o 你无需直接new Calendar子类对象,而是通过静态工厂方法getInstance()获得本地化/时区适配的对象。
  • o 这个“工厂”会根据平台、参数选择合适的实现类(如GregorianCalendar、JapaneseImperialCalendar等)。

Swift实现类比

假设你做一个日历App,不同地区需要定制化的Calendar:

protocol CalendarType {
    func today() -> Date
}
class ChineseCalendar: CalendarType { /*...*/ }
class JapaneseCalendar: CalendarType { /*...*/ }
class GregorianCalendar: CalendarType { /*...*/ }

class CalendarFactory {
    static func createCalendar(locale: Locale) -> CalendarType {
        switch locale.identifier {
        case "zh_CN": return ChineseCalendar()
        case "ja_JP": return JapaneseCalendar()
        default: return GregorianCalendar()
        }
    }
}
let calendar = CalendarFactory.createCalendar(locale: Locale.current)

Kotlin实现类比

interface CalendarType {
    fun today(): Date
}
class ChineseCalendar: CalendarType { /*...*/ }
class JapaneseCalendar: CalendarType { /*...*/ }
class GregorianCalendar: CalendarType { /*...*/ }

object CalendarFactory {
    fun createCalendar(locale: Locale): CalendarType = when(locale.language) {
        "zh" -> ChineseCalendar()
        "ja" -> JapaneseCalendar()
        else -> GregorianCalendar()
    }
}
val calendar = CalendarFactory.createCalendar(Locale.getDefault())

优点总结

  • o 业务层不用关心具体类型,只需要调用工厂方法。
  • o 新增地区、节日、特殊实现时,只需扩展工厂和子类,无需大改业务。
  • o 解耦了对象创建和使用,易于扩展和测试。

三、建造者模式(Builder Pattern):复杂对象一步步组装

3.1 JDK中的Builder模式

JDK很多类使用Builder模式解决“构造参数过多”的困扰(如StringBuilder、Calendar.Builder等):

Calendar cal = new Calendar.Builder()
    .setCalendarType("gregory")
    .setDate(2023, 6, 1)
    .setTimeOfDay(14, 0, 0)
    .build();
  • o 通过链式方法调用设置各类参数,最后统一build。
  • o 避免构造函数参数爆炸,提升可读性、灵活性。

Swift实现类比

class MeetingBuilder {
    private var title: String = ""
    private var date: Date = Date()
    private var place: String = ""

    func setTitle(_ title: String) -> MeetingBuilder { self.title = title; return self }
    func setDate(_ date: Date) -> MeetingBuilder { self.date = date; return self }
    func setPlace(_ place: String) -> MeetingBuilder { self.place = place; return self }
    func build() -> Meeting { Meeting(title: title, date: date, place: place) }
}

let meeting = MeetingBuilder()
    .setTitle("设计模式研讨会")
    .setDate(Date())
    .setPlace("线上")
    .build()

Kotlin实现类比

class MeetingBuilder {
    private var title: String = ""
    private var date: Date = Date()
    private var place: String = ""

    fun setTitle(title: String) = apply { this.title = title }
    fun setDate(date: Date) = apply { this.date = date }
    fun setPlace(place: String) = apply { this.place = place }
    fun build() = Meeting(title, date, place)
}

val meeting = MeetingBuilder()
    .setTitle("设计模式研讨会")
    .setDate(Date())
    .setPlace("线上")
    .build()

优点总结

  • o 避免构造函数参数爆炸,链式可读性强。
  • o 易于新增/删减参数,维护和拓展友好。
  • o 适合组装复杂配置、表单、弹窗、多参数对象等场景。

四、装饰器模式(Decorator Pattern):运行时扩展对象能力

4.1 JDK中的装饰器

JDK的I/O库(如BufferedInputStream、DataInputStream等)大量用到装饰器模式:

InputStream in = new FileInputStream("a.txt");
InputStream buffered = new BufferedInputStream(in);
InputStream data = new DataInputStream(buffered);
  • o 动态包装对象,按需扩展功能。
  • o 不需要继承一堆类,只需组合“装饰器”即可。

Swift实现类比

protocol InputStream {
    func read() -> Data
}
class FileInputStream: InputStream {
    func read() -> Data { /* 读取文件 */ }
}
class BufferedInputStream: InputStream {
    private let inner: InputStream
    init(_ input: InputStream) { self.inner = input }
    func read() -> Data { /* 先缓冲,再读inner.read() */ }
}
class DataInputStream: InputStream {
    private let inner: InputStream
    init(_ input: InputStream) { self.inner = input }
    func read() -> Data { /* 解析数据格式,再读inner.read() */ }
}

let fileIn: InputStream = FileInputStream()
let buffered: InputStream = BufferedInputStream(fileIn)
let dataIn: InputStream = DataInputStream(buffered)

Kotlin实现类比

interface InputStream {
    fun read(): ByteArray
}
class FileInputStream: InputStream {
    override fun read(): ByteArray { /* 读取文件 */ return ByteArray(0) }
}
class BufferedInputStream(private val inner: InputStream): InputStream {
    override fun read(): ByteArray { /* 缓冲+inner.read() */ return inner.read() }
}
class DataInputStream(private val inner: InputStream): InputStream {
    override fun read(): ByteArray { /* 数据解析+inner.read() */ return inner.read() }
}

val fileIn: InputStream = FileInputStream()
val buffered: InputStream = BufferedInputStream(fileIn)
val dataIn: InputStream = DataInputStream(buffered)

优点总结

  • o 动态组合功能,避免继承层级爆炸。
  • o 运行时可灵活拼装新能力(如缓存、加密、统计、限速等)。
  • o 移动端场景:图片加载(缓存/解码/统计)、网络请求装饰、UI视图“链式修饰”等。

五、适配器模式(Adapter Pattern):让不兼容的接口协同工作

5.1 JDK中的适配器

JDK的Adapter典型如Collection的UnmodifiableCollection(只读视图)、各种Listener Adapter(抽象类适配接口)。

比如
Collection.unmodifiableCollection():

Collection<String> c = Arrays.asList("a", "b", "c");
Collection<String> readOnly = Collections.unmodifiableCollection(c);
  • o 你得到一个“只读适配器”,不能再添加/删除元素。
  • o 原始对象和外部接口“解耦”,用适配器包装即可。

Swift实现类比

protocol UserList {
    func count() -> Int
    func user(at: Int) -> String
}
class ArrayUserList: UserList {
    private let users: [String]
    init(_ users: [String]) { self.users = users }
    func count() -> Int { users.count }
    func user(at: Int) -> String { users[at] }
}
class ReadOnlyUserList: UserList {
    private let inner: UserList
    init(_ inner: UserList) { self.inner = inner }
    func count() -> Int { inner.count() }
    func user(at: Int) -> String { inner.user(at: at) }
    // 不暴露写方法
}
let arrayList = ArrayUserList(["A", "B", "C"])
let readOnlyList = ReadOnlyUserList(arrayList)

Kotlin实现类比

interface UserList {
    fun count(): Int
    fun userAt(index: Int): String
}
class ArrayUserList(private val users: List<String>): UserList {
    override fun count() = users.size
    override fun userAt(index: Int) = users[index]
}
class ReadOnlyUserList(private val inner: UserList): UserList {
    override fun count() = inner.count()
    override fun userAt(index: Int) = inner.userAt(index)
    // 无写入接口
}
val arrayList = ArrayUserList(listOf("A", "B", "C"))
val readOnlyList = ReadOnlyUserList(arrayList)

优点总结

  • o 新旧接口轻松对接,兼容老代码。
  • o 封装第三方库、外部API、不同平台模块(如iOS/Android不同蓝牙库适配)时尤为常用。
  • o 动态保护数据安全、只读、权限隔离等场景。

六、从JDK设计到App工程实践的迁移思考

  1. 1. 不是照搬JDK实现,而是理解背后的思想:
  2. o 工厂模式提升对象创建灵活性,适合业务多变的场景(如支付、UI组件、数据存储等)。
  3. o Builder链式构建,适合复杂数据输入、表单、弹窗、多配置项初始化。
  4. o 装饰器让功能扩展随需应变,避免子类膨胀、运行时自由组合。
  5. o 适配器让不同系统、接口、第三方库协同,轻松对接新老平台。
  6. 2. 移动端开发中的实践技巧:
  7. o 善用协议(Swift)和接口(Kotlin)实现解耦,保持代码可测和可扩展。
  8. o 抽象与封装应服务于灵活迭代,而非“炫技”或提前堆砌。
  9. o 理解和迁移标准库、开源框架中的优秀模式,让App代码更健壮、可维护。

七、总结与观点升华

  • o JDK源码是设计模式教科书,阅读和类比移植能让你的App架构层次分明、应对变化游刃有余。
  • o 设计模式不是固定套路,而是为实际工程问题提供通用解法的智慧。
  • o 推荐定期阅读优秀开源代码,将JDK的设计思想融入Swift/Kotlin项目,形成自己的技术积淀。

Tags:

最近发表
标签列表