常见设计模式及应用

233 阅读5分钟

在软件开发工作中,设计出一个好的模型能够有效减少软件项目的开发和维护工作量。在软件行业的发展过程中,对一些典型的场景已经总结出目前最佳的设计模型,像我们熟知的23种设计模式。本文介绍其中一些常见的设计模式和在移动端开发的应用。

1. 创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

1.1 单例模式

当一个软件模型中,某个类的实例只能存在一个的时候,就需要用到单例模式。这种情况其实很普遍,例如我们对一个学校进行软件建模的话,校长只有一个就是单例,而学生可以存在多个实例,不是单例。 实现

1.饿汉式:缺点是类加载的时候就会创建实例,造成不合时宜的内存和CPU资源分配。 2.懒汉式:缺点是线程不安全 3.懒汉式: 获取单例的方法加锁,缺点是不高效,因为多数情况下这个方法的调用不会涉及多线程 4.双重校验锁:线程安全,同时又是延迟加载, 推荐 5.静态内部类:线程安全,同时也是延迟加载,推荐。

应用

  1. kotlin语言 object kotlin语言提供了object关键字,可以让开发者方便地实现单例模式。object的实现原理是静态代码块中创建了实例,和饿汉式原理一致。
// kotlin object关键字实现单例的例子
object Singleton {
    var count: Int = 0

    fun showCount() {
        println("Count: $count")
    }
}

// 把上述代码转成java语言,
// 发现主要的原理就是在静态代码块中创建了实例
public final class Singleton {
    public static final Singleton INSTANCE;
    private int count;

    private Singleton() {
        count = 0;
    }

    public final void showCount() {
        System.out.println("Count: " + count);
    }

    static {
        Singleton var0 = new Singleton();
        INSTANCE = var0;
    }
}

1.2 工厂模式

当创建一个类的实例的逻辑比较复杂的时候,可以考虑用工厂模式把创建实例的逻辑抽离出来。 实现 工厂模式没有特定的具体实现方式,总的思想就是创建一个工厂类负责产品对象的创建。 应用 安卓SDK 图片类Bitmap的创建过程就用到了工厂模式,因为创建Bitmap的方式有多种,可以从文件,流,字节数组创建,并且创建bitmao的过程中过程也很复杂。所以这边把bitmap的创建逻辑独立到BitmapFactory中。

//BitmapFactory.java
   public static Bitmap decodeFile(String pathName) {
        return decodeFile(pathName, null);
    }
    
    public static Bitmap decodeResource(Resources res, int id) {
        return decodeResource(res, id, null);
    }

    public static Bitmap decodeStream(InputStream is) {
        return decodeStream(is, null, null);
    }

1.3 建造者模式

当创建一个对象的过程中有很多属性可以指定,那么可以用建造者模式。建造者模式把设置属性的过程和创建对象的过程都抽离到建造类中。相比于建造者模式,直接在调用对象的类里面创建对象并设置属性,会使得对象创建的过程比较分散,而且这块逻辑耦合到调用类中。同样同比于建造者模式,如果产品类提供不同属性组合的各种构造函数,那么在属性比较多的时候,需要大量的构造函数。 实现 一般会创建一个建造类Buidler, 开发者要创建一个产品对象的时候,先调用Builder设置产品的属性,然后再创建产品对象。 应用实例 安卓SDK中的Dialog就用到了这个创建模式,因为Dialog的属性比较多,有标题,消息,图标,按钮属性等等,所以很适用于建造者模式。

// Dialog源码
public class AlertDialog extends Dialog implements DialogInterface {
    public static class Builder {
            public Builder setTitle(CharSequence title) {
            P.mTitle = title;
            return this;
        }
           public AlertDialog create() {
            // 其他代码
            return dialog;
        }
 }
 
 // Dialog创建方式实例
AlertDialog dialog = new AlertDialog.Builder(context)
        .setTitle("Title")
        .setMessage("Message")
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Do something
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Do something
            }
        })
        .create();
dialog.show();

2. 行为型模式

这些模式关注对象之间的通信和交互,旨在解决对象之间的责任分配

2.1 策略模式

当对一个问题的处理有好几种选择,那么可以考虑使用策略模式。

实现

要实现这种模式,我可以首先定义好通用的接口类,然后定义具体的几种不同实现类,在调用类中根据需要使用合适的实现类。

应用实例

在安卓应用Activity中,经常会接收到各种各样的intent, 不同的intent有不同的处理方法。这个场景可以考虑用策略模式来解决。

classDiagram
IntentProcessor <|-- AIntentProcessor
IntentProcessor <|-- BIntentProcessor
IntentProcessor <|-- CIntentProcessor
IntentProcessor: +process()

2.2 观察者模式

当一个对象的数据更新之后需要通知另外一个对象的时候,可以考虑用观察者模式

应用实例

  1. 安卓jetpack库中的LiveData 在数据变化时会通知UI界面更新。

2.3 责任链模式

当一个长流程比较复杂,可以拆成几个明显的步骤,而且各个步骤之间有确定的先后关系,可以考虑用责任链模式。

应用实例

okhttp进行网络请求的时候使用了责任链模式

graph TD
RetryAndFloowupIntercepter --> BridgeIntercepter --> CacheIntercepter --> ConnectionIntercepter --> RealCallIntercepter

3. 结构型模式

这些模式关注对象之间的组合和关系,旨在解决如何构建灵活且可复用的类和对象结构。

3.1 适配器模式

充当两个不兼容接口之间的桥梁,它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。 通过适配器模式把中间件的接口转成领域层需要的接口。

应用实例

在整洁架构中,经常有防腐层的设计,在防腐层中,需要把基础设施层(中间件,外部SDK)的接口转换为领域层定义的接口,这里可以使用适配器模式来解决问题。