你该拥有自己的一套项目结构----Kotlin+Dagger2+MVP+Rx+Retrofit

2023-12-21 05:08

本文主要是介绍你该拥有自己的一套项目结构----Kotlin+Dagger2+MVP+Rx+Retrofit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

架构是什么?框架是什么?
其实很简单,一句话:框架是软件,架构不是软件。框架落脚在“架”字上,可以理解成名词性的,是一个客观性的名词存在,如.Net Framework;而架构体现在“构”字上,理解成构造,是一个动词性的,是一系列动作发生的策略性体现。先大局后局部,就出现了架构;先通用后专用,就出现了框架。
让我这个菜鸟LOL玩家看来:架构就是LOL里面的一套打法、战术,框架则是精确到QWER+走位。

1.以前不懂得架构思想的我,拿到一个项目之后,囫囵吞枣的按照需求文档,也能“有模有样”的按时提交成果。这样直接导致的后果就是,很怕leader又要改改改,加加加。
2.当然网上有很多优秀的架构,别人的东西不是百分百适合自己的项目,所以要结合理解,搭建出属于自己熟悉的一套架构。随着经验的增长,从而不断的完善自己的那一套。
3.本文难点不大,高手勿喷,欢迎指点。希望起到抛砖迎玉的作用,让每个开发者都有自己熟悉的一套架构。


源码:https://github.com/KomoriWu/Http.git

目录

一、MVP 设计模式
二、网络请求框架(Rx+Retrofit )
三、Kotlin
四、Dagger2

此文不在讲述一、二 请看 上一篇博文
http://blog.csdn.net/sinat_27033869/article/details/66972339

二、网络请求框架(Rx+Retrofit )

其中相比上一次,我把网络请求的框架完全提取出来,直接无脑使用就行。
Android studio 导入方法:
第一步:

allprojects {repositories {...maven { url 'https://jitpack.io' }}}

第二步:

dependencies {compile 'com.github.KomoriWu:Http:v1.0.0'}

在项目中的调用
//这里框架我之前是用Java语言写的,demo中的调用我用的Kotlin。之后我会响应号召,把网络请求的框架也改为Kotlin
1.这里写图片描述
调用者只需编写两个简单的类即可。


public class ArticleApi extends BaseApi {private String mPage;private String mSize;public ArticleApi(RxAppCompatActivity rxAppCompatActivity, String page, String size,HttpOnNextListener listener) {super(rxAppCompatActivity, listener,BASE_URL);this.mPage = page;this.mSize = size;//是否显示加载框setShowProgress(false);}//提供请求所需字段的数据@Overridepublic Observable getObservable(Retrofit retrofit) {Map<String, String> map = new HashMap<>();map.put("page", mPage);map.put("size", mSize);HttpService service = retrofit.create(HttpService.class);return service.getAllArticles(map);//传数据到HttpService}
}
public interface HttpService {@GET(GET_ALL_ARTICLES)Observable<ArticleBody> getAllArticles(@QueryMap Map<String, String> map);
}

在程序中调用:

 val articleApi: ArticleApi = ArticleApi(context as RxAppCompatActivity, page, size, object :HttpOnNextListener<ArticleBody>() {override fun onNext(t: ArticleBody?) {onLoadListListener.onSuccess(t);}override fun onError(e: Throwable?) {onLoadListListener.onFail(e);}})HttpManager.getInstance().doHttpDeal(articleApi)

十分清爽,无脑使用。实现原理可以看我上一篇博客,这里只是交大家如何使用。结合demo看,效果更佳。

三、kotlin

Demo中的代码大家可以发现,既有Java 也有 Kotlin。的确100%融合,有些地方用Kotlin省心很多。
kotlin是什么?多的话我不说,早学晚学都要学。以后找Android,不会这个,估计就被挤下去了。
刚开始接触kotlin时,十分惧怕,看网上博客一脸懵逼。很难吗?其实不然,大家只要搞懂几个关键点,之后写代码,多使用官方API文档。上手还是很快的。

1.配置
第一种:as在3.0以下的需要安装插件:
Android Studio的Kotlin插件, 用于支持Kotlin的语言特性.
选择: Preferences -> Plugins -> Install JetBrains plugin -> kotlin.

第二种:也是我极力推荐的,将as升级到3.0,一切省心省事,3.0的版本优化很大,完全支持kotlin。

2.添加依赖

 compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"compile 'org.jetbrains.anko:anko-sdk15:0.8.3'

//快捷键:选择Code -> Convert Java File to Kotlin File, 更好的学习kotlin

Kotlin API 入门
1. 变量

⼀次赋值(只读)的局部变量:

val a: Int = 1 // ⽴即赋值
val b = 2 // ⾃动推断出 `Int` 类型
val c: Int // 如果没有初始值类型不能省略
c = 3 // 明确赋值

可变变量:

var x = 5 // ⾃动推断出 `Int` 类型
x += 1

当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引⽤可为空。
如果 str 的内容不是数字返回 null

2.条件
在 Kotlin 中,if是⼀个表达式,即它会返回⼀个值。 因此就不需要三元运算符(条件 ? 然后 : 否则),因为普通的 if 就能胜任这个⻆⾊

// 传统⽤法
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b

if的分⽀可以是代码块,最后的表达式作为该块的值:

val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}

如果你使⽤ if 作为表达式⽽不是语句(例如:返回它的值或者 把它赋给变量),该表达式需要有 else 分⽀。

3.循环
when 取代了类 C 语⾔的 switch 操作符。其最简单的形式如下:

when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}

如果很多分⽀需要⽤相同的⽅式处理,则可以把多个分⽀条件放在⼀起,⽤逗号分隔:

when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}

我们可以⽤任意表达式(⽽不只是常量)作为分⽀条件

when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}

我们也可以检测⼀个值在(in)或者不在(!in)⼀个区间或者集合中:

when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}

For 循环
for 循环可以对任何提供迭代器(iterator)的对象进⾏遍历,语法如下:

for (item in collection) print(item)

如果你想要通过索引遍历⼀个数组或者⼀个 list,你可以这么做

for (i in array.indices) {
print(array[i])
}

4.函数
定义函数:带有两个 Int 参数、返回 Int 的函数:
fun+方法名+参数(参数名:类型)+返回类型(可以不写,自动判断。返回为空可省略)

fun sum(a: Int, b: Int): Int {
return a + b
}

将表达式作为函数体、返回值类型⾃动推断的函数:

fun sum(a: Int, b: Int) = a + b

函数返回⽆意义的值:

fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}

Unit 返回类型可以省略
//以上为Kotlin一些基础语法,简单易上手,有了这些看懂demo无压力

四、Dagger2在MVP中的使用

Dagger2:Dagger2现在由Google接手维护。是一个依赖注入的框架。
依赖注入:是面向对象编程的一种设计模式,其目的是为了降低程序耦合,这个耦合就是类之间的依赖引起的。
网上关于Dagger2的文章太多,比较后推荐这篇:
http://www.open-open.com/lib/view/open1482201981550.html


具体项目中我们如何使用呢?
先来看Demo的MVP+Dagger2的项目结构:
这里写图片描述
可能你觉得分包太多,但是实际层次更分明,结构更简单。日后维护、迭代再也不怕了。
MVP中的model :网络数据请求

class ArticleModelImpl : ArticleModel {override fun loaderArticle(context: Context, page: String, size: String,onLoadListListener: OnLoadListListener) {val articleApi: ArticleApi = ArticleApi(context as RxAppCompatActivity, page, size, object :HttpOnNextListener<ArticleBody>() {override fun onNext(t: ArticleBody?) {onLoadListListener.onSuccess(t);}override fun onError(e: Throwable?) {onLoadListListener.onFail(e);}})//采用已经封装完毕的RX+Retrofit框架HttpManager.getInstance().doHttpDeal(articleApi)}interface OnLoadListListener {fun onSuccess(t: ArticleBody?)fun onFail(e: Throwable?)}
}

MVP中的View :将Model中得到的数据传给activity显示出来

interface ArticleView {fun addArticleList(articleBody: ArticleBody?)
}

MVP中的Presenter :中间体。将model与view连接起来

class ArticlePresenterImpl(private var mContext: Context,private var mArticleView: ArticleView) :ArticlePresenter, ArticleModelImpl.OnLoadListListener {private var mArticleModel: ArticleModel? = nullinit {mArticleModel = ArticleModelImpl()}override fun loaderArticle(page: String, size: String) {mArticleModel?.loaderArticle(mContext, page, size, this)}override fun onSuccess(t: ArticleBody?) {mArticleView.addArticleList(t)}override fun onFail(e: Throwable?) {}}

activity中的调用:
常规调用为:

 lateinit var mArticlePresenter: ArticlePresenter
mArticlePresenter = ArticlePresenterImpl(this, this)     mArticlePresenter?.loaderArticle("1", "8")

结合Dagger2

1.Module :生成依赖对象。@Module就是用来标准这个类的,而@Provide则是用来标注具体提供依赖对象的方法。由@Module 与@Provides 完成。提供数据。
我们这里提供数据的类是ArticlePresenterImpl

@Module
class ArticleModule(private var mContext: Context,private var mArticleView: ArticleView) {@Providesfun providePresenter(): ArticlePresenter {return ArticlePresenterImpl(mContext, mArticleView)}
}

2.Component:是依赖需求方和依赖提供方之间的桥梁。
Dagger2提供依赖的是ArticleModule这个类。
Dagger2得到依赖的是MainActivity

@Component(modules = arrayOf(ArticleModule::class))
interface ArticleComponent {fun inject(mainActivity: MainActivity)
}

3.依赖需求方:在activity中的调用。
完成这些之后我们需要Build下项目,让Dagger2帮我们生成相关的Java类。接着我们就可以在activity中调用Dagger2生成的DaggerArticleComponent来实现注入

 @Injectlateinit var mArticlePresenter: ArticlePresenter
  DaggerArticleComponent.builder().articleModule(ArticleModule(this, this)).build().inject(this)mArticlePresenter.loaderArticle("1", "8")

下载demo学习更佳,欢迎start:
https://github.com/KomoriWu/Http.git

这篇关于你该拥有自己的一套项目结构----Kotlin+Dagger2+MVP+Rx+Retrofit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

SpringBoot项目是如何启动

启动步骤 概念 运行main方法,初始化SpringApplication 从spring.factories读取listener ApplicationContentInitializer运行run方法读取环境变量,配置信息创建SpringApplication上下文预初始化上下文,将启动类作为配置类进行读取调用 refresh 加载 IOC容器,加载所有的自动配置类,创建容器在这个过程

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

2. 下载rknn-toolkit2项目

官网链接: https://github.com/airockchip/rknn-toolkit2 安装好git:[[1. Git的安装]] 下载项目: git clone https://github.com/airockchip/rknn-toolkit2.git 或者直接去github下载压缩文件,解压即可。