组件化开发:基于可重用目的的应用拆分与独立组件构建

2024-12-09 0 253

单工程深入挖掘,项目规模不断扩张,问题也逐渐显现。这时,或许应当考虑进行模块化改革。这样的转变是众多开发者共同经历的,其中既有机遇也有挑战。

为什么要开始组件化

单独进行工程开发,一旦项目规模扩大,麻烦随之增多。比如某家公司,起初为了迅速推出项目,选择了单一工程模式,但随着时间的推移,每次对功能进行微调,都需要在庞大的工程中费时寻找,极大地影响了开发速度。在开发过程中,累积的代码容易导致混乱。这就像一个杂乱无章的储藏室,东西随意堆放,需要用时难以寻觅。

项目在单一工程模式中运行时间过长,代码的维护难度极大。我的一位朋友就遇到过这样的情况,新加入的开发人员要花很多时间去理解那些老旧的代码。在这种情况下,采用组件化设计似乎是一条可行的道路。

模块化与组件化辨析

模块

程序被按照功能划分成了模块。例如,社交软件中的登录模块,它主要负责用户登录系统的验证和互动。而首页模块,就像商场的前窗,主要用来展示各类信息。这两个模块功能清晰,且互不干扰。这种拆分使得每个模块都能各尽其责。

组件

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件的功能趋向单一化。比如视频应用中的视频模块,主要聚焦于视频播放的各个环节。而支付模块则独立处理支付的安全性和流程问题。此外,这些组件可以独立进行开发,就像小型工作室那样闭门造车,完成后再对外发布成SDK。通常,一个模块中会包含一个或多个这样的组件。

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件化的好处

减少耦合性

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件化的主要好处在于它以可重复利用为核心,减少了相互依赖。在众多大型项目中,一处变动往往会导致全局动摇。然而,在实施组件化之后,各个组件之间相对独立。比如我参与过的那个办公软件项目,在应用了组件化之后,当我们需要对某个业务逻辑进行修改时,只需对相应的组件进行调整,对其他部分的干扰极小。

独立开发

不同的开发团队或个人可以并行开展不同模块的开发工作,这显著提升了开发效率。例如,一些规模较大的团队会按模块划分,分别专注于用户界面交互模块,以及数据处理模块。

//构建后输出一个 APK 安装包
apply plugin: 'com.android.application'
//构建后输出 ARR 包
apply plugin: 'com.android.library'
//配置一个 Android Test 工程
apply plugin: 'com.android.test'

组件化要面临的问题

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件间的依赖关系

//注意gradle.properties中的数据类型都是String类型,使用其他数据类型需要自行转换
if(isDebug.toBoolean()){
    //构建后输出一个 APK 安装包
    apply plugin: 'com.android.application'
}else{
    //构建后输出 ARR 包
    apply plugin: 'com.android.library'
}

在组件的层级结构中,上层组件对下层组件有依赖,同时上层的修改次数较多,这种情况带来了一定的风险。若上层组件频繁变动,下层组件便需作出相应的调整。以一个电商App的组件化改造项目为例,前端界面这一上层组件变动频繁,这就要求底层数据处理组件持续调整接口以实现适配。

项目结构混乱的风险

若组件界限模糊,会使项目架构变得更加杂乱无章。就像刚开始学习拼图,若拼块放置错误,拼图时便会出现多处不匹配的情况。

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件分层的具体策略

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scc.module.collect">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SccMall">
        <activity android:name=".CollectActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

合理划分基础组件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scc.module.collect">
    <application
        android:allowBackup="true"
        android:supportsRtl="true"
        >
        <activity android:name=".CollectActivity"/>
    </application>
</manifest>

项目若因基础组件过多而显得庞大,不妨另设一个层级,并在其中进一步划分这些基础组件。我的同事在处理项目时就采取了这种做法,之前基础组件杂乱无章,后来经过清晰分层,开发效率显著提升。

