百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

从MyBatis到App架构:设计模式全景应用指南

ccwgpt 2025-08-03 04:24 1 浏览 0 评论

从MyBatis到App架构:设计模式全景应用指南


引言

在企业级应用和服务端开发领域,MyBatis凭借其灵活、简洁、强大的ORM映射能力被广泛应用。而它之所以能拥有如此优秀的可扩展性和工程可维护性,正是因为在其源码和架构中深度融合了多种设计模式。这些设计模式不仅仅适用于后端开发,对于移动端(如Swift/Kotlin)开发同样具有极高的参考价值和迁移意义。

本文将从架构、源码和实战三个维度,详细梳理MyBatis中用到的10大经典设计模式,深入分析其应用原理,并结合Swift和Kotlin举例,帮助移动端工程师理解并落地这些模式。无论你是追求高质量架构的App开发者,还是服务端和客户端双修的全栈工程师,这篇内容都值得收藏!


1. 工厂模式(Factory Pattern)

定义与作用:
工厂模式用于将对象的创建与使用解耦,客户端无需关心具体实例化过程,直接通过工厂获得对象。MyBatis广泛使用工厂模式来管理对象的生命周期,比如SqlSessionFactory、TypeHandlerFactory等。

MyBatis源码示例解读:
以SqlSessionFactory为例,用户通过工厂获取SqlSession对象,而不是自己手动new对象。

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = factory.openSession();

原理:

  • o 提供统一接口创建对象。
  • o 便于替换实现和扩展。

移动端实战举例(Swift/Kotlin):
比如网络请求层的工厂封装:

protocol NetworkClient { func request(url: String) }
class AlamofireClient: NetworkClient { func request(url: String) { /* ... */ } }
class URLSessionClient: NetworkClient { func request(url: String) { /* ... */ } }

enum ClientType { case alamofire, urlsession }
class NetworkFactory {
    static func createClient(type: ClientType) -> NetworkClient {
        switch type {
        case .alamofire: return AlamofireClient()
        case .urlsession: return URLSessionClient()
        }
    }
}
let client = NetworkFactory.createClient(type: .alamofire)
client.request(url: "https://api.example.com")
interface NetworkClient { fun request(url: String) }
class OkHttpClient : NetworkClient { override fun request(url: String) { /* ... */ } }
class KtorClient : NetworkClient { override fun request(url: String) { /* ... */ } }

object NetworkFactory {
    fun createClient(type: String): NetworkClient = when (type) {
        "okhttp" -> OkHttpClient()
        else -> KtorClient()
    }
}
val client = NetworkFactory.createClient("okhttp")
client.request("https://api.example.com")

2. 单例模式(Singleton Pattern)

定义与作用:
保证系统中某个类只有一个实例,且全局可访问。MyBatis大量使用单例,如Configuration、SqlSessionFactoryBuilder等。

MyBatis源码示例解读:

public class Configuration {
    private static final Configuration INSTANCE = new Configuration();
    public static Configuration getInstance() { return INSTANCE; }
}

原理:

  • o 避免重复创建,节省资源。
  • o 全局共享状态。

移动端实战举例(Swift/Kotlin):
全局管理类、配置中心、数据库、缓存等。

class UserManager {
    static let shared = UserManager()
    private init() {}
    var username: String?
}
UserManager.shared.username = "Alice"
object UserManager {
    var username: String? = null
}
UserManager.username = "Alice"

3. 代理模式(Proxy Pattern)

定义与作用:
为其他对象提供代理以控制对该对象的访问。MyBatis中的Mapper代理、缓存机制等都是典型应用。

MyBatis源码示例解读:
MapperProxy负责为每个Mapper接口生成代理对象,自动执行SQL,无需手写实现类。

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.findById(1);

原理:

  • o 动态生成代理对象,拦截方法调用。
  • o 可实现懒加载、访问控制、缓存等功能。

移动端实战举例(Swift/Kotlin):
网络层的Mock代理、权限校验代理等。

