Android常用设计模式总结-待续

2024-05-24 04:32

本文主要是介绍Android常用设计模式总结-待续,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

设计模式总结

1.面向对象的六大原则:

1.1 解决类的耦合性:单一职责
定义:就一个类而言,应该只有一个职责。如果一个类有一个以上的职责,这些职责就耦合在了一起。
当一个职责发生变化时,可能会影响其它的职责。
原则:遵守单一职责原则,将不同的职责封装到不同的类或模块中。

1.2 解决程序可扩展性:开闭原则
定义:软件中的对象(类,模块,函数等等)对于扩展是开放的,对于修改是封闭的。
原则:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

1.3 解决程序的灵活性:里氏替换
核心原理是抽象。
定义:任何基类可以出现的地方,子类一定可以出现。子类可以扩展父类的功能,但不能改变父类原有的功能。
原则:
1、子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法
2、子类中可以增加自己特有的方法
3、当子类重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松
4、当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等

1.4 解决程序稳定性:依赖倒置
其核心思想是:要面向接口编程,不要面向实现编程。
依赖倒置原则可以降低类间的耦合性。
依赖倒置原则可以提高系统的稳定性。
依赖倒置原则可以减少并行开发引起的风险。
依赖倒置原则可以提高代码的可读性和可维护性。
定义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
原则:
每个类尽量提供接口或抽象类,或者两者都具备。
变量的声明类型尽量是接口或者是抽象类。
任何类都不应该从具体类派生。
使用继承时尽量遵循里氏替换原则。

1.5 解决接口的耦合性:接口隔离
提高类的内聚性、降低它们之间的耦合性 
定义:一个类对另一个类的依赖应该建立在最小的接口上。
要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
原则:
接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑。
提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

1.6 解决程序模块之间相对独立:迪米特法则
定义:
只与你的直接朋友交谈,不跟“陌生人”说话。
如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
降低了类之间的耦合度,提高了模块的相对独立性。由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

原则:
从依赖者的角度来说,只依赖应该依赖的对象。
从被依赖者的角度说,只暴露应该暴露的方法。

在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
在类的结构设计上,尽量降低类成员的访问权限。
在类的设计上,优先考虑将一个类设置成不变类。
在对其他类的引用上,将引用其他对象的次数降到最低。
不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。
谨慎使用序列化(Serializable)功能。

2.单例模式具有以下几个优点:

1)在内存中只有一个对象,节省内存空间;
2)避免频繁的创建销毁对象,可以提高性能;
3)避免对共享资源的多重占用,简化访问;
4)为整个系统提供一个全局访问点。

场景:
需要频繁的进行创建和销毁的对象;
创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
工具类对象;
频繁访问数据库或文件的对象。

饿汉式:简单来说就是空间换时间,因为上来就实例化一个对象,占用了内存,(也不管你用不用)。绝对线程安全,立即加载。
(由于一个类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例)
场景:试用于创建对象次数多的场景。
//饿汉式单例
public class Singleton1 {
 
    // 指向自己实例的私有静态引用,主动创建
    private static Singleton1 singleton1 = new Singleton1();
 
    // 私有的构造方法
    private Singleton1(){}
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton1 getSingleton1(){
        return singleton1;
    }
}

懒汉式:简单来说就是时间换空间,于饿汉式正好相反。传统式的懒汉式单例是非线程安全的,延时加载。
场景:试用于创建对象次数少的场景。
// 懒汉式单例,非线程安全的
public class Singleton2 {
 
    // 指向自己实例的私有静态引用
    private static Singleton2 singleton2;
 
    // 私有的构造方法
    private Singleton2(){}
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton2 getSingleton2(){
        // 被动创建,在真正需要使用时才去创建
        if (singleton2 == null) {
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}

推荐试用:
// 线程安全的懒汉式单例
同步延迟加载 — 使用内部类实现延迟加载
public class Singleton5 {
 
    // 私有内部类,按需加载,用时加载,也就是延迟加载
    private static class Holder {
        private static Singleton5 singleton5 = new Singleton5();
    }
    // 私有的构造方法
    private Singleton5() {}
 
    public static Singleton5 getSingleton5() {
        return Holder.singleton5;
    }
}
/* Output(完全一致)

双重检测同步延迟加载
public class Singleton3 {
 
    //使用volatile关键字防止重排序,因为 new Instance()是一个非原子操作,可能创建一个不完整的实例
    private static volatile Singleton3 singleton3;
     // 私有的构造方法
    private Singleton3() {}
 
    public static Singleton3 getSingleton3() {
        // Double-Check idiom
        if (singleton3 == null) {
            synchronized (Singleton3.class) {  
                // 只需在第一次创建实例时才同步
                if (singleton3 == null) {      
                    singleton3 = new Singleton3();
                }
            }
        }
        return singleton3;
    }
}/* Output(完全一致)

可以看到在getInstance3()方法里面,先判断当前实例是否为空,然后进入同步处理后又判断一次实例是否为空。前后两次判断校验了两次。这个就是双重校验

去掉第一个判断为空:即懒汉式(线程安全),这会导致所有线程在调用getInstance()方法的时候,不管三七二十一就直接排队等待同步锁,然后等到排到自己的时候进入同步处理时,才去校验实例是否为空,这样子做会耗费很多时间(即线程安全,但效率低下)。

去掉第二个判断为空:即懒汉式(线程不安全),这会出现 线程A先执行了getInstance()方法,同时线程B在因为同步锁而在外面等待,等到A线程已经创建出来一个实例出来并且执行完同步处理后,B线程将获得锁并进入同步代码,如果这时B线程不去判断是否已经有一个实例了,然后直接再new一个。这时就会有两个实例对象,即破坏了设计的初衷。(即线程不安全,效率高)

双重校验的目的:除了第一次实例化需要进行加锁同步,之后的线程只要进行第一层的if判断不为空即可直接返回,而不用每一次获取单例都加锁同步,因此相比前面两种懒汉式,双重检验锁更佳。(双重校验锁结合了 两种懒汉式 的优点)

3.MVVM:
https://www.cnblogs.com/loaderman/p/10076529.html
View: Activty/fragemnt,实际是View成还包括ViewDataBinding.
ViewModel:作为Activity/Fragment与其他组件的连接器。
负责转换和聚合Model中返回的数据,使这些数据易于显示,并把这些数据改变及时的通知给Activity/Fragment。
ViewModel是具有生命周期意识的,当Activity/Fragment销毁时ViewModel的onClear方法会被回调,你可以在这里做一些清理工作。
LiveData是具有生命周期意识的一个可观察的的数据持有者,ViewModel中的数据由LiveData持有,并且只有当Activity/Fragment处于活动时才会通知UI数据的改变,避免无用的刷新UI;
Model
Repository及其下方就是Model了。Repository负责提取和处理数据。数据可以来自本地数据库(Room),也可以来自网络,这些数据统一有Repository处理,对应隐藏数据来源及获取方式
Binder 绑定器
Android中的数据绑定技术由DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时(由LiveData自动通知数据的改变),将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新,而不用书写类似setText的方法。

MVVM与MVC最大的区别就是:MVVM实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用d再自己手动操作来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。

这篇关于Android常用设计模式总结-待续的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/997372

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的