{"id":5,"date":"2011-09-17T00:36:15","date_gmt":"2011-09-17T00:36:15","guid":{"rendered":"http:\/\/www.lexicalscope.com\/blog\/?p=5"},"modified":"2011-09-17T02:04:49","modified_gmt":"2011-09-17T02:04:49","slug":"fail-fast-fail-durring-compile","status":"publish","type":"post","link":"https:\/\/www.lexicalscope.com\/blog\/2011\/09\/17\/fail-fast-fail-durring-compile\/","title":{"rendered":"Fail Fast &#8211; Fail During Compile"},"content":{"rendered":"<p>One of the fastest ways for faulty software to fail is at compile time. <\/p>\n<p>Here is an example of <strong>slow<\/strong> failing code, it will fail at runtime if it comes across an implementation of <code>A<\/code> that it did not expect. This can happen if a developer adds a new implementation of <code>A<\/code> but forgets to update this code (or is not aware of it, or it is located in some other dependent library).<\/p>\n<pre lang=\"java\">\r\ninterface A { }\r\nclass B implements A { }\r\nclass C implements A { }\r\n\r\nvoid doSomething(A a) {\r\n   \/\/ not recommend\r\n   if(a instanceof B) {\r\n      doMyBThings((B) a);\r\n   } else if(a instanceof C) {\r\n      doMyCThings((C) a);\r\n   } else {\r\n      throw IllegalArgumentException(\"unexpected kind of A\");\r\n   }\r\n}\r\n<\/pre>\n<p>One way to move these failures to compile time would be to move the responsibility for doing my <code>B<\/code> things and doing my <code>C<\/code> things on to the classes <code>B<\/code> and <code>C<\/code> respectively.<\/p>\n<pre lang=\"java\">\r\ninterface A { void doMyThings(); }\r\nclass B implements A { void doMyThings(){ \/* do my B things *\/ } }\r\nclass C implements A { void doMyThings(){ \/* do my C things *\/ } }\r\n\r\nvoid doSomething(A a) {\r\n   a.doMyThings();\r\n}\r\n<\/pre>\n<p>If I add a new type <code>D<\/code> the compiler forces us to implement <code>doMyThings()<\/code>  <\/p>\n<pre lang=\"java\">\r\nclass D implements A { void doMyThings(){ \/* do my D things *\/ } }\r\n<\/pre>\n<p>Sometimes it is not appropriate to put the responsibility to <code>doMyThings()<\/code> onto <code>A<\/code>. It might create undesirable coupling (a dependency) or have some other undesirable property. I can maintain the fail fast property in in other ways.<\/p>\n<pre lang=\"java\">\r\ninterface A { void doThings(Things things); }\r\nclass B implements A { void doThings(Things things){ things.doBThings(this); } }\r\nclass C implements A { void doThings(Things things){ things.doCThings(this); } }\r\n\r\ninterface Things {\r\n      void doBThings(B b);\r\n      void doCThings(C c);\r\n}\r\n\r\nvoid doSomething(A a) {\r\n   a.doThings(new Things(){\r\n      void doBThings(B b){ \/* do my B things *\/}\r\n      void doCThings(C c){ \/* do my C things *\/}\r\n   });\r\n}\r\n<\/pre>\n<p>Adding a new type <code>D<\/code>, the compiler forces me to implement <code>doThings<\/code> on <code>D<\/code>, which leads me to add a new method onto the Things interface, which forces any implementers of Things to handle <code>D<\/code> types. <\/p>\n<pre lang=\"java\">\r\nclass D implements A { void doThings(Things things){ things.doDThings(this); } }\r\n\r\ninterface Things {\r\n      void doBThings(B b);\r\n      void doCThings(C c);\r\n      void doDThings(D d);\r\n}\r\n\r\nvoid doSomething(A a) {\r\n   a.doThings(new Things(){\r\n      void doBThings(B b){ \/* do my B things *\/}\r\n      void doCThings(C c){ \/* do my C things *\/}\r\n      void doDThings(D d){ \/* do my D things *\/}\r\n   });\r\n}\r\n<\/pre>\n<p>However, a user might not want to handle every new implementation of <code>A<\/code>, I can provide default implementations of the methods:  <\/p>\n<pre lang=\"java\">\r\nclass BaseThings implements Things {\r\n      void doBThings(B b) { };\r\n      void doCThings(C c) { };\r\n}\r\n\r\nvoid doSomething(A a) {\r\n   a.doThings(new BaseThings(){\r\n      void doBThings(B b){ \/* do my B things *\/}\r\n      void doCThings(C c){ \/* do my C things *\/}\r\n   });\r\n}\r\n<\/pre>\n<p>When I add <code>D<\/code> I also add a default implementation, so I do not have to add any new handling code:<\/p>\n<pre lang=\"java\">\r\nclass BaseThings implements Things {\r\n      void doBThings(B b) { };\r\n      void doCThings(C c) { };\r\n      void doDThings(D d) { };\r\n}\r\n\r\nvoid doSomething(A a) {\r\n   a.doThings(new BaseThings(){\r\n      void doBThings(B b){ \/* do my B things *\/}\r\n      void doCThings(C c){ \/* do my C things *\/}\r\n   });\r\n}\r\n<\/pre>\n<p>I can choose to either have my code break when new implementations of <code>A<\/code> are added (by extending <code>Things<\/code>) or not to break (by extending <code>BaseThings<\/code>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the fastest ways for faulty software to fail is at compile time. Here is an example of slow failing code, it will fail at runtime if it comes across an implementation of A that it did not expect. &hellip; <a href=\"https:\/\/www.lexicalscope.com\/blog\/2011\/09\/17\/fail-fast-fail-durring-compile\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[4,3],"tags":[],"class_list":["post-5","post","type-post","status-publish","format-standard","hentry","category-patterns","category-safety"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2e3P7-5","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/posts\/5","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/comments?post=5"}],"version-history":[{"count":10,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/posts\/5\/revisions"}],"predecessor-version":[{"id":33,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/posts\/5\/revisions\/33"}],"wp:attachment":[{"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/media?parent=5"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/categories?post=5"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lexicalscope.com\/blog\/wp-json\/wp\/v2\/tags?post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}