protocol ImageLoader { func load(url: String) }
class RealImageLoader: ImageLoader { func load(url: String) { print("Load from \(url)") } }
class ImageLoaderProxy: ImageLoader {
    private let real: ImageLoader
    init(real: ImageLoader) { self.real = real }
    func load(url: String) {
        print("Check permission")
        real.load(url: url)
    }
}
let loader = ImageLoaderProxy(real: RealImageLoader())
loader.load(url: "http://image.com/test.jpg")
interface ImageLoader { fun load(url: String) }
class RealImageLoader : ImageLoader { override fun load(url: String) { println("Load from $url") } }
class ImageLoaderProxy(private val real: ImageLoader) : ImageLoader {
    override fun load(url: String) {
        println("Check permission")
        real.load(url)
    }
}
val loader: ImageLoader = ImageLoaderProxy(RealImageLoader())
loader.load("http://image.com/test.jpg")

4. 模板方法模式(Template Method Pattern)

定义与作用:
在抽象类中定义算法骨架,把部分实现延迟到子类。MyBatis的Executor、BaseTypeHandler、Plugin体系等,均采用模板方法。

MyBatis源码示例解读:
比如BaseExecutor定义了SQL执行流程,具体细节由子类实现。

public abstract class BaseExecutor implements Executor {
    public <E> List<E> query(...) {
        // 通用流程
        ...
        // 留给子类
        doQuery(...);
    }
    protected abstract <E> List<E> doQuery(...);
}

原理:

  • o 复用主流程,灵活定制局部行为。

移动端实战举例(Swift/Kotlin):
如自定义视图、网络请求、数据解析等通用流程的定制点。

class BaseRefreshController {
    func refresh() {
        fetchData()
        reloadUI()
    }
    func fetchData() { fatalError("Must override") }
    func reloadUI() { fatalError("Must override") }
}
class UserRefreshController: BaseRefreshController {
    override func fetchData() { print("拉取用户数据") }
    override func reloadUI() { print("刷新用户页面") }
}
abstract class BaseRefreshController {
    fun refresh() {
        fetchData()
        reloadUI()
    }
    abstract fun fetchData()
    abstract fun reloadUI()
}
class UserRefreshController : BaseRefreshController() {
    override fun fetchData() = println("拉取用户数据")
    override fun reloadUI() = println("刷新用户页面")
}

5. 观察者模式(Observer Pattern)

定义与作用:
对象之间一对多依赖关系,被观察者状态变化,自动通知所有观察者。MyBatis中的事件监听(Configuration、Plugin、PluginChain)、一级缓存失效等,均用到了观察者。

MyBatis源码示例解读:

public class Configuration {
    private List<ConfigurationObserver> observers = new ArrayList<>();
    public void addObserver(ConfigurationObserver obs) { observers.add(obs); }
    public void notifyObservers() { for (o : observers) o.update(); }
}

移动端实战举例(Swift/Kotlin):
典型如App消息通知、数据源变化、状态监听等。

protocol Observer { func update() }
class Subject {
    private var observers = [Observer]()
    func add(observer: Observer) { observers.append(observer) }
    func notify() { observers.forEach { $0.update() } }
}
class Logger: Observer {
    func update() { print("配置变化,日志记录!") }
}
let subject = Subject()
let logger = Logger()
subject.add(observer: logger)
subject.notify()
interface Observer { fun update() }
class Subject {
    private val observers = mutableListOf<Observer>()
    fun add(observer: Observer) { observers.add(observer) }
    fun notifyAll() { observers.forEach { it.update() } }
}
class Logger : Observer {
    override fun update() { println("配置变化,日志记录!") }
}
val subject = Subject()
val logger = Logger()
subject.add(logger)
subject.notifyAll()

---

## 6. 策略模式(Strategy Pattern)

**定义与作用:**
定义一系列算法,将每种算法分别封装起来,让它们可以互换。MyBatis在类型处理器(TypeHandler)、SQL执行器(Executor)、参数解析器等均用到策略模式。

