{"id":2056,"date":"2019-06-08T15:18:16","date_gmt":"2019-06-08T12:18:16","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2056"},"modified":"2024-12-16T22:32:36","modified_gmt":"2024-12-16T19:32:36","slug":"template-pattern","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/hi\/2019\/06\/08\/template-pattern\/","title":{"rendered":"Template method"},"content":{"rendered":"<p>The template method is a behavioral design pattern. The pattern describes a way to replace part of a class&#8217;s logic on demand, while leaving the common part unchanged for descendants.<\/p>\n<figure id=\"attachment_2059\" aria-describedby=\"caption-attachment-2059\" style=\"width: 420px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.flickr.com\/photos\/diphi\/24449843465\/\" target=\"_blank\" rel=\"noopener noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2059\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/06\/cars-1.jpg\" alt=\"\" width=\"420\" height=\"265\" \/><\/a><figcaption id=\"caption-attachment-2059\" class=\"wp-caption-text\"><a href=\"https:\/\/www.flickr.com\/photos\/diphi\/24449843465\/\" target=\"_blank\" rel=\"noopener noreferrer\">Cuban Cars<\/a><\/figcaption><\/figure>\n<p>Let&#8217;s say we are developing a bank client, let&#8217;s consider the task of developing an authorization module &#8211; the user should be able to log in to the application using abstract login data.<br \/>The authorization module must be cross-platform, support different authorization technologies and storage of encrypted data of different platforms. To implement the module, we choose the cross-platform language Kotlin, using the abstract class (protocol) of the authorization module, we will write an implementation for the MyPhone phone:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class MyPhoneSuperDuperSecretMyPhoneAuthorizationStorage {\n    fun loginAndPassword() : Pair<String, String> {\n        return Pair(\"admin\", \"qwerty65435\")\n    }\n}\n\nclass ServerApiClient {\n    fun authorize(authorizationData: AuthorizationData) : Unit {\n        println(authorizationData.login)\n        println(authorizationData.password)\n        println(\"Authorized\")\n    }\n}\n\nclass AuthorizationData {\n    var login: String? = null\n    var password: String? = null\n}\n\ninterface AuthorizationModule {\n    abstract fun fetchAuthorizationData() : AuthorizationData\n    abstract fun authorize(authorizationData: AuthorizationData)\n}\n\nclass MyPhoneAuthorizationModule: AuthorizationModule {\n    \n    override fun fetchAuthorizationData() : AuthorizationData {\n        val loginAndPassword = MyPhoneSuperDuperSecretMyPhoneAuthorizationStorage().loginAndPassword()\n        val authorizationData = AuthorizationData()\n        authorizationData.login = loginAndPassword.first\n        authorizationData.password = loginAndPassword.second\n        \n        return authorizationData\n    }\n    \n    override fun authorize(authorizationData: AuthorizationData) {\n        ServerApiClient().authorize(authorizationData)\n    }\n    \n}\n\nfun main() {\n    val authorizationModule = MyPhoneAuthorizationModule()\n    val authorizationData = authorizationModule.fetchAuthorizationData()\n    authorizationModule.authorize(authorizationData)\n}\n<\/code><\/pre>\n<\/div>\n<p>Now for each phone\/platform we will have to duplicate the code for sending authorization to the server, there is a violation of the DRY principle. The example above is very simple, in more complex classes there will be even more duplication. To eliminate code duplication, you should use the Template Method pattern.<br \/>We will move the common parts of the module into immutable methods, and transfer the functionality of transmitting encrypted data to specific platform classes:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class MyPhoneSuperDuperSecretMyPhoneAuthorizationStorage {\n    fun loginAndPassword() : Pair<String, String> {\n        return Pair(\"admin\", \"qwerty65435\")\n    }\n}\n\nclass ServerApiClient {\n    fun authorize(authorizationData: AuthorizationData) : Unit {\n        println(authorizationData.login)\n        println(authorizationData.password)\n        println(\"Authorized\")\n    }\n}\n\nclass AuthorizationData {\n    var login: String? = null\n    var password: String? = null\n}\n\ninterface AuthorizationModule {\n    abstract fun fetchAuthorizationData() : AuthorizationData\n    \n    fun authorize(authorizationData: AuthorizationData) {\n        ServerApiClient().authorize(authorizationData)\n    }\n}\n\nclass MyPhoneAuthorizationModule: AuthorizationModule {\n    \n    override fun fetchAuthorizationData() : AuthorizationData {\n        val loginAndPassword = MyPhoneSuperDuperSecretMyPhoneAuthorizationStorage().loginAndPassword()\n        val authorizationData = AuthorizationData()\n        authorizationData.login = loginAndPassword.first\n        authorizationData.password = loginAndPassword.second\n        \n        return authorizationData\n    }\n    \n}\n\nfun main() {\n    val authorizationModule = MyPhoneAuthorizationModule()\n    val authorizationData = authorizationModule.fetchAuthorizationData()\n    authorizationModule.authorize(authorizationData)\n}\n<\/code><\/pre>\n<\/div>\n<h3>Sources<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/design-patterns\/template-method\" rel=\"noopener noreferrer\" target=\"_blank\">https:\/\/refactoring.guru\/ru\/design- patterns\/template-method<\/a><\/p>\n<h3>Source code<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/patterns\/\" rel=\"noopener noreferrer\" target=\"_blank\">https:\/\/gitlab.com\/demensdeum\/patterns\/<\/a>< \/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The template method is a behavioral design pattern. The pattern describes a way to replace part of a class&#8217;s logic on demand, while leaving the common part unchanged for descendants. Cuban Cars Let&#8217;s say we are developing a bank client, let&#8217;s consider the task of developing an authorization module &#8211; the user should be able<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/hi\/2019\/06\/08\/template-pattern\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Template method&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[95,107],"class_list":["post-2056","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-patterns","tag-template-method","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"hi","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/posts\/2056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/comments?post=2056"}],"version-history":[{"count":13,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/posts\/2056\/revisions"}],"predecessor-version":[{"id":3954,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/posts\/2056\/revisions\/3954"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/media?parent=2056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/categories?post=2056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/hi\/wp-json\/wp\/v2\/tags?post=2056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}