{"id":483,"date":"2017-12-02T20:08:29","date_gmt":"2017-12-02T20:08:29","guid":{"rendered":"http:\/\/www.onux.com\/jspp\/blog\/?p=483"},"modified":"2021-10-12T19:29:48","modified_gmt":"2021-10-12T19:29:48","slug":"the-template-method-pattern-and-final-methods","status":"publish","type":"post","link":"https:\/\/www.onux.com\/jspp\/blog\/the-template-method-pattern-and-final-methods\/","title":{"rendered":"Design Patterns: The Template Method Pattern and Final Methods"},"content":{"rendered":"<p>C# got it wrong. Java got it right.<\/p>\n<p>C# doesn&#8217;t let you &#8220;seal&#8221; methods that aren&#8217;t overridden. Java allows you to mark any method as &#8220;final&#8221; &#8211; whether it&#8217;s an overridden method or not. This subtle detail has interesting implications.<\/p>\n<p>The Gang of Four&#8217;s &#8220;<a href=\"https:\/\/www.amazon.com\/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook\/dp\/B000SEIBB8\" rel=\"noopener\" target=\"_blank\">Design Patterns: Elements of Reusable Object-Oriented Software<\/a>&#8221; was published in 1994&mdash;many years before C# was first released and just two years before Java was released. (Although, most of the code in the book was presented in C++.) The book presents the &#8220;Template Method&#8221; behavioral pattern. Template methods define the &#8220;framework&#8221; of an algorithm and leave subclasses to define the behavior. Unfortunately, if you cannot mark a template method as &#8216;final&#8217; (or &#8216;sealed&#8217; in C#), it enables subclasses to&mdash;potentially by accident&mdash;change the behavior of the template method.<\/p>\n<p>Here&#8217;s a template method in action, written in JS++, to demonstrate how this might be undesirable:<\/p>\n<pre class=\"brush:jspp\">\r\nabstract class Model\r\n{\r\n\tabstract public bool validate();\r\n\tabstract protected void saveTemplate(IDatabase db);\r\n\tpublic final void save(IDatabase db) {\r\n\t\tif (!this.validate()) {\r\n\t\t\tthrow new ValidationException();\r\n\t\t}\r\n\r\n\t\tthis.saveTemplate(db);\r\n\t}\r\n}\r\n<\/pre>\n<p>In the above class, the template method (&#8220;save&#8221;) is marked as &#8216;final&#8217;. Without &#8216;final&#8217;, an overriding method (or overwriting method, to use JS++ terminology) can potentially forget to perform business object validation before altering the database. This can lead to potential bugs and security threats.<\/p>\n<p>Beginning with the next release of JS++, you will be able to mark any method as &#8216;final&#8217;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C# got it wrong. Java got it right. C# doesn&#8217;t let you &#8220;seal&#8221; methods that aren&#8217;t overridden. Java allows you to mark any method as &#8220;final&#8221; &#8211; whether it&#8217;s an overridden method or not. This subtle detail has interesting implications. The Gang of Four&#8217;s &#8220;Design Patterns: Elements of Reusable Object-Oriented Software&#8221; was published in 1994&mdash;many &hellip; <a href=\"https:\/\/www.onux.com\/jspp\/blog\/the-template-method-pattern-and-final-methods\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Design Patterns: The Template Method Pattern and Final Methods&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,2],"tags":[],"_links":{"self":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/483"}],"collection":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/comments?post=483"}],"version-history":[{"count":6,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/483\/revisions"}],"predecessor-version":[{"id":1253,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/483\/revisions\/1253"}],"wp:attachment":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/media?parent=483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/categories?post=483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/tags?post=483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}