使用Kotlin掌握Android中的设计模式

重点 (Top highlight)

Before starting this blog, I would like to ask one question. What makes your code good? Is it the code size or something else? Just think over it for a while and then continue reading this blog.

在开始这个博客之前,我想问一个问题。 是什么使您的代码良好? 是代码大小还是其他? 仔细考虑一下,然后继续阅读此博客。

Originally published at blog.mindorks.com

最初发布在 blog.mindorks.com

There are certain factors that are used to differentiate between a good Android code and a bad Android code. It may be the code structure or the comments used or the variable names or something else. So, in Android, every developer should follow some Design Pattern while writing the code of an Android application. The following are some of the benefits of using Design Pattern in Android:

有一些因素可用来区分好Android代码和差的Android代码。 可能是代码结构或使用的注释,也可能是变量名或其他名称。 因此,在Android中,每个开发人员在编写Android应用程序的代码时都应遵循某种设计模式 。 以下是在Android中使用“设计模式”的一些好处:

  • Understandable code: By using Design Pattern, you can make your code understandable to everyone i.e. for writing code, you can follow certain guidelines and anyone can understand why you have written that code. For example, if you are using singleton pattern, then anyone viewing your code can understand that here you want to make only one object of a class and you want to access the same object throughout the application.

    易懂的代码:通过使用设计模式,您可以使每个人都可以理解您的代码,例如,编写代码时,您可以遵循某些准则,并且任何人都可以理解您为什么编写该代码。 例如 ,如果您使用的是单例模式,那么查看代码的任何人都可以理解,在这里您只想创建一个类的对象,并且想要在整个应用程序中访问同一对象。

  • Code reusability: By following the Design Pattern, you can make your code reusable i.e. for performing a certain task at more than one place, you need not write the same code again and again at various places.

    代码可重用性:通过遵循“设计模式”,您可以使代码可重用,即,要在多个地方执行某项任务,您无需在多个地方一次又一次地编写相同的代码。

  • Cleaner code: You can make your code cleaner by decoupling the code and it will make the code easier to understand by using Design Pattern.

    更清晰的代码:您可以通过解耦代码来使代码更简洁,并且可以使用“设计模式”使代码更易于理解。

So, in order to achieve the above-mentioned things, certain Design Patterns are defined that every Android Developer or every developer should follow while writing any code. In this blog, we will be learning about these Design Patterns in Android. So, let’s get started.

因此,为了实现上述目的,定义了某些设计模式,每个Android开发人员或每个开发人员在编写任何代码时都应遵循。 在此博客中,我们将学习有关Android中的这些设计模式的信息。 因此,让我们开始吧。

什么是设计模式? (What is a Design Pattern?)

As Wikipedia says:

正如维基百科所说:

A Design Pattern is a general, reusable solution to a commonly occurring problem within a given context.

设计模式是在给定上下文中对常见问题的通用,可重用的解决方案。

So, it is basically a pattern that can be followed to solve a particular feature. These are the best practices that can be used by any programmer to build an application.

因此,从根本上讲,这是可以解决特定功能的模式。 这些是任何程序员都可以用来构建应用程序的最佳实践。

In Android also, we use some Design Pattern that is used to make our code easier to understand and more reusable.

同样在Android中,我们使用一些设计模式,该设计模式用于使我们的代码更易于理解和重用。

There are a number of Design Patterns that can be used in Software Development and all these can be classified into the following three categories:

在软件开发中可以使用许多设计模式,所有这些模式都可以分为以下三类:

  • Creational Pattern

    创作模式
  • Structural Pattern

    结构模式
  • Behavioural Pattern

    行为模式

Let’s understand one by one.

让我们一一理解。

创作模式 (Creational Pattern)

The Creational Pattern is used to create some object without showing the logic or the steps that are involved in creating the object. So, every time you want an object, you need not instantiate the object by using the new operator. So, this makes the creation of object easier and can be easily created again and again. Some of the examples of Creational Pattern are Builder, Singleton, and Dependency Injection.

创作模式用于 创建一些对象而不显示创建对象所涉及的逻辑或步骤。 因此,每次需要一个对象时, 都不需要使用new运算符实例化该对象 。 因此,这使对象的创建更加容易,并且可以轻松地一次又一次地创建。 创建模式的一些示例包括Builder,Singleton和Dependency Injection。

Builder pattern

建造者模式

In a builder pattern, you are only concerned about what you need from a class and not everything that a class has. For example, when you go to buy some laptop, then you have a list of important features that you want in your laptop like processors, ram, storage, etc. Apart from these features, all the other features like the speaker, battery, etc are some of the optional features for you. So, based on the important features, the shopkeeper will provide you with a laptop that contains all your important features.

在构建器模式中,您只关心类的需求,而不是类所拥有的一切。 例如 ,当您购买笔记本电脑时,会列出笔记本电脑中想要的重要功能,例如处理器,内存,存储器等。除了这些功能之外,其他所有功能(例如扬声器,电池等)是为您提供的一些可选功能。 因此,店主将根据重要功能为您提供一台包含您所有重要功能的笔记本电脑。

Similarly, when we have a model class and that class is having a number of parameter out of which some are important and some are not important then we can use the Builder pattern. By using the Builder pattern, the user need not call all the methods(as in the case of constructors) present in the class. The user can call only the required methods and even the order of calling of the method is not fixed i.e you can call any method before and after any method. There is no need for new keyword here(for java). Let’s understand this with the help of an example.

同样,当我们有一个模型类并且该类具有许多参数时,其中一些重要而又不重要,则可以使用Builder模式。 通过使用Builder模式,用户无需调用类中存在的所有方法(就构造函数而言)。 用户只能调用所需的方法,甚至该方法的调用顺序也不固定,即您可以在任何方法之前和之后调用任何方法。 这里不需要new关键字(对于Java) 。 让我们借助示例了解这一点。

In this example, we will be having one Laptop class with four properties i.e. processor, ram, battery, and screen size. The processor is important, so you need to pass it every time and the rest of the properties are not important. So, if you are not setting the value then the default value will be used. Our model class for Laptop looks like:

在此示例中,我们将拥有一个笔记本电脑类,该类具有四个属性,即处理器,内存,电池和屏幕尺寸。 处理器很重要,因此您每次都需要传递它,其他属性并不重要。 因此,如果您未设置该值,则将使用默认值。 我们的笔记本电脑模型类如下:

class Laptop(builder: Builder) {
private val processor: String = builder.processor
private val ram: String = builder.ram
private val battery: String = builder.battery
private val screenSize: String = builder.screenSize // Builder class
class Builder(processor: String) {
var processor: String = processor // this is necessary // optional features
var ram: String = "2GB"
var battery: String = "5000MAH"
var screenSize: String = "15inch" fun setRam(ram: String): Builder {
this.ram = ram
return this
} fun setBattery(battery: String): Builder {
this.battery = battery
return this
} fun setScreenSize(screenSize: String): Builder {
this.screenSize = screenSize
return this
} fun create(): Laptop {
return Laptop(this)
}
}
}

Now, you need not create the object every time. Just use the below code:

现在, 您无需每次都创建对象 。 只需使用以下代码:

Laptop.Builder("i7") // processor is compulsory
.setRam("8GB") // this is optional
.setBattery("6000MAH") // this is optional
.create()

In the above code, we have to pass the processor because this is a necessary component and rest are optional. Here, we are not passing the screen size, so the default value of the screen size will be used.

在上面的代码中,我们必须通过处理器,因为这是必需的组件,其余部分是可选的。 在这里,我们没有传递屏幕尺寸,因此将使用屏幕尺寸的默认值。

One of the common examples of Builder pattern that we all use in our daily life is that of AlertDialog. In AleartDialog, we call only the required methods like:

我们都在日常生活中使用的Builder模式的常见示例之一是AlertDialog。 在AleartDialog中,我们仅调用所需的方法,例如:

AlertDialog.Builder(this)
.setTitle("This is a title")
.setMessage("This is some message")
.show()

There are other methods available in AlertDialog, but you can use it according to your need.

AlertDialog中还有其他方法可用,但是您可以根据需要使用它。

Singleton pattern

单例模式

There are cases when you need only one instance of a class. So, whenever you call the object of the class, then the new object should not be created(only one-time object creation will be there). This design pattern provides a global point of access to a class. For example, the network connection in an application should be done once and not every time because it is a very expensive process. So in these cases, we can use a singleton.

在某些情况下,您需要一个类的一个实例 。 因此,无论何时调用该类的对象,都不应创建新对象(只有一次创建对象)。 这种设计模式提供了对类的全局访问点。 例如 ,应用程序中的网络连接应该一次而不是每次都进行,因为这是一个非常昂贵的过程。 因此,在这些情况下,我们可以使用单例。

Following is an example of a singleton class in Kotlin:

以下是Kotlin中单例课程的示例:

object DataManager{
init {
println("Singleton class invoked.")
}
fun getUserData(): User{
// some code
}}
// to user singleton class
fun main(args: Array<String>) {
DataManager.getUserData()
// more code
}

In Kotlin, there is no need for using private construction or static method to create a singleton class. Learn more about a singleton class in Kotin.

在Kotlin中,无需使用私有构造或静态方法来创建单例类。 了解有关Kotin的单例课程的更多信息

Dependency Injection pattern

依赖注入模式

Most of the classes have some dependency that is needed for the proper functioning of the class. In the general case, we hard-code all the dependencies needed in the class inside the class itself. But this is a very wrong way of providing dependency to a class because in future if the class requires some more dependency or you want to add more dependency, then you have to update the new dependency in all the classes that will be using that dependency. You have to update the code at many places and you should avoid this in your project.

大多数类都具有某些依赖,这些依赖是该类正常运行所必需的。 在一般情况下,我们在类本身内部对类中所需的所有依赖项进行硬编码。 但这是向类提供依赖关系的一种非常错误的方式,因为将来如果该类需要更多的依赖关系,或者您想添加更多的依赖关系,则必须在将使用该依赖关系的所有类中更新新的依赖关系。 您必须在许多地方更新代码,并且在项目中应避免这样做。

For example, a car needs an engine to run. So, instead of providing the engine inside the same car class, we should provide the engine from outside the car class.

例如 ,汽车需要引擎才能运行。 因此,与其在同一个车类中提供引擎,不如在车类外部提供引擎。

So, in the Dependency Injection pattern, we provide the dependency of a class from outside the class and no dependency will be provided in the same class.

因此,在“依赖注入”模式中,我们从类外部提供了一个类的依赖,而在同一类中将不提供任何依赖

For example, if a class “DataManager” is dependent on “DatabaseHelper” and “NetworkHelper” then we should not provide these two dependencies in the same “DataManager” class because there may be cases when these two dependencies are the dependencies of some other classes also. So, if there is a change in these dependencies, then you have to change the code of these two dependencies in all the classes that are dependent on these two.

例如 ,如果类“ DataManager”依赖于“ DatabaseHelper”和“ NetworkHelper”,则我们不应在同一“ DataManager”类中提供这两个依赖关系,因为有时这两个依赖关系是某些其他类的依赖关系也。 因此,如果这些依赖项发生了变化,则必须在所有依赖于这两个的类中更改这两个依赖项的代码。

Let’s understand how to implement Dependency Injection in our code.

让我们了解如何在我们的代码中实现依赖注入。

If we don’t use the concept of Dependency Injection in our code, then our code will look like:

如果我们在代码中不使用依赖注入的概念,那么我们的代码将如下所示:

