{"componentChunkName":"component---node-modules-gatsby-theme-medium-to-own-blog-src-templates-blog-post-js","path":"/inheritance-is-not-oo-template-methods-are-evil/","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://javame.netlify.app","githubUrl":"https://github.com/aterreno/blog"}},"mdx":{"fields":{"slug":"/inheritance-is-not-oo-template-methods-are-evil/"},"excerpt":"My first coach  Bruno  always said that Inheritance doesn’t imply Object Oriented and he’s absolutely right. An abstract class necessarily…","timeToRead":2,"frontmatter":{"title":"Inheritance is not OO, template methods are evil","description":"","categories":[],"date":"July 21, 2007","canonical_link":"https://javame.netlify.app//inheritance-is-not-oo-template-methods-are-evil-c3a28d4902ce"},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Inheritance is not OO, template methods are evil\",\n  \"description\": \"\",\n  \"date\": \"2007-07-21T00:00:00.000Z\",\n  \"categories\": [],\n  \"published\": true,\n  \"canonical_link\": \"https://javame.netlify.app//inheritance-is-not-oo-template-methods-are-evil-c3a28d4902ce\",\n  \"redirect_from\": [\"/inheritance-is-not-oo-template-methods-are-evil-c3a28d4902ce\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"My first coach \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://bbossola.wordpress.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Bruno\"), \" always said that Inheritance doesn\\u2019t imply Object Oriented and he\\u2019s absolutely right. An abstract class necessarily implies inheritance and I really don\\u2019t like abstract classes! I rather prefer to use dependency injection, inheritance between classes just leads to the highest level of coupling that you can introduce.\"), mdx(\"p\", null, \"Right after the university I was abusing of it, then day by day fortunately I started to use interfaces rather than that. It\\u2019s strange, looks like that at the university they really love that kind of stuff, I was doing some code reviews in the last weeks for new graduates applying to TW, you know what: a good number of them were (ab)using of abstract classes with no sense, instead of using Interfaces.\"), mdx(\"p\", null, \"A common usage of abstract class is for template methods pattern, \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://www.martinfowler.com\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Martin\"), \" wrote \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://www.martinfowler.com/bliki/CallSuper.html\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"an article\"), \" about this already. I really hate any framework that forces you to call a super implementation. What about the design of Junit 3! What about Struts Actions!!! What\\u2019s doing the super class? Why do I have to call super (base) something? It just smells.\"), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://tech.puredanger.com/2007/07/03/pattern-hate-template/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Here\"), \" there\\u2019s a good article by \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://tech.puredanger.com/about/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Alex Miller\"), \" on how to remove template methods and why template methods are evil, I just can\\u2019t add nothing more.\"), mdx(\"p\", null, \"But what to do then, when you need to call something before or after? Aspects maybe, Interceptors, Annotations (Java),\\xC2 Attributes(C#).\"), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://testng.org/doc/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"TestNG\"), \" has some really interesting annotations like the BeforeClass:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"package example1;\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"import org.testng.annotations.\", \"*\", \";\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public class SimpleTest {\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"@BeforeClass\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public void setUp() {\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"}\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"@Test(groups = { \\u201Cfast\\u201D })\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public void aFastTest() {\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"System.out.println(\\u201CFast test\\u201D);\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"}\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"@Test(groups = { \\u201Cslow\\u201D })\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public void aSlowTest() {\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"System.out.println(\\u201CSlow test\\u201D);\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"}\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"}\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://aspectwerkz.codehaus.org/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Aspectwerkz\"), \" is AOP with annotations, so, here an example:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"package testAOP;\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"import org.codehaus.aspectwerkz.joinpoint.JoinPoint;\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public class MyAspectWithAnnotations {\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"/\", \"*\", \"*\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"\", \"*\", \" @Before execution(\", \"*\", \" testAOP.HelloWorld.greet(..))\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"\", \"*\", \"/\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public void beforeGreeting(JoinPoint joinPoint) {\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"System.out.println(\\u201Cbefore greeting\\u2026\\u201D);\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"}\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"/\", \"*\", \"*\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"\", \"*\", \" @After execution(\", \"*\", \" testAOP.HelloWorld.greet(..))\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"\", \"*\", \"/\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"public void afterGreeting(JoinPoint joinPoint) {\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"System.out.println(\\u201Cafter greeting\\u2026\\u201D);\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"}\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"}\")), mdx(\"p\", null, \"Spring is also another well known framework that plays with this stuff, in the reference guide they say:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"So much for the pros and cons of each style then: which is best? If you are not using Java5 (or above) then\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"clearly the XML-style is the best because it is the only option available to you. If you are using Java5+, then\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"you really will have to come to your own decision as to which style suits you best. In the experience of the\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"Spring team, we advocate the use of the @AspectJ style whenever there are aspects that do more than simple\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"\\u201Cconfiguration\\u201D of enterprise services. If you are writing, have written, or have access to an aspect that is not\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"part of the business contract of a particular class (such as a tracing aspect), then the XML-style is better.\")), mdx(\"p\", null, \"I\\u2019m not sure about this, xml writing is voluntarily not supported by this blog syntax highlighter, so I\\u2019m not pasting any example\\xA0:-D\"), mdx(\"p\", null, \"So, finally, the tip is, \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"do not extend, implement\"), \".\"));\n}\n;\nMDXContent.isMDXComponent = true;"},"allWebMentionEntry":{"nodes":[]}},"pageContext":{"id":"37a02916-d612-541b-80c6-d68bee360327","previous":{"id":"82f8abd9-5fe4-5fb3-aca5-bd30f7f17e1a","fields":{"slug":"/pragmatic-tips-on-wordpress/","published":true},"frontmatter":{"redirect_from":["/pragmatic-tips-on-wordpress-b4925d4a7c33"],"redirect_to":null,"title":"Pragmatic tips on wordpress"}},"next":{"id":"34bc7ec0-e4e7-5b50-aa8a-f257e722d275","fields":{"slug":"/what-if-apple-has-sold-fewer-than-1-million-iphones/","published":true},"frontmatter":{"redirect_from":["/what-if-apple-has-sold-fewer-than-1-million-iphones-d4ce9371e60"],"redirect_to":null,"title":"What If Apple Has Sold Fewer Than 1 Million iPhones?"}},"permalink":"https://javame.netlify.app/inheritance-is-not-oo-template-methods-are-evil/","themeOptions":{"plugins":[],"config":{"title":"Antonio Terreno","description":"Antonio Terreno's blog archive","shortBio":"","bio":"Principal Consultant at Equal Experts","author":"Antonio Terreno","githubUrl":"https://github.com/aterreno/blog","siteUrl":"https://javame.netlify.app/","social":{"twitter":"javame","medium":"","facebook":"","github":"aterreno","linkedin":"antonioterreno","instagram":"tritonitri"},"goatCounterCode":null}}}},"staticQueryHashes":["4131332129","645483741"]}