{"id":6233,"date":"2020-09-15T16:13:23","date_gmt":"2020-09-15T10:43:23","guid":{"rendered":"https:\/\/www.innovationm.com\/blog\/?p=6233"},"modified":"2023-01-20T18:55:16","modified_gmt":"2023-01-20T13:25:16","slug":"design-pattern","status":"publish","type":"post","link":"https:\/\/www.innovationm.com\/blog\/design-pattern\/","title":{"rendered":"Design Pattern"},"content":{"rendered":"<p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone wp-image-6234 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a1.png\" alt=\"\" width=\"619\" height=\"359\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a1.png 619w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a1-300x174.png 300w\" sizes=\"(max-width: 619px) 100vw, 619px\" \/>MVC Design Pattern(Model View Controller)<\/p>\n<p>After developing the complex application it is very tough to manage the application, so the stable app we want it to be, we use design pattern so any developer can easily understand the code any easy change the code according to need<\/p>\n<p>MVC firstly comes picture in design pattern<\/p>\n<p>The Model-View-Controller Pattern:-<\/p>\n<p>Model \u2014 the model layer, responsible for managing the business logic and handling network or database API.<\/p>\n<p>View \u2014 the UI layer, perform the operation related to the user interface<\/p>\n<p>Controller \u2014 the controller layer, gets notified of the user\u2019s behaviour and updates the Model.<\/p>\n<p>Note:- Here we can see that\u00a0 both the Controller and the View depend on the Model<\/p>\n<p>Q- How to use MVC in android<\/p>\n<p>The Activities, Fragments and Views should be the Views in the MVC world.<\/p>\n<p>The Controllers should be separate classes that don\u2019t extend or use any Android class.<\/p>\n<p>The Model should be separate classes that don\u2019t extend or use any Android class.<\/p>\n<p>Things you should know:-<\/p>\n<p>One problem arises when connecting the Controller to the View since the Controller needs to tell the View to update. In the Model MVC architecture, the Controller needs to hold a reference to the View. The easiest way of doing this, while focusing on testing, is to have a Base View interface, that the Activity\/Fragment would extend. So the Controller would have a reference to the Base View.<\/p>\n<p>Advantage:-<\/p>\n<p>The Model-View-Controller pattern highly supports the separation of concerns. This advantage not only increases the understanding of the code but it also makes it easier to extend, allowing easy implementation of new features.<\/p>\n<p>The Model classes don\u2019t have any reference to Android classes. The Controller doesn\u2019t extend or implement any Android classes and should have a reference to an interface class of the View.<\/p>\n<p>the Views respect the single responsibility principle then their role is just to update the Controller for every user event and just display data from the Model, without implementing any business logic.<\/p>\n<p>According to the MVC pattern, the Controller updates the Model and the View gets the data to be displayed from the Model. But who decides on how to display the data?<\/p>\n<p>we have a User, with first name and last name. In the View, we need to display the user name as \u201cLastname, Firstname\u201d (e.g. \u201cABC&#8221;, &#8220;DEF\u201d).<\/p>\n<p>If the Model\u2019s role is to just provide the \u201craw\u201d data, it means that the code in the View would be:<\/p>\n<pre class=\"lang:default decode:true \">String firstName = userModel.getFirstName();\r\n\r\nString lastName = userModel.getLastName();\r\n\r\nnameTextView.setText(lastName + \", \" + firstName)<\/pre>\n<p>The other approach is to have the Model expose only the data that needs to be displayed, hiding any business logic from the View. But then, we end up with Models that handle both business and UI logic. It would be unit-testable, but then the Model ends up, implicitly being dependent on the View.<\/p>\n<pre class=\"lang:default decode:true \">String name = userModel.getDisplayName();\r\n\r\nnameTextView.setText(name);<\/pre>\n<p>MVP(Model View Presenter)<\/p>\n<p>MVP is one of the software development design patterns which is currently in use by many android application developers for better app development<\/p>\n<p>The MVP pattern allows separating the presentation layer from the logic.<\/p>\n<p>MVP:&#8212;&#8212;&#8211;<\/p>\n<p>Model: The Model holds the business logic of the application. It controls how data is created, stored, and modified.<\/p>\n<p>View: The View is an interface that displays data and routes user actions to the Presenter.<\/p>\n<p>Presenter: The Presenter acts as the middleman. It retrieves data from the Model and shows it in the View. It also processes user actions forwarded by the View.<\/p>\n<p>MVP makes views independent from our data source. We divide the application into at least three different layers<\/p>\n<p>How to implement MVP?<\/p>\n<p>There are many variations of MVP and everyone can adjust the pattern idea to their needs and the way they feel more comfortable.<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-6235 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a2.png\" alt=\"\" width=\"700\" height=\"442\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a2.png 700w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a2-300x189.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a2-624x394.png 624w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/p>\n<pre class=\"lang:default decode:true \">interface ChangePasswordContractor {\r\n\r\n\u00a0\u00a0\u00a0 interface View: BaseActivityContractor.View {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun showError(resId: Int, errorMessage: String)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun setBackground(resId: Int, drawbleId: Int)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun moveToLoginScreen()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun isOldObsecure() : Boolean\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun setIsOldObsecure(isOldObsecure : Boolean)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun isNewObsecure() : Boolean\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun setIsNewObsecure(isNewObsecure : Boolean)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun isConfirmObsecure() : Boolean\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun setIsConfirmObsecure(isConfirmObsecure : Boolean)\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 interface Presenter : BaseActivityContractor.Presenter, AlertDialogCallback {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun showAlertDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun onChangePasswordSuccess()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun onChangePasswordFailed(errorMessage: String)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun onSaveButtonClick(oldPassword: String, newPassword: String, confirmPassword : String)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun getSaveInstanceDataMap() : HashMap&lt;String, Any&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun initializeSavedInstanceData(map : HashMap&lt;String, Any&gt;)\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 interface Interactor: BaseActivityContractor.Interactor {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fun onApiHitOfChangePassWord(accessToken: String, map: HashMap&lt;String, String&gt;)\r\n\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>Above interfaces will use to pass data between three layers. To implement these interfaces we will create three classes which will implement the defined methods of interfaces.<\/p>\n<p>Above methods will interact with the view layer to update user interface as needed. This ILoginView will be implemented by LoginActivity.<\/p>\n<pre class=\"lang:default decode:true \">class ChangePasswordActivity : BaseActivity(), ChangePasswordContractor.View {\r\n\u00a0\u00a0\u00a0 override fun isOldObsecure(): Boolean = this.isOldObsecure\r\n\r\n\u00a0\u00a0\u00a0 override fun setIsOldObsecure(isOldObsecure: Boolean) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.isOldObsecure = isOldObsecure\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun isNewObsecure(): Boolean = this.isNewObsecure\r\n\r\n\u00a0\u00a0\u00a0 override fun setIsNewObsecure(isNewObsecure: Boolean) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.isNewObsecure = isNewObsecure\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun isConfirmObsecure(): Boolean = this.isConfirmObsecure\r\n\r\n\u00a0\u00a0\u00a0 override fun setIsConfirmObsecure(isConfirmObsecure: Boolean) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.isConfirmObsecure = isConfirmObsecure\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 private val mChangePasswordPresenter: ChangePasswordContractor.Presenter =\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ChangePasswordPresenter(this)\r\n\u00a0\u00a0\u00a0 private var isOldObsecure = true\r\n\u00a0\u00a0\u00a0 private var isNewObsecure = true\r\n\u00a0\u00a0\u00a0 private var isConfirmObsecure = true\r\n\r\n\u00a0\u00a0\u00a0 override fun getLayoutResourseId(): Int = R.layout.activity_change_password\r\n\u00a0\u00a0\u00a0 override fun showError(resId: Int, errorMessage: String) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 findViewById&lt;TextInputLayout&gt;(resId).error = errorMessage\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun moveToLoginScreen() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 val intent = Intent(this, LoginActivity::class.java)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 startActivity(intent)\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\r\n\u00a0\u00a0\u00a0 override fun setBackground(resId: Int, drawbleId: Int) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 findViewById&lt;EditText&gt;(resId).setBackgroundResource(drawbleId)\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun initViews() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isOldObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isNewObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isConfirmObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tvBack.setOnClickListener {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 onBackPressed()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 btnSave.setOnClickListener {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onSaveButtonClick(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.text.toString().trim(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.text.toString().trim(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.text.toString().trim()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.setOnTouchListener(object : DrawableOnClickListener(etOldPassword) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun onClick(v: View?, event: MotionEvent?, whichDrawable: Int) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ViewUtils.showKeyboard(this@ChangePasswordActivity, etOldPassword)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isOldObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etOldPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isOldObsecure = !isOldObsecure\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.setOnTouchListener(object : DrawableOnClickListener(etNewPassword) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun onClick(v: View?, event: MotionEvent?, whichDrawable: Int) {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ViewUtils.showKeyboard(this@ChangePasswordActivity, etNewPassword)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isNewObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etNewPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isNewObsecure = !isNewObsecure\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.setOnTouchListener(object : DrawableOnClickListener(etConfirmPassword) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun onClick(v: View?, event: MotionEvent?, whichDrawable: Int) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ViewUtils.showKeyboard(this@ChangePasswordActivity, etConfirmPassword)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isConfirmObsecure) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.transformationMethod = null\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_show, 0)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.inputType = InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.transformationMethod = PasswordTransformationMethod()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 etConfirmPassword.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_password_hide, 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isConfirmObsecure = !isConfirmObsecure\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onSaveInstanceState(outState: Bundle) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 super.onSaveInstanceState(outState)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 outState.putSerializable(SAVED_INSTANCE_DATA, mChangePasswordPresenter.getSaveInstanceDataMap())\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\r\n\u00a0\u00a0\u00a0 @Suppress(\"UNCHECKED_CAST\")\r\n\u00a0\u00a0\u00a0 override fun onCreate(savedInstanceState: Bundle?) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 super.onCreate(savedInstanceState)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (savedInstanceState != null) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.initializeSavedInstanceData(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 savedInstanceState.getSerializable(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SAVED_INSTANCE_DATA\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ) as HashMap&lt;String, Any&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onCreate()\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>In LoginPresenterImpl, we will have an instance of view(ILoginView) and Model(ILoginInteractor) which call methods as needed.<\/p>\n<p>Interactor:-<\/p>\n<p>personally we prefer Api related operation here<\/p>\n<pre class=\"lang:default decode:true \">class ChangePasswordIntractor(private val mChangePasswordPresenter: ChangePasswordContractor.Presenter) :\r\n\u00a0\u00a0\u00a0 BaseActivityInteractor(mChangePasswordPresenter), ChangePasswordContractor.Interactor {\r\n\u00a0\u00a0\u00a0 override fun onApiHitOfChangePassWord(accessToken: String, map: HashMap&lt;String, String&gt;) {\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!mChangePasswordPresenter.isInternetAvailable()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onChangePasswordFailed(ERROR_NO_INTERNET)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RestClient.getApiInterface()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .changePassword(getHeader(accessToken, CHANGE_PASSWORD), map)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 .enqueue(object : ResponseCallback&lt;Any&gt;() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun success(responseBody: BaseResponse&lt;Any&gt;) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onChangePasswordSuccess()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun failure(statusCode: Int, errorMessage: String) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onChangePasswordFailed(errorMessage)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun sessionExpired() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onSessionExpired()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 override fun onForceUpdate() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordPresenter.onForceUpdate()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })\r\n\r\n\u00a0\u00a0\u00a0 }\r\n}\u00a0Presenter:-Act\u00a0 as\u00a0 a brain,which contain the reference of view and intractor.\u00a0class ChangePasswordPresenter(private val mChangePasswordView: ChangePasswordContractor.View) :\r\n\u00a0\u00a0\u00a0 BaseActivityPresenter(mChangePasswordView), ChangePasswordContractor.Presenter {\r\n\r\n\r\n\u00a0\u00a0\u00a0 private val mChangePasswordIntractor: ChangePasswordIntractor = ChangePasswordIntractor(this)\r\n\u00a0\u00a0\u00a0 private var isAlertDialogOpen: Boolean = false\r\n\r\n\u00a0\u00a0\u00a0 override fun getSaveInstanceDataMap(): java.util.HashMap&lt;String, Any&gt; = hashMapOf(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"is_old_password_visible\" to mChangePasswordView.isOldObsecure(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"is_new_password_visible\" to mChangePasswordView.isNewObsecure(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"is_confirm_password_visible\" to mChangePasswordView.isConfirmObsecure(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"isAlertDialogOpen\" to isAlertDialogOpen\r\n\u00a0\u00a0\u00a0 )\r\n\r\n\u00a0\u00a0\u00a0 override fun initializeSavedInstanceData(map: java.util.HashMap&lt;String, Any&gt;) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setIsOldObsecure(map[\"is_old_password_visible\"].toString().toBoolean())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setIsNewObsecure(map[\"is_new_password_visible\"].toString().toBoolean())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setIsConfirmObsecure(map[\"is_confirm_password_visible\"].toString().toBoolean())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.isAlertDialogOpen = map[\"isAlertDialogOpen\"].toString().toBoolean()\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onSaveButtonClick(oldPassword: String, newPassword: String, confirmPassword : String) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(R.id.tv_passwoordnotmatch, \"\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (oldPassword.isEmpty()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(R.id.tv_passwoordnotmatch, mChangePasswordView.getStringFor(R.string.error_empty_old_password))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else if (newPassword.isEmpty()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(R.id.tv_passwoordnotmatch, mChangePasswordView.getStringFor(R.string.error_empty_new_password))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else if (!newPassword.isPassword() || newPassword.length &lt; 7) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 R.id.tv_passwoordnotmatch,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.getStringFor(R.string.error_invalid_password)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else if (newPassword.length &gt; 15) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 R.id.tv_passwoordnotmatch,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.getStringFor(R.string.error_password_greaterthan15)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else if (confirmPassword.isEmpty()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(R.id.tv_passwoordnotmatch, mChangePasswordView.getStringFor(R.string.error_empty_confirm_password))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else if (confirmPassword.replace(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"\\\\s\".toRegex(),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ) != newPassword.replace(\"\\\\s\".toRegex(), \"\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.setTextFor(R.id.tv_passwoordnotmatch, mChangePasswordView.getStringFor(R.string.error_password_mismatch))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.showProgressDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordIntractor.onApiHitOfChangePassWord(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 accessToken!!, hashMapOf(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"oldPassword\" to oldPassword.replace(\"\\\\s\".toRegex(), \"\"),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"newPassword\" to newPassword.replace(\"\\\\s\".toRegex(), \"\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onChangePasswordSuccess() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.dismissProgressDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 showAlertDialog()\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onChangePasswordFailed(errorMessage: String) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.dismissProgressDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.showSnackbarMessage(errorMessage)\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onAlertDialogPositiveButtonClicked(purposeType: Int) {\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onAlertDialogNegativeButtonClicked(purposeType: Int) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (purposeType == 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isAlertDialogOpen = false\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.dismissAlertDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 super.onBackPressed()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun onAlertDialogNeutralButtonClicked(purposeType: Int) {\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 override fun showAlertDialog() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isAlertDialogOpen = true\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.showPrimaryAlertDialog(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 title = mChangePasswordView.getStringFor(R.string.password_change_successfully),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 positiveButton = \"\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 negativeButton = mChangePasswordView.getStringFor(R.string.text_ok),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 isCanclable = true,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 purposeType = 0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\r\n\u00a0\u00a0\u00a0 override fun onCreate() {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (isAlertDialogOpen) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 showAlertDialog()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.addAlertDialogCallback(this)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 super.onCreate()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mChangePasswordView.initViews()\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p><strong>MVVM\u00a0 (MODEL-VIEW-VIEWMODEL)<\/strong><\/p>\n<p>MVVM is a software architectural pattern which facilitates separation of development UI (Activity or Fragment) from the development of the business logic or back-end logic (the data model).<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-6236 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/A3.png\" alt=\"\" width=\"700\" height=\"210\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/A3.png 700w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/A3-300x90.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/A3-624x187.png 624w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>ViewModels are simples classes that interact with the logic\/model layer and just exposes states\/data and actually have no idea by whom or how that data will be consumed. Only View(Activity) holds the reference to ViewModel and not vice versa, this solves our tight coupling issue.<\/p>\n<p>Note:&#8211; A single view can hold a reference to multiple ViewModels.<\/p>\n<p>Q- Why it is good to use MVVM over MVP?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6237 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a4.png\" alt=\"\" width=\"481\" height=\"330\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a4.png 481w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a4-300x206.png 300w\" sizes=\"(max-width: 481px) 100vw, 481px\" \/><\/p>\n<p>In MVP, the role of a Presenter is to drive the View changes and at the same time provide data for completing those operations whereas MVVM, the ViewModel only provides the data, whereas the View is responsible for consuming them and does not hold the reference to the View. The ViewModel can also hold the logic for processing users input, same as the Presenter<\/p>\n<p>Note:-we can worry less about lifecycle, memory leaks and crashes.<\/p>\n<p>MVVM components:-<\/p>\n<p>Data Model \u2014 it abstracts the data source. The ViewModel works with the DataModel to get and save the data. it represents the business objects that encapsulate the data and behaviour of the application.<\/p>\n<p>ViewModel \u2014 it exposes streams of data relevant to the View and provides the data for a specific UI component, such as a fragment or activity, and contains data-handling business logic to communicate with the model.<\/p>\n<p>View \u2014 the UI that users see and view send and receive the data from the view model<\/p>\n<p>The Repository holds all the business logic of the particular app section in the app.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6238 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a5.png\" alt=\"\" width=\"700\" height=\"525\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a5.png 700w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a5-300x225.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a5-624x468.png 624w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6239 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a6.png\" alt=\"\" width=\"700\" height=\"310\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a6.png 700w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a6-300x133.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/a6-624x276.png 624w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>Step to implement MVVM in your project:-<\/p>\n<p><strong>1- Add the following line in your project level build.gradle<\/strong><\/p>\n<pre class=\"lang:default decode:true\">repositories {\r\n\u00a0\u00a0\u00a0 google()\r\n\u00a0\u00a0\u00a0 jcenter()\r\n\u00a0\u00a0\u00a0 maven {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 url 'https:\/\/maven.fabric.io\/public'\r\n\u00a0\u00a0\u00a0 }<\/pre>\n<p><strong>2- Open the build.gradle file for your app or module and add dependencies:<\/strong><\/p>\n<p>implementation <strong>&#8220;androidx.lifecycle:lifecycle-viewmodel:2.2.0&#8221;<br \/>\n<\/strong>annotationProcessor <strong>&#8220;androidx.lifecycle:lifecycle-compiler:2.2.0&#8221;<\/strong><\/p>\n<p><strong>3- Create data source<\/strong><\/p>\n<p>you will create a data source for your application if you are using RestAPI you might use Retrofit or Volley for parsing the JSON data and if you are using SQL database you will use Room Database or SQLite.<\/p>\n<p><strong>4- Create repository<\/strong><\/p>\n<p>A Repository is basically a wrapper class which contains the business logic of our app.<\/p>\n<p>we are Using Room database we need to have ApplicationContext and we will write all the database operation here so the person who is working on the UI does not have to worry about any database operations.<\/p>\n<pre class=\"lang:default decode:true \">Public class Reprository{\r\n\r\nPublic Reprository(Application application)\r\n\r\n{\r\n\r\n}\r\n\r\n}<\/pre>\n<p>In this Repository class, we will write all the DAO operations and access them in the UI through ViewModel.<\/p>\n<p><strong>5- Create a viewmodel<\/strong><\/p>\n<p>The ViewModel class allows data to survive configuration changes such as screen rotations.<\/p>\n<p>The purpose of the ViewModel is to acquire and keep the information that is necessary for an Activity or a Fragment. The Activity or the Fragment should be able to observe changes in the ViewModel. ViewModels usually expose this information via LiveData or Android Data Binding. You can also use any observability construct from your favourite framework.<\/p>\n<pre class=\"lang:default decode:true \">public class SignupViewModel extends ViewModel implements RetrofitResponseCallback {\r\n\u00a0\u00a0\u00a0 private SignupCallback signupCallback;\r\n\u00a0\u00a0\u00a0 private Context context;\r\n\r\n\u00a0\u00a0\u00a0 public void setCallback(Context context) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.context = context;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.signupCallback = (SignupCallback) context;\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 private ApiInterface apiInterface(String token) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return ApiClient.getRetrofitInstance(token).create(ApiInterface.class);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 public void signupUser(String email, String language, String name, String country, String state, String password) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SignupRequest signupRequest = new SignupRequest();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setEmail(email);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setLanguage(language);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setFirst_name(name);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setCountry(country);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setPassword(password);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setRole(\"DMS_Admin\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupRequest.setState(state);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Call&lt;SignupResponse&gt; call = apiInterface(\"\").signUpUser(signupRequest);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ApiClient.retrofitInvokeWebService(call, this, AppConstants.REQUEST_CODE_SIGNUP);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 public void sendTokenToServer(String token, String authToken, String userId, String userEmail) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ApiInterface apiInterface = ApiClient.getRetrofitInstance(authToken).create(ApiInterface.class);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UserAppDetail userAppDetail = new UserAppDetail();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAppDetail.setFirebaseId(token);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAppDetail.setUserId(userId);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAppDetail.setUserEmail(userEmail);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAppDetail.setAppVersionId(Integer.toString(BuildConfig.VERSION_CODE));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 userAppDetail.setAppVersionName(BuildConfig.VERSION_NAME);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Call&lt;UserAppResponse&gt; call = apiInterface.sendFirebaseUserDetail(userAppDetail);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ApiClient.retrofitInvokeWebService(call, this, AppConstants.REQUEST_CODE_SEND_TOKEN);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 @Override\r\n\u00a0\u00a0\u00a0 public void onStart(int requestCode) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (requestCode == AppConstants.REQUEST_CODE_SIGNUP) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupCallback.onShowProgress(\"SIgnUp ...\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 @Override\r\n\u00a0\u00a0\u00a0 public void onResponse(Object call, Object response, int requestCode) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupCallback.onSuccess(response, requestCode);\r\n\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 @Override\r\n\u00a0\u00a0\u00a0 public void onFailure(Object call, Object faliure, int requestCode) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (faliure instanceof String) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 signupCallback.onHideProgress();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ToasterNotification.showToast(context, faliure.toString());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n}<\/pre>\n<p>Note:-ViewModel can handle the lifecycle configurations.<\/p>\n<p><strong>6- Use view model in UI<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>MVC Design Pattern(Model View Controller) After developing the complex application it is very tough to manage the application, so the stable app we want it to be, we use design pattern so any developer can easily understand the code any easy change the code according to need MVC firstly comes picture in design pattern The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6243,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[215,14],"class_list":["post-6233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mobile","tag-design-pattern","tag-innovationm"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Design Pattern - InnovationM - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.innovationm.com\/blog\/design-pattern\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Design Pattern - InnovationM - Blog\" \/>\n<meta property=\"og:description\" content=\"MVC Design Pattern(Model View Controller) After developing the complex application it is very tough to manage the application, so the stable app we want it to be, we use design pattern so any developer can easily understand the code any easy change the code according to need MVC firstly comes picture in design pattern The [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.innovationm.com\/blog\/design-pattern\/\" \/>\n<meta property=\"og:site_name\" content=\"InnovationM - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-09-15T10:43:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-20T13:25:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"InnovationM Admin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"InnovationM Admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/\"},\"author\":{\"name\":\"InnovationM Admin\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"headline\":\"Design Pattern\",\"datePublished\":\"2020-09-15T10:43:23+00:00\",\"dateModified\":\"2023-01-20T13:25:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/\"},\"wordCount\":1225,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/Design-Pattern.png\",\"keywords\":[\"Design Pattern\",\"InnovationM\"],\"articleSection\":[\"Mobile\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/\",\"name\":\"Design Pattern - InnovationM - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/Design-Pattern.png\",\"datePublished\":\"2020-09-15T10:43:23+00:00\",\"dateModified\":\"2023-01-20T13:25:16+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/Design-Pattern.png\",\"contentUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/Design-Pattern.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/design-pattern\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Design Pattern\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\",\"name\":\"InnovationM - Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\",\"name\":\"InnovationM Admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"caption\":\"InnovationM Admin\"},\"sameAs\":[\"http:\\\/\\\/www.innovationm.com\\\/\"],\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/author\\\/innovationmadmin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Design Pattern - InnovationM - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.innovationm.com\/blog\/design-pattern\/","og_locale":"en_US","og_type":"article","og_title":"Design Pattern - InnovationM - Blog","og_description":"MVC Design Pattern(Model View Controller) After developing the complex application it is very tough to manage the application, so the stable app we want it to be, we use design pattern so any developer can easily understand the code any easy change the code according to need MVC firstly comes picture in design pattern The [&hellip;]","og_url":"https:\/\/www.innovationm.com\/blog\/design-pattern\/","og_site_name":"InnovationM - Blog","article_published_time":"2020-09-15T10:43:23+00:00","article_modified_time":"2023-01-20T13:25:16+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png","type":"image\/png"}],"author":"InnovationM Admin","twitter_misc":{"Written by":"InnovationM Admin","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#article","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/"},"author":{"name":"InnovationM Admin","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"headline":"Design Pattern","datePublished":"2020-09-15T10:43:23+00:00","dateModified":"2023-01-20T13:25:16+00:00","mainEntityOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/"},"wordCount":1225,"commentCount":0,"image":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png","keywords":["Design Pattern","InnovationM"],"articleSection":["Mobile"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.innovationm.com\/blog\/design-pattern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/","url":"https:\/\/www.innovationm.com\/blog\/design-pattern\/","name":"Design Pattern - InnovationM - Blog","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#primaryimage"},"image":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png","datePublished":"2020-09-15T10:43:23+00:00","dateModified":"2023-01-20T13:25:16+00:00","author":{"@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"breadcrumb":{"@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.innovationm.com\/blog\/design-pattern\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#primaryimage","url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png","contentUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2020\/09\/Design-Pattern.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/www.innovationm.com\/blog\/design-pattern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.innovationm.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Design Pattern"}]},{"@type":"WebSite","@id":"https:\/\/www.innovationm.com\/blog\/#website","url":"https:\/\/www.innovationm.com\/blog\/","name":"InnovationM - Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.innovationm.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed","name":"InnovationM Admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","caption":"InnovationM Admin"},"sameAs":["http:\/\/www.innovationm.com\/"],"url":"https:\/\/www.innovationm.com\/blog\/author\/innovationmadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/6233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/comments?post=6233"}],"version-history":[{"count":0,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/6233\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media\/6243"}],"wp:attachment":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media?parent=6233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/categories?post=6233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/tags?post=6233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}