class DataManager {
private val databaseHelper: DatabaseHelper = DatabaseHelper() // dependent on DatabaseHelper
private val networkHelper: NetworkHelper = NetworkHelper() // dependent on NetworkHelper

fun someTask() {
// do some operation with DatabaseHelper and NetworkHelper
}
}

To use the dependency you have to use the below code:

要使用依赖关系,您必须使用以下代码:

val dataManager: DataManager = DataManager()
dataManager.someTask()

But here, it is very difficult to test each class separately and also if there is a change in dependency, then you have to change the code of the DataManager class again and again.

但是在这里,很难分别测试每个类,并且如果依赖关系发生变化,则必须一次又一次地更改DataManager类的代码。

So, if we provide dependency from outside the class then the code looks something like this:

因此,如果我们从类外部提供依赖关系,则代码如下所示:

class DataManager(databaseHelper: DatabaseHelper, networkHelper: NetworkHelper) {
private val databaseHelper: DatabaseHelper = databaseHelper
private val networkHelper: NetworkHelper = networkHelper fun someTask() {
// do some operation with DatabaseHelper and NetworkHelper
}
}

Now, you can use the DatabaseHelper and NetworkHelper by using the below code:

现在,您可以通过以下代码使用DatabaseHelper和NetworkHelper:

val databaseHelper: DatabaseHelper = DatabaseHelper()
val networkHelper: NetworkHelper = NetworkHelper()
val dataManager: DataManager = DataManager(databaseHelper, networkHelper)
dataManager.someTask()

So by using the DependencyInjection pattern, you will get the ability to test each class in isolation. But every time you want to use the DatabaseHelper and NetworkHelper, you need to write all these codes. So, to make things easier, we make use of a framework called Dagger. The Dagger will do all these things for you and make your coding life easier :)

因此,通过使用DependencyInjection模式,您将能够独立测试每个类。 但是每次您想使用DatabaseHelper和NetworkHelper时,都需要编写所有这些代码。 因此,为了使事情变得容易,我们使用了一个称为Dagger的框架。 Dagger将为您做所有这些事情,并使您的编码工作更轻松:)

Learn more about Dagger.

了解有关Dagger的更多信息。

结构模式 (Structural Pattern)

In this Design Pattern, we are concerned about the structure of the code. Here we follow some particular structural pattern that will help in understanding the code and the working of code just by looking at the structure of the code. Some of the common Structural Pattern used are Adapter, Bridge, Facade, Proxy, etc.

在此设计模式中,我们关注代码的结构。 在这里,我们遵循一些特定的结构模式,仅通过查看代码的结构即可帮助理解代码和代码的工作。 某些常用的结构模式包括适配器,桥,立面,代理等。

Adapter pattern

适配器图案

An Adapter is something like a connector that is used to connect two or more incompatible interface. This pattern lets the classes work together. Let’s look at one example:

适配器类似于连接器,用于连接两个或多个不兼容的接口。 这种模式使类可以一起工作。 让我们看一个例子:

Consider that you are having an airline app that shows the flight details. This application is used in India. So, all the details such as flight price and flight time are according to Indian currency and Indian time respectively. So, for this, you can have one view class called “FlightView” that is having the view that shows the flight time and flight price. In this class, you can have a “ShowDetails()” methods that provide the flight time and flight price and then sets these value on some textview.

考虑到您有一个显示航班详细信息的航空公司应用程序。 该应用程序在印度使用。 因此,航班价格和航班时间等所有详细信息分别是根据印度货币和印度时间计算的。 因此,为此,您可以拥有一个名为“ FlightView ”的视图类,该类具有显示航班时间和航班价格的视图。 在此类中,您可以使用“ ShowDetails() ”方法来提供飞行时间和飞行价格,然后在某些textview上设置这些值。

The problem arises when we have the details of two airlines of different countries let’s say AirIndia and UnitedAirlines. The time and price of the AirIndia will be shown correctly because it is according to Indian standards. But the UnitedAirlines will be having timings and pricing according to the American time and currency. Both the classes have different time zone and currency. So, these two classes i.e. the “AirIndia” and “UnitedAirlines” are totally incompatible and here we need one Adapter to have communication between these two otherwise, we will end up having the price of UnitedAirlines in rupees(without any conversion from the dollar).

当我们拥有不同国家的两家航空公司的详细信息时,比如说AirIndia和UnitedAirlines,就会出现问题。 由于符合印度标准,因此可以正确显示AirIndia的时间和价格。 但美联航将根据美国时间和货币确定时间和价格。 两种课程都有不同的时区和货币。 因此,“ AirIndia”和“ UnitedAirlines”这两个类是完全不兼容的,在这里,我们需要一个适配器来在这两个类之间进行通信,否则,最终将使UnitedAirlines的价格为卢比(不进行美元换算) 。

So let’s create an interface Adapter named “FlightDetailAdapter”. This interface is having two methods that will return the time according to IST(Indian Standard Time) and the price will be in INR(i.e. Indian currency). The basic idea is we will implement this interface in various Airlines to get the details according to Indian standards. By using these methods we can have the timings and price of all the airlines according to the Indian time and Indian currency.

因此,让我们创建一个名为“ FlightDetailAdapter ”的接口适配器。 该接口有两种方法,它们将根据IST(印度标准时间)返回时间,价格将以INR(即印度货币)显示。 基本思想是,我们将在各个航空公司中实现此接口,以根据印度标准获取详细信息。 通过使用这些方法,我们可以根据印度时间和印度货币得出所有航空公司的时间和价格。

interface FlightDetailAdapter {
// get price in indian rupees
fun getPriceInINR()

// get time in Indian Standard Time
fun getTimeInIST()
}

After creating the interface, now we have to make two classes i.e. “AirIndiaFlightDetailAdapter” and “UnitedAirlinesFlightDetailAdapter”. Both of these classes will implement the same interface i.e. “FlightDetailAdapter”.

创建接口之后,现在我们必须创建两个类,即“ AirIndiaFlightDetailAdapter ”和“ UnitedAirlinesFlightDetailAdapter ”。 这两个类都将实现相同的接口,即“ FlightDetailAdapter”。

The code for the “AirIndiaFlightDetailAdapter” will be:

“ AirIndiaFlightDetailAdapter”的代码为:

class AirIndiaFlightDetailsAdapter: FlightDetailAdapter {    // some AirIndiaApi that gives the time and price according to Indian standards
var api:AirIndianApi = AirIndiaAPI() override fun getPriceInINR(): Int {
// returns the price in INR
return api.price
} override fun getTimeInIST(): String {
//returns the time in IST
return api.time
}
}

The code for the “UnitedAirlinesFlightDetailAdapter” will be:

“ UnitedAirlinesFlightDetailAdapter”的代码为:

class UnitedAirlinesFlightDetailAdapter: FlightDetailAdapter {
// some UnitedAirlinesAPI that gives the time and price according to American standards
var api:UnitedAirlinesAPI = UnitedAirlinesAPI() override fun getPriceInINR(): Int {
// returns the price in INR
return convertUSDToINR(api.price)
} override fun getTimeInIST(): String {
//returns the time in IST
return convertESTToIST(api.time)
} fun convertUSDToINR(price: Int): Int {
// some logic
} fun convertESTToIST(time: String): String {
// some logic
}
}

Now, we can write the code of our “FlightView” class that will show the time and price of the flights on the application:

现在,我们可以编写“ FlightView”类的代码,该代码将在应用程序上显示航班的时间和价格:

class FlightView(context: Context) : View(context) {
// showing flight details according to Indian time and price
fun showFlightData(fda: FlightDetailAdapter) {
priceTextView.text = fda.getPriceInINR()
timeTextView.text = fda.getTimeInIST()
}
}