**MyBatis源码示例解读:**
```java
// 以TypeHandler为例
public interface TypeHandler<T> {
    void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType);
    T getResult(ResultSet rs, String columnName);
}

public class IntegerTypeHandler implements TypeHandler<Integer> { ... }
public class StringTypeHandler implements TypeHandler<String> { ... }

在运行时由TypeHandlerRegistry自动选择合适的TypeHandler进行数据转换。

移动端实战举例(Swift/Kotlin):
如支付方式切换、图片压缩算法切换等。

protocol PaymentStrategy { func pay(amount: Double) }
class WeChatPay: PaymentStrategy { func pay(amount: Double) { print("微信支付\(amount)") } }
class Alipay: PaymentStrategy { func pay(amount: Double) { print("支付宝支付\(amount)") } }

class PaymentContext {
    private var strategy: PaymentStrategy
    init(strategy: PaymentStrategy) { self.strategy = strategy }
    func setStrategy(_ s: PaymentStrategy) { self.strategy = s }
    func execute(amount: Double) { strategy.pay(amount: amount) }
}
let ctx = PaymentContext(strategy: WeChatPay())
ctx.execute(amount: 100)
ctx.setStrategy(Alipay())
ctx.execute(amount: 200)
interface PaymentStrategy { fun pay(amount: Double) }
class WeChatPay : PaymentStrategy { override fun pay(amount: Double) { println("微信支付$amount") } }
class Alipay : PaymentStrategy { override fun pay(amount: Double) { println("支付宝支付$amount") } }

class PaymentContext(private var strategy: PaymentStrategy) {
    fun setStrategy(s: PaymentStrategy) { strategy = s }
    fun execute(amount: Double) = strategy.pay(amount)
}
val ctx = PaymentContext(WeChatPay())
ctx.execute(100.0)
ctx.setStrategy(Alipay())
ctx.execute(200.0)

7. 责任链模式(Chain of Responsibility Pattern)

定义与作用:
将处理请求的对象串成链,沿着责任链传递请求,直到有对象处理它为止。MyBatis中的Plugin拦截器体系、配置解析等场景大量应用。

MyBatis源码示例解读:

public interface Interceptor {
    Object intercept(Invocation invocation) throws Throwable;
}
public class PluginChain {
    private List<Interceptor> interceptors;
    public Object proceed(Invocation inv) throws Throwable {
        for (Interceptor i : interceptors) { inv = i.intercept(inv); }
        return inv.proceed();
    }
}

移动端实战举例(Swift/Kotlin):
如UI事件分发、数据校验、网络请求拦截链等。

protocol Handler {
    var next: Handler? { get set }
    func handle(request: String)
}
class LoggingHandler: Handler {
    var next: Handler?
    func handle(request: String) {
        print("记录日志: \(request)")
        next?.handle(request: request)
    }
}
class AuthHandler: Handler {
    var next: Handler?
    func handle(request: String) {
        if request == "Auth" { print("认证通过") }
        next?.handle(request: request)
    }
}
let log = LoggingHandler()
let auth = AuthHandler()
log.next = auth
log.handle(request: "Auth")
interface Handler {
    var next: Handler?
    fun handle(request: String)
}
class LoggingHandler : Handler {
    override var next: Handler? = null
    override fun handle(request: String) {
        println("记录日志: $request")
        next?.handle(request)
    }
}
class AuthHandler : Handler {
    override var next: Handler? = null
    override fun handle(request: String) {
        if (request == "Auth") println("认证通过")
        next?.handle(request)
    }
}
val log = LoggingHandler()
val auth = AuthHandler()
log.next = auth
log.handle("Auth")

8. 建造者模式(Builder Pattern)

定义与作用:
将复杂对象的构建过程与表示分离,同样的构建过程可生成不同表示。MyBatis的Configuration、XML解析器、MappedStatement、SqlSessionFactoryBuilder等均使用建造者模式。

MyBatis源码示例解读:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);

移动端实战举例(Swift/Kotlin):
如链式创建UI组件、网络请求参数等。

class AlertBuilder {
    private var title: String?
    private var message: String?
    func setTitle(_ title: String) -> AlertBuilder { self.title = title; return self }
    func setMessage(_ msg: String) -> AlertBuilder { self.message = msg; return self }
    func build() -> AlertController { AlertController(title: title, message: message) }
}
let alert = AlertBuilder().setTitle("警告").setMessage("操作失败").build()
class AlertBuilder {
    private var title: String? = null
    private var message: String? = null
    fun setTitle(title: String) = apply { this.title = title }
    fun setMessage(message: String) = apply { this.message = message }
    fun build() = AlertDialog.Builder(context)
        .setTitle(title)
        .setMessage(message)
        .create()
}
val alert = AlertBuilder().setTitle("警告").setMessage("操作失败").build()

9. 装饰器模式(Decorator Pattern)

定义与作用:
动态地给对象添加职责。MyBatis的插件体系、SQL日志、性能监控等应用了装饰器模式。

MyBatis源码示例解读:
比如在Executor外层不断叠加插件,形成责任链。

public class ExecutorPlugin implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
        // do logging, timing, etc.
        return invocation.proceed();
    }
}

移动端实战举例(Swift/Kotlin):
如View修饰、网络请求日志、缓存层装饰等。

protocol ImageFetcher { func fetch(url: String) }
class RealFetcher: ImageFetcher { func fetch(url: String) { print("Fetch \(url)") } }
class LoggingFetcher: ImageFetcher {
    private let inner: ImageFetcher
    init(inner: ImageFetcher) { self.inner = inner }
    func fetch(url: String) {
        print("日志装饰")
        inner.fetch(url: url)
    }
}
let fetcher = LoggingFetcher(inner: RealFetcher())
fetcher.fetch(url: "http://img.com")
interface ImageFetcher { fun fetch(url: String) }
class RealFetcher : ImageFetcher { override fun fetch(url: String) { println("Fetch $url") } }
class LoggingFetcher(private val inner: ImageFetcher) : ImageFetcher {
    override fun fetch(url: String) {
        println("日志装饰")
        inner.fetch(url)
    }
}
val fetcher: ImageFetcher = LoggingFetcher(RealFetcher())
fetcher.fetch("http://img.com")

10. 桥接模式(Bridge Pattern)

定义与作用:
将抽象与实现分离,使两者可以独立扩展。MyBatis类型处理器体系、数据源体系都体现了桥接思想。

MyBatis源码示例解读:
比如TypeHandler和JdbcType解耦。

public interface TypeHandler<T> { ... }
public class IntegerTypeHandler implements TypeHandler<Integer> { ... }

移动端实战举例(Swift/Kotlin):
如视图与渲染引擎解耦、跨平台UI适配等。

protocol Renderer { func render(text: String) }
class MacRenderer: Renderer { func render(text: String) { print("Mac渲染:\(text)") } }
class iOSRenderer: Renderer { func render(text: String) { print("iOS渲染:\(text)") } }
class Label {
    var renderer: Renderer
    init(renderer: Renderer) { self.renderer = renderer }
    func display(text: String) { renderer.render(text: text) }
}
let label = Label(renderer: iOSRenderer())
label.display(text: "Hello")
label.renderer = MacRenderer()
label.display(text: "World")
interface Renderer { fun render(text: String) }
class AndroidRenderer : Renderer { override fun render(text: String) { println("Android渲染:$text") } }
class DesktopRenderer : Renderer { override fun render(text: String) { println("Desktop渲染:$text") } }
class Label(var renderer: Renderer) {
    fun display(text: String) = renderer.render(text)
}
val label = Label(AndroidRenderer())
label.display("Hello")
label.renderer = DesktopRenderer()
label.display("World")

总结

MyBatis之所以能够在大规模业务系统中保持高效、灵活和可扩展性,正是因为其巧妙地融合了多种设计模式。这些模式无论在服务端还是移动端,都有极强的通用性。对于移动端开发者,深入理解这些经典设计模式,可以大大提升架构思维、代码复用和团队协作能力。


相关推荐

土豪农村建个别墅不新鲜 建个车库都用框架结构?

农村建房子过去都是没车库,也没有那么多豪车,一般直接停在路边或者院子里。现在很多人都会在建房子的时候留一个车库,通过车库可以直接进入客厅,省得雨雪天气折腾。农村土豪都是有钱任性,建房子跟我们普通人不一...

自建框架结构出现裂缝怎么回事?

三层自建房梁底与墙体连接处裂缝是结构问题吗?去前帮我姑画了一份三层自建房的图纸,前天他们全部装修好了。我姑丈突然打电话给我说他发现二层的梁底与墙分离了,有裂缝。也就是图纸中前面8.3米那跨梁与墙体衔接...

钢结构三维图集-框架结构(钢柱对接)

1、实腹式钢柱对接说明1:1.上节钢柱的安装吊点设置在钢柱的上部,利用四个吊点进行吊装;2.吊装前,下节钢柱顶面和本节钢柱底面的渣土和浮锈要清除干净,保证上下节钢柱对接面接触顶紧;3.钢柱吊装到位后...

三层框架结构主体自建房设计案例!布局13*12米占地面积156平米!

绘创意设计乡村好房子设计小编今日头条带来分享一款:三层框架结构主体自建房设计案例!布局13*12米占地面积156平米!本案例设计亮点:这是一款三层新中式框架结构自建房,占地13×12米,户型占地面积...

Casemaker机箱框架结构3D图纸 STEP格式

农村自建房新宠!半框架结构凭啥这么火?内行人揭开3个扎心真相

回老家闲逛,竟发现个有意思的现象:村里盖新房,十家有八家都选了"半框架结构"。隔壁王叔家那栋刚封顶的二层小楼,外墙红砖还露着糙面没勾缝,里头的水泥柱子倒先支棱得笔直,这到底是啥讲究?蹲...

砖混结构与框架结构!究竟有何区别?千万别被坑!

农村自建房选结构,砖混省钱但出事真能保命吗?7月建材价格波动期,多地建房户因安全焦虑陷入选择困境——框架结构虽贵30%,却是地震区保命的关键。框架柱和梁组成的承重体系,受力分散得像一张网。砖混靠墙硬扛...

砖混结构与框架结构,究竟有何区别?千万别被坑!

农村建房选砖混结构还是框架结构?这个问题算是近期留言板里问得最多的问题了。今天咱们说说二者的区别,帮您选个合适的。01成本区别假如盖一栋砖混结构的房子需要30万,那么换成框架结构,一般要多掏30%的费...

6个小众却逆天的App神器,个个都是黑科技的代表

你的手机上有哪些好用的软件?今天我就给大家分享6个小众却逆天的App神器,个个都是黑科技的代表!01*Via浏览器推荐理由:体积极小的浏览器,没有任何广告。使用感受:它的体量真的很小,只有702KB,...

合肥App开发做一个app需要多少钱?制作周期有多久?

在移动互联网时代,开发一款APP已成为企业数字化转型与个人创业的重要途径。然而,APP的开发成本与制作周期受功能复杂度、技术架构、团队类型等多重因素影响,差异极大。好牛软件将从这两个维度展开分析,帮助...

详解应对App臃肿化的五大法则

编者注:本文转自腾讯ISUX。先来看一张图:图上看到,所有平台上用户花费时间都在减少,除了移动端。观察身边也是如此,回家不开电脑的小伙伴越来越多。手机平板加电视,下班场景全搞定。连那些以前电脑苦手的...

实战!如何从零搭建10万级 QPS 大流量、高并发优惠券系统

需求背景春节活动中,多个业务方都有发放优惠券的需求,且对发券的QPS量级有明确的需求。所有的优惠券发放、核销、查询都需要一个新系统来承载。因此,我们需要设计、开发一个能够支持十万级QPS的券系...

8种移动APP导航设计模式大对比

当我们确定了移动APP的设计需求和APP产品设计流程之后,开始着手设计APP界面UI或是APP原型图啦。这个时候我们都要面临的第一个问题就是如何将信息以最优的方式组合起来?也许我们对比和了解了其他一些...

数字资产支付 App 的技术框架

开发一款功能强大、安全可靠的数字资产支付App需要一个整合了区块链技术、后端服务、前端应用以及第三方集成的全栈技术框架。这个框架的核心在于保障数字资产的安全流通,并将其高效地桥接到传统的法币支付场...

从MyBatis到App架构:设计模式全景应用指南

从MyBatis到App架构:设计模式全景应用指南引言在企业级应用和服务端开发领域,MyBatis凭借其灵活、简洁、强大的ORM映射能力被广泛应用。而它之所以能拥有如此优秀的可扩展性和工程可维护性,正...

取消回复欢迎 发表评论: