{"id":371,"date":"2024-10-08T18:29:27","date_gmt":"2024-10-08T18:29:27","guid":{"rendered":"https:\/\/permutationcity.co.uk\/bp\/?p=371"},"modified":"2024-10-01T19:01:17","modified_gmt":"2024-10-01T19:01:17","slug":"the-law-of-demeter","status":"publish","type":"post","link":"https:\/\/permutationcity.co.uk\/bp\/2024\/10\/08\/the-law-of-demeter\/","title":{"rendered":"The Law of Demeter"},"content":{"rendered":"\n<p>I&#8217;ve been doing some more reading and came across the\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Law_of_Demeter\">Law of Demeter<\/a> and train wrecks again.\nThe last time while while reading\n<a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/03\/14\/clean-code\/#objects-and-data-structures\">Clean Code<\/a>.<\/p>\n\n\n\n<p>I&#8217;ve one book that tells me this is bad practice:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">    const auto path = context.GetOptions().GetScratchDirectory().GetAbsolutePath();<\/pre><\/div>\n\n\n\n<p>And that I should do this instead:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">    const auto options = context.GetOptions();\n    const auto directory = options.GetScratchDirectory();\n    const auto path = directory.getAbsolutePath();<\/pre><\/div>\n\n\n\n<p>My feeling was to prefer the first as more compact here and\nit avoids turning a simple context wrapper into a heavyweight class.\nNow another book that tells me that <em>both<\/em> are bad.\nIt doesn&#8217;t feel like there was too much to back either up.\nI&#8217;ll dig in to it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"loose-coupling-and-the-law\">Loose coupling and the law<\/h2>\n\n\n\n<p>The law is a specific case of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Loose_coupling\">loose coupling<\/a>.\nThe general goal with loose coupling is to ensure that components make use of little or\nno internal knowledge about other components.\nThat allows each component to be changed with little or no impact on other components.\nWith Demeter it&#8217;s specifically about a method <em>M<\/em> within a class <em>C<\/em> and what it can interact with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Other instances methods in C<\/li>\n\n\n\n<li>The parameters of M<\/li>\n\n\n\n<li>Methods in objects that it creates<\/li>\n\n\n\n<li>Global variables<\/li>\n<\/ul>\n\n\n\n<p>Roughly speaking that means we should not reach through a series of other methods or\nclasses to do something because that requires knowledge of each system along the way.\nThis was initially devised in the 1980s and so global variables were more of a thing.\nThat&#8217;s likely to be discounted today.<\/p>\n\n\n\n<p>The first code sample with method call after method call gets called <em>train wrecks<\/em> because they look like a bunch of coupled train cars. It&#8217;s considered bad because it links the calling code to code several steps away. The second code sample is <em>also<\/em> considered bad for the same reason, it is just spread out over more lines.<\/p>\n\n\n\n<p>Clean Code notes that this is particular to classes and method calls so that\naccess structures is considered okay:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C++&quot;,&quot;language&quot;:&quot;C++&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">    const auto path = context.options.scratchDirectory.absolutePath;<\/pre><\/div>\n\n\n\n<p>On the face of it loose coupling makes sense. One component should be able to use another without detailed knowledge of it&#8217;s internals. Ideally an interface should make certain guarantees about what it provides but not <em>how<\/em> it provides them. This law allows the set of methods callable directly from the start point but nothing else. You could not make components any less connected than this. However technically that could still involve many things. It all depends on how many parameters and other instance methods there are. To me it ends up feeling somewhat arbitrary. Many things have pros and cons and going to one extreme may not be right.<\/p>\n\n\n\n<p>Wikipedia claims that it makes code that is more\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Law_of_Demeter#advantages\">maintainable and adaptable<\/a> but\nwithout references.\nIt goes on to suggest that calling a method with invoke fewer sub-methods but\neach class will end up with more methods,\nthese decrease and increase the probability of bugs respectively.\nSo that seems to be a wash as well.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"on-balance\">On balance<\/h2>\n\n\n\n<p>While loose coupling sounds good I can&#8217;t say the same about the specifics of the Law of Demeter.<\/p>\n\n\n\n<p>Most of the examples I&#8217;ve seen shows a &#8220;train wreck&#8221; which is being used to access a relative slim set of interfaces. After they&#8217;ve &#8220;fixed it&#8221; the interfaces are much bulkier and the intermediate level is full of code that just exists pass things down to lower levels. It does mean that you can swap out the lower level and only have to change one file\u2026 Is that even a great benefit if you have ownership of all levels?<\/p>\n\n\n\n<p>For me it feels like how many method calls are in a chain might be a distraction. I think it&#8217;s better to worry about whether classes and methods have distinct responsibilities instead. Classes encapsulate data and are responsible for it. That doesn&#8217;t just mean containing that data but performing the necessary calculations on it as well. In that case more of the information is likely to be local and therefore there will be few or smaller chains, reducing coupling.<\/p>\n\n\n\n<p>If you do have a chain consider <em>what<\/em> it does and <em>where<\/em> it goes. Some classes cluster together and it feels okay that they should be talking to each other. Other classes are simple wrappers around read-only data, such as the <code>options<\/code> above, and increase coupling but are unlikely to cause bugs. If you have a chain that changes the state of other objects that is more likely to cause problems. All the more likely if that object is in some sense distant. Is it on a different server, manage by a different team or company? Anywhere there is an interface between systems it does make sense to slow down and think about them again.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been doing some more reading and came across the Law of Demeter and train wrecks again. The last time while while reading Clean Code. I&#8217;ve one book that tells me this is bad practice: And that I should do this instead: My feeling was to prefer the first as more compact here and it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[1],"tags":[20,8],"class_list":["post-371","post","type-post","status-publish","format-standard","hentry","category-general","tag-books","tag-standards"],"_links":{"self":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/371","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/comments?post=371"}],"version-history":[{"count":2,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/371\/revisions"}],"predecessor-version":[{"id":376,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/371\/revisions\/376"}],"wp:attachment":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/media?parent=371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/categories?post=371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/tags?post=371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}