Finally, you can call for the desired flight details i.e. you can call the AirIndia classes and the UnitedAirlines classes according to your need and show the correct output in the view. For showing the AirIndia flight details, just use:

最后,您可以调用所需的航班详细信息,即可以根据需要调用AirIndia类和UnitedAirlines类,并在视图中显示正确的输出。 要显示AirIndia的航班详细信息,只需使用:

val flightView: FlightView = FlightView()// for showing AirIndia flight details
flightView.showFlightData(AirIndiaFlightDetailsAdapter())

And for showing the UnitedAirlines flight details, just use:

要显示美联航的航班详细信息,只需使用:

val flightView: FlightView = FlightView()// for showing UnitedAirlines flight details
flightView.showFlightData(UnitedAirlinesFlightDetailAdapter())

In Android, RecyclerView and PagerAdapter are some of the good examples of the Adapter pattern.

在Android中,RecyclerView和PagerAdapter是Adapter模式的一些很好的例子。

This is how we can use the Adapter in Android that will help us in creating a connection between two incompatible classes.

这就是我们在Android中使用适配器的方式,它将帮助我们在两个不兼容的类之间创建连接。

Facade pattern

外墙图案

In the Facade pattern, a complicated system is wrapped into a simpler system that will help us in getting the values from the complicated system without having knowledge of how the data is being fetched and returned to the view or the presenter.

在Facade模式中,一个复杂的系统被包装到一个更简单的系统中,这将帮助我们从复杂的系统中获取值,而无需了解如何获取数据并将其返回给视图或演示者。

For example, We have one Presenter or View that shows us the users that are stored in the Database. So, the presenter demands the list of users by some DataManager class. The DataManager class deals with various data related things. It can have one NetworkHelper and one DatabaseHelper class. Internally, the DataManager may use the NetworkHelper or DatabaseHelper class to fetch the details, but our view or presenter is less bothered about that. It only needs the list of available users and nothing else. Even the view or presenter is unaware of the fact that there is some NerworkHelper or DatabaseHelper class.

例如 ,我们有一个演示者或视图,向我们显示存储在数据库中的用户。 因此,演示者通过某些DataManager类要求用户列表。 DataManager类处理各种与数据相关的事物。 它可以具有一个NetworkHelper和一个DatabaseHelper类。 在内部,DataManager可以使用NetworkHelper或DatabaseHelper类来获取详细信息,但是我们的视图或演示者对此并不那么在意。 它仅需要可用用户列表,而无需其他任何内容。 甚至视图或演示者也没有意识到存在某些NerworkHelper或DatabaseHelper类的事实。

Image for post

行为模式 (Behavioural Pattern)

Behavioural Pattern mainly tells how the objects of the classes will communicate with each other. These patterns help us in understanding the code in a better way because by viewing the code we can identify the pattern and then we can understand the code in a better way. Some of the behavioural patterns are Chain of Responsibility, Interpreter, Mediator, Observer, Command, Model View Controler, Model View ViewModel, etc.

行为模式主要说明类的对象如何相互通信。 这些模式有助于我们更好地理解代码,因为通过查看代码,我们可以识别模式,然后我们可以更好地理解代码。 一些行为模式是责任链,解释器,中介者,观察者,命令,模型视图控制器,模型视图ViewModel等。

Observer pattern

观察者模式

The observer pattern is like one-to-many(or one) dependencies between objects. For example, on YouTube, you can subscribe to a particular channel and if some video is uploaded on that channel then all its subscriber will be notified about the change or about the new video.

观察者模式就像对象之间的一对多(或一个)依赖关系。 例如 ,在YouTube上,您可以订阅特定频道,如果在该频道上载了一些视频,则将通知所有订阅者有关更改或新视频的信息。

So, in Android also, when there is a change in some object, then the dependents of that object will be notified about the change and the possible update will be made accordingly in the dependents. This is called an Observer pattern because here we are observing for some change in the object.

