MVC的概念
MVC全称为Model-View-Controller,也就是 模型-视图-控制器。是最常见的一种软件设计模式。
Model:对应的Android中的数据实体模型、数据访问接口、数据库操作等,用于存取数据和处理业务逻辑。
View:对应Android中的布局文件,用来展示UI。
Controller:对应Android中的Activity、Fragment等,用于更新UI界面与数据。
他们之间的关系图(忽略图中的小字部分,只关注三部分即可):
MVC的工作原理是用户在View层触发事件,Controller层接收到View层的事件后就会更新Model层数据,Model层数据改变后就通知Controller层更新UI。(View层也可以直接更新Model层的数据)
本部分借鉴文章:https://www.jianshu.com/p/e48e9158325b
MVC设计模式在代码中的体现(以一个简易的图书管理器为例)
模块逻辑设计图
信息类Book——含有书名和作者的信息
data class Book(val Name:String,val Author:String)
BookDao接口——统一方法
因为数据的获取和保存可能是来自于数据库,也有可能是来自于网络,统一接口也就统一了方法。后方将有模拟数据库的类和模拟网络的类,两个类继承同一个接口,接口中有定义的方法,这两个类就只管具体实现即可。
interface BookDao {
var bookList:MutableList<Book>
fun getBooks():List<Book>
fun addBook(book: Book)
}
定义类BookDaoDbImpl继承于接口BookDao
用于模拟数据库中存储的数据
class BookDaoDbImpl : BookDao {
//模拟数据库中存储的数据
override var bookList: MutableList<Book> = mutableListOf()
override fun getBooks(): List<Book> {
return bookList
}
override fun addBook(book: Book) {
bookList.add(book)
}
}
定义类Database——用于封装BookDaoDbImpl类
此处是利用单例对象对数据库类型进行封装 下方的模拟网络一样的方式,就不再做过多的介绍
至于单例对象的作用,详情可见简书:https://www.jianshu.com/p/93f547293ec3
class Database private constructor(){
val bookDao = BookDaoDbImpl()
companion object{
//被volatile关键字修饰的变量是被禁止重排序的
@Volatile private var instance: Database? = null
fun getInstance() = instance ?: synchronized(this){
instance ?: Database().also { instance = it }
}
}
}
定义类BookDaoNetworkImpl模拟网络数据操作
class BookDaoNetworkImpl: BookDao {
override var bookList: MutableList<Book> = mutableListOf()
override fun getBooks(): List<Book> {
return bookList
}
override fun addBook(book: Book) {
bookList.add(book)
}
}
对类BookDaoNetworkImpl进行封装
class Network private constructor(){
val bookDao = BookDaoNetworkImpl()
companion object{
@Volatile private var instance: Network? = null
fun getInstance() = instance ?: synchronized(this){
instance ?: Network().also { instance = it }
}
}
}
类BookRepository作为数据中心
BookRepository类管理不同的数据类型,增强灵活性。如果只有一种数据类型,这个类就相当鸡肋了,但现实中不可能只操作一种数据类型,所以建立一个数据中心作为中间桥梁还是很有必要的。
class BookRepository private constructor(private val bookDao: BookDao){
companion object{
@Volatile private var instance: BookRepository? = null
fun getInstance(dao: BookDao) = instance ?: synchronized(this){
instance ?: BookRepository(dao).also { instance = it }
}
}
fun getBooks(): List<Book>{
return bookDao.getBooks()
}
fun addBook(book: Book){
bookDao.addBook(book)
}
}
静态类 ProvideRepositoryFactory——作为工厂
在团队成员分工合作时,此操作的作用就能完美体现。(只需将Database做更改即可)
object ProvideRepositoryFactory {
fun getRepository():BookRepository{
//如果需要模拟网络数据操作 改为Network即可
val dao = Database.getInstance().bookDao
return BookRepository.getInstance(dao)
}
}
最后是MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
private fun initializeUI(){
//监听按钮的点击事件
mButton.setOnClickListener{
if (mNameEditText.text.toString().isEmpty()){
Toast.makeText(this,"书名不能为空",Toast.LENGTH_LONG).show()
return@setOnClickListener
}
if (mAuthorEditText.text.toString().isEmpty()){
Toast.makeText(this,"作者名不能为空",Toast.LENGTH_LONG).show()
return@setOnClickListener
}
//数据保存到本地的数据库
val book = Book(mNameEditText.text.toString(),mAuthorEditText.text.toString())
val repository = ProvideRepositoryFactory.getRepository()
repository.addBook(book)
}
}
}
xml布局文件
本demo码简单,但也复杂(难就难在逻辑结构),其作用在于帮助理解MVC设计模式。
全部代码地址:https://github.com/gun-ctrl/MVC_Model