构建类型的动态配置

    defaultConfig {
        if(isDebug.toBoolean()){
            //独立调试的时候才能设置applicationId
            applicationId "com.scc.module.collect"
        }
    }
    sourceSets {
        main {
            if (isDebug.toBoolean()) {
                //独立调试
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                //集成调试
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

工程类型构建

在项目开发过程中,我们需借助相应工具进行搭建,例如在Android开发中采用Gradle,同时还有众多插件可供选择。这些插件用于构建各式各样的工程。这一流程颇似厨师烹饪时选用不同的厨具。

动态配置build文件

组件化开发:基于可重用目的的应用拆分与独立组件构建

与创建插件相似,构建文件同样需要灵活调整。这在组件化开发中尤为关键。就好比建筑师根据不同的建筑要求来修改图纸。

组件化开发:基于可重用目的的应用拆分与独立组件构建

组件化的最终效果

独立调试

组件化开发:基于可重用目的的应用拆分与独立组件构建

升级插件或依赖库版本时,若项目众多,修改起来颇为棘手。采用组件化设计后,每个组件可独立调试。这就像为每个组件配备了一个独立的小实验室,可以单独进行升级实验,彼此之间互不干扰。

界面跳转解决方案

ext{
    //组件独立调试开关, 每次更改值后要同步工程
    isDebug = true
    android = [
            // 编译 SDK 版本
            compileSdkVersion: 31,
            // 最低兼容 Android 版本
            minSdkVersion    : 21,
            // 最高兼容 Android 版本
            targetSdkVersion : 31,
            // 当前版本编号
            versionCode      : 1,
            // 当前版本信息
            versionName      : "1.0.0"
    ]
    applicationid = [
            app:"com.scc.sccmall",
            main:"com.scc.module.main",
            webview:"com.scc.module.webview",
            login:"com.scc.module.login",
            collect:"com.scc.module.collect"
    ]
    dependencies = [
            "appcompat"         :'androidx.appcompat:appcompat:1.2.0',
            "material"          :'com.google.android.material:material:1.3.0',
            "constraintlayout"  :'androidx.constraintlayout:constraintlayout:2.0.1',
            "livedata"          :'androidx.lifecycle:lifecycle-livedata:2.4.0',
            "viewmodel"         :'androidx.lifecycle:lifecycle-viewmodel:2.4.0',
            "legacyv4"          :'androidx.legacy:legacy-support-v4:1.0.0',
            "splashscreen"      :'androidx.core:core-splashscreen:1.0.0-alpha01'
    ]
    libARouter= 'com.alibaba:arouter-api:1.5.2'
    libARouterCompiler = 'com.alibaba:arouter-compiler:1.5.2'
    libGson = 'com.google.code.gson:gson:2.8.9'
}

界面跳转的困难

apply from:"config.gradle"

在Android系统中,界面切换原本操作简便。然而,由于组件化开发中各组件之间没有依赖关系,无法直接访问类,因此无法继续采用原有的直接跳转方法。

使用ARouter框架解决

//build.gradle
//注意gradle.properties中的数据类型都是String类型,使用其他数据类型需要自行转换
if(isDebug.toBoolean()){
    //构建后输出一个 APK 安装包
    apply plugin: 'com.android.application'
}else{
    //构建后输出 ARR 包
    apply plugin: 'com.android.library'
}
android {
    compileSdkVersion 31
    defaultConfig {
        if(isDebug.toBoolean()){
            //独立调试的时候才能设置applicationId
            applicationId "com.scc.module.collect"
        }
        minSdkVersion 21
        targetSdkVersion 31
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            if (isDebug.toBoolean()) {
                //独立调试
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                //集成调试
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {
//    implementation root.dependencies.appcompat
//    implementation root.dependencies.material
//    implementation root.dependencies.constraintlayout
//    implementation root.dependencies.livedata
//    implementation root.dependencies.viewmodel
//    implementation root.dependencies.legacyv4
//    implementation root.dependencies.splashscreen
//    implementation root.libARouter
    //上面内容在lib_common中已经添加咱们直接依赖lib_common
    implementation project(':lib_common')
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

ARouter能助力App实现组件化升级,实现模块间的路由、通讯及解耦。使用时需先设置依赖,接着初始化SDK,随后即可进行路由操作。以资讯类App为例,应用此框架后,组件间的切换变得非常流畅。

互动环节

我已经将实现单工程转组件化的关键点进行了介绍,大家在实际尝试组件化过程中,面临的最大难题是什么?期待大家为这篇文章点赞并转发,同时也欢迎在评论区留下你们的见解和讨论。

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

七爪网 行业资讯 组件化开发:基于可重用目的的应用拆分与独立组件构建 https://www.7claw.com/2801136.html

七爪网源码交易平台

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务