因此,同样在Android中,当某些对象发生更改时,该更改将通知该对象的依赖项,并在依赖项中进行相应的可能更新。 之所以称为Observer模式,是因为我们正在观察对象中的某些变化。

For example, In Android, LiveData is an observable data holder class that enables the use of an observer pattern.

例如 ,在Android中,LiveData是可观察的数据持有者类,该类允许使用观察者模式。

Learn how to use LiveData in Android.

了解如何在Android中使用LiveData。

Also, RxJava enables the use of an observer pattern in Android.

同样,RxJava允许在Android中使用观察者模式。

Learn RxJava.

学习RxJava

Command pattern

命令模式

In the Command pattern, we give commands and we want our output and nothing else. We are not bothered about who will do our operation to give the desired result. All we want is our things to be done at the right time.

在“命令”模式中,我们给出命令,并且希望得到我们的输出,而没有其他要求。 我们不关心谁将执行我们的操作以提供期望的结果。 我们想要的是在正确的时间完成我们的工作。

For example, You have an “Execute” interface and there are two classes that are implementing this “Execute” interface. One class is responsible for writing something in the file and the other class is responsible for appending the contents of a file. So, you can call any of these two classes i.e. the “WriteFile” and “AppendClass” with the help of “Execute” interface.

例如 ,您有一个“ Execute”接口,并且有两个类正在实现此“ Execute”接口。 一类负责在文件中写入内容,另一类负责附加文件的内容。 因此,您可以借助“执行”界面调用这两个类中的任何一个,即“ WriteFile”和“ AppendClass”。

Image for post

Model View Controller pattern

模型视图控制器模式

Model View Controller or MVC is an Architectural Design pattern this is used to write an organised code for Android applications. Code following the MVC pattern is divided into three parts:

Model View Controller或MVC是一种体系结构设计模式,用于为Android应用程序编写组织的代码。 遵循MVC模式的代码分为三个部分:

  • Model: It is the place where you write all your Business logic and data state. So, all the data classes of your application are considered as Model.

    模型:在这里编写所有业务逻辑和数据状态。 因此,您的应用程序的所有数据类都被视为模型。

  • View: It is the user interface that a user sees. In Android, the user interface is built with the help of XML. So, all the views that the user sees come under this category.

    视图:这是用户看到的用户界面。 在Android中,用户界面是在XML的帮助下构建的。 因此,用户看到的所有视图都属于此类别。

  • Controller: A controller is simply a communication medium between the Model and the View. It takes the user input from the view. It processes the request and it sends the data from the Model to the view.

    控制器:控制器只是模型和视图之间的通信媒介。 它从视图中获取用户输入。 它处理请求,并将数据从模型发送到视图。

Image for post

Nowadays, we don’t use this pattern because it is declared as “Massive View Controller” for Android. Instead of MVC, we use MVP and MVVM.

如今,我们不使用此模式,因为它在Android中被声明为“ Massive View Controller ”。 代替MVC,我们使用MVP和MVVM。

Model View Presenter

模型视图演示者

Model View Presenter or MVP is a set of guidelines that are followed to make the code reusable and testable because it decouples the whole code. MVP divides the application into three parts:

Model View Presenter或MVP是一组准则,遵循这些准则可使代码可重用和可测试,因为它使整个代码脱钩。 MVP将应用程序分为三个部分:

  • Model: It is the place where you write all your Business logic and data state. So, all the data classes of your application are considered as Model.

    模型:在这里编写所有业务逻辑和数据状态。 因此,您的应用程序的所有数据类都被视为模型。

  • View: It is the user interface that a user sees. In Android, the user interface is built with the help of XML. So, all the views that the user sees come under this category.

    视图:这是用户看到的用户界面。 在Android中,用户界面是在XML的帮助下构建的。 因此,用户看到的所有视图都属于此类别。

  • Presenter: The presenter is responsible for giving the data to the view. If view demands some data from the Model, then it is the presenter that will fetch the data from the Model and provide the data to the view to display the required details.

    演示者:演示者负责将数据提供给视图。 如果视图需要模型中的某些数据,则演示者将从模型中获取数据,并将数据提供给视图以显示所需的详细信息。

Image for post

Learn more about MVP

进一步了解MVP

Model View ViewModel pattern

模型视图ViewModel模式

The Model View ViewModel or MVVC is similar to that of MVC but here the controller is replaced by the ViewModel. The three components of the Model View ViewModel are:

模型视图ViewModel或MVVC与MVC相似,但此处的控制器由ViewModel代替。 模型视图ViewModel的三个组件是:

  • Model: It is the place where you write all your Business logic and data state. So, all the data classes of your application are considered as Model.

    模型:在这里编写所有业务逻辑和数据状态。 因此,您的应用程序的所有数据类都被视为模型。

  • View: It is the user interface that a user sees. In Android, the user interface is built with the help of XML. So, all the views that the user sees come under this category.

    视图:这是用户看到的用户界面。 在Android中,用户界面是在XML的帮助下构建的。 因此,用户看到的所有视图都属于此类别。

  • ViewModel: It is a bridge between the Model and the View. Here most of the user interface logic is stored. This is mainly used to store and manage the UI-related and it resolves one of the biggest problems of data loss that was faced due to screen rotation.

    ViewModel:它是模型和视图之间的桥梁。 此处存储了大多数用户界面逻辑。 这主要用于存储和管理与UI相关的内容,它解决了由于屏幕旋转而面临的最大数据丢失问题之一。

Image for post

Have a look at our MVVM blog to have a better understanding of the same.

看看我们的MVVM博客,以更好地了解它们。

Clean Architecture

清洁建筑

Clean Architecture defines the way in which the various layers of an app i.e. presentation, use case, domain, data, and framework layer interact with each other. The Clean Architecture produces a system that is testable, UI-independent, and independent of external agencies and libraries. The following image is a popular clean architecture image:

Clean Architecture定义了应用程序各个层(即表示层,用例,域,数据和框架层)相互交互的方式。 Clean Architecture产生了一个可测试,独立于UI且独立于外部代理和库的系统。 下图是一个流行的干净建筑图像:

Image for post

These circles represent the various levels in our application. As we move inward in the circle, each circle is more abstract and higher-level. The inner circle is not dependent on any outer circle and the most inner circle denotes the business logic of the application.

这些圆圈代表了我们应用程序中的各个级别。 当我们在圆圈中向内移动时,每个圆圈都更加抽象和更高层次。 内圈不依赖于任何外圈,最内圈表示应用程序的业务逻辑。

结论 (Conclusion)

So in this blog, we learned about some of the Design Patterns that are used in Android to write a cleaner and understandable code. We learn about Builder pattern, Singleton pattern, Dependency Injection pattern, Adapter pattern, Facade pattern, Observer pattern, Command pattern, MVC, MVP, and MVVM pattern.

因此,在此博客中,我们了解了Android中用于编写更简洁易懂的代码的一些设计模式。 我们了解了Builder模式,Singleton模式,依赖注入模式,适配器模式,Facade模式,Observer模式,Command模式,MVC,MVP和MVVM模式。

Hope you will apply these Design Patterns in your next Android Project :)

希望您在下一个Android项目中应用这些设计模式:)

If you are preparing for your next Android Interview, Join our Android Professional Course to learn the latest in Android and land job at top tech companies.

如果您正在为下一次Android面试做准备,请参加我们的Android专业课程,以学习最新的Android知识并在顶级科技公司找到工作。

Happy Learning :)

快乐学习:)

Team MindOrks!

MindOrks团队!

Also, Let’s connect on Twitter, Linkedin, Github, and Facebook

另外,让我们在 Twitter Linkedin Github Facebook上连接

翻译自: https://medium.com/mindorks/mastering-design-patterns-in-android-with-kotlin-a6d83b24c363

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值