{"id":3624,"date":"2017-08-21T07:21:56","date_gmt":"2017-08-21T07:21:56","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=3624"},"modified":"2017-08-21T07:24:19","modified_gmt":"2017-08-21T07:24:19","slug":"code-complete-2-steve-mcconnell-working-classes","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/books\/programming\/code-complete-2-steve-mcconnell-working-classes\/","title":{"rendered":"Code Complete 2 &#8211; Steve McConnell &#8211; Working Classes"},"content":{"rendered":"<p>I just love Steve McConnell&#8217;s classic book <a href=\"http:\/\/amzn.to\/2vdwv5v\">Code Complete 2<\/a>, and I recommend it to everyone in the Software &#8216;world&#8217; who&#8217;s willing to progress and sharpen his skills.<\/p>\n<p>Other blog posts in this series:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/books\/programming\/code-complete-2-steve-mcconnell-part-1-laying-foundation\/\">Part 1: Laying the Foundation<\/a><\/li>\n<li><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/books\/programming\/code-complete-2-steve-mcconnell-design-construction\/\">Chapter 5: Design in Construction<\/a><\/li>\n<\/ul>\n<h2>Class Foundations: Abstract Data Types (ADTs)<\/h2>\n<p>An abstract data type is a collection of data and operations that work on that data. The operations both describe the data to the rest of the program and allow the rest of the program to change the data.<br \/>\nFor example, if you are not using ADTs to change a bold property of text you could write something like:<\/p>\n<p><code>currentFont.bold = true;<\/code><\/p>\n<p>but a better way, which keeps the abstraction of the class, is:<\/p>\n<p><code>currentFont.SetBoldOn();<\/code><\/p>\n<blockquote><p>\n  It ain&#8217;t abstract if you have to look at the underlying implementation to understand what&#8217;s going on. ~ P.J. Plauger\n<\/p><\/blockquote>\n<p>By thinking about ADT, and not about classes, we are programming <strong>into<\/strong> the language and not programming <strong>in<\/strong> language.<\/p>\n<p>If a stack represents a set of employees, treat the ADT as employees rather than as a stack. <strong>Treat yourself to the highest possible level of abstraction.<\/strong><\/p>\n<p>Try to make the names of classes and access routines independent of how the data is stored.<\/p>\n<p>For example:<\/p>\n<p><code>game.save()<\/code><\/p>\n<p>is better than<\/p>\n<p><code>game.saveDataInFile()<\/code><\/p>\n<p>One way to think of a class is as an <strong>abstract data type<\/strong> plus <strong>inheritance<\/strong> and <strong>polymorphism<\/strong>.<\/p>\n<h2>Good class interface<\/h2>\n<p>The first and probably most important step in creating a high-quality class is creating a good interface. This consists of creating a good abstraction for the interface to represent and ensuring the details remain hidden behind the abstraction.<\/p>\n<p><strong>If the class interface doesn&#8217;t present a consistent abstraction, then the class has poor cohesion.<\/strong><\/p>\n<blockquote><p>\n  Class interface consists of public routines (functions, methods)\n<\/p><\/blockquote>\n<p>Each class should implement one ADT!<\/p>\n<p>In some cases, you\u2019ll find that half a class\u2019s routines work with half the class\u2019s data, and half the routines work with the other half of the data. In such a case, you really have two classes masquerading as one. Break them up!<\/p>\n<blockquote><p>\n  Move unrelated information to another class\n<\/p><\/blockquote>\n<h2>Good Encapsulation<\/h2>\n<p>Encapsulation is a stronger concept than abstraction.<br \/>\nAbstraction helps to manage complexity by providing models that allow you to ignore implementation details. <strong>Encapsulation is the enforcer that prevents you from looking at the details even if you want to.<\/strong><\/p>\n<h3>Don&#8217;t expose  member data in public<\/h3>\n<p>You shouldn&#8217;t expose data like this:<\/p>\n<pre><code>float x;\nfloat y;\n<\/code><\/pre>\n<p>because client code can <em>monkey around<\/em> with data. And perfect encapsulation would look like:<\/p>\n<pre><code>float GetX();\nfloat GetY();\nvoid SetX( float x );\nvoid SetY( float y );\n<\/code><\/pre>\n<p>Now you have no idea whether the underlying implementation is in terms of floats x, y, whether the class is storing those items as doubles and converting them to floats, or whether the class is storing them on the moon and retrieving them from a satellite in outer space. ?<\/p>\n<h3>Avoid friend classes<\/h3>\n<p>In a few circumstances such as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/State_pattern\">State pattern<\/a>, friend classes can be used in a disciplined way that contributes to managing complexity. But, in general, friend classes violate encapsulation. They expand the amount of code you have to think about at any one time, increasing complexity.<\/p>\n<h2>Design and Implementation Issues<\/h2>\n<h3>Containment (&#8220;has a&#8221; Relationships)<\/h3>\n<p>Containment is a simple idea that a class contains a primitive data element or object. A lot more is written about inheritance than about containment, <strong>but that\u2019s because inheritance is more tricky and error prone, not because it\u2019s better<\/strong>.<\/p>\n<h3>Inheritance (&#8220;is a&#8221; Relationships)<\/h3>\n<blockquote><p>\n  Don&#8217;t inherit a class instead it&#8217;s a truly &#8220;is a&#8221; more specific version of the <strong>Base Class<\/strong>. ~ Barbara Liskov\n<\/p><\/blockquote>\n<p>Inherited routines come in three basic <em>flavors<\/em>:<br \/>\n+ <strong>An Abstract overridable routine<\/strong> means that the derived class inherits the routine&#8217;s interface but not its implementation.<br \/>\n+ <strong>Overridable routine<\/strong> means that the derived class inherits the routine&#8217;s interface but not its implementation<\/p>\n<blockquote><p>\n  Overridable routine -> polymorphism<br \/>\n  + <strong>A non-overridable routine<\/strong> means that the derived class inherits the routine&#8217;s interface and its default implementation and it is not allowed to override the routine&#8217;s implementation<\/p>\n<p>  Don&#8217;t reuse names of non-overridable base-class routines in derived classes.\n<\/p><\/blockquote>\n<h3>Avoid deep inheritance trees<\/h3>\n<p>Deep inheritance trees have been found to be significantly associated with increased fault rates. That&#8217;s because of deep inheritance trees <strong>increase complexity<\/strong>, which is exactly the opposite of what inheritance should be used to accomplish.<\/p>\n<blockquote><p>\n  7\u00b12 subclasses from base class, and maximum of three levels of inheritance\n<\/p><\/blockquote>\n<h2>Rules for inheritance<\/h2>\n<ul>\n<li>If multiple classes share common data but not behavior, create a common object that those classes can contain.<\/li>\n<li>If multiple classes share common behavior but not data, derive them from a common base class that defines the common routines.<\/li>\n<li>If multiple classes share common data and behavior, inherit from a common base class that defines the common data and routines.<\/li>\n<li>Inherit when you want the base class to control your interface; contain when you want to control your interface.<\/li>\n<\/ul>\n<h3>Law of Demeter<\/h3>\n<p>The rule states that Object A can call any of its own routines. If Object A instantiates an Object B, it can call any of Object B&#8217;s routines. But it should avoid calling routines on objects provided by Object B.<\/p>\n<h3>Constructors<\/h3>\n<p><strong>Initialize all member data in all constructors, if possible<\/strong>. Initializing all data member in all constructors is an inexpensive defensive programming practice.<\/p>\n<p><strong>Enforce the singleton property by using a private constructor<\/strong>. If you want to define a class that allows only one object to be instantiated, you can enforce this by hiding all the constructors of the class and then providing a <em>static GetInstance()<\/em> routine to access the class&#8217;s single instance.<\/p>\n<h3>Deep and shallow copy<\/h3>\n<ul>\n<li><strong>Deep copies<\/strong> are simpler to code and maintain than shallow copies<\/li>\n<li><strong>Shallow copies<\/strong> are created typically to improve performance<\/li>\n<\/ul>\n<blockquote><p>\n  Prefer deep copies to shallow copies until proven otherwise.\n<\/p><\/blockquote>\n<h3>Reasons to Create a Class<\/h3>\n<p>Create a class to hide information so that you won&#8217;t have to think about it and to <strong>reduce complexity<\/strong>. Sure, you will need to think about it when you write the class, but after it&#8217;s written you can forget about the implementation details and use the class without any knowledge of its internal workings.<\/p>\n<h2>Key points<\/h2>\n<ul>\n<li>Class interface should provide a consistent abstraction. Many problems arise from violating this single principle.<\/li>\n<li>Classes must have data members and behavior<\/li>\n<li>Containment is usually preferable to inheritance unless you&#8217;re modeling an &#8220;is a &#8220;relationship<\/li>\n<li>Inheritance is a useful tool, but it adds complexity, which is counter to Software&#8217;s Primary Technical Imperative of managing complexity<\/li>\n<\/ul>\n<blockquote class=\"twitter-tweet\" data-width=\"550\">\n<p lang=\"en\" dir=\"ltr\">My <a href=\"https:\/\/twitter.com\/hashtag\/notes?src=hash\">#notes<\/a> from the classic Code Complete 2 <a href=\"https:\/\/twitter.com\/hashtag\/book?src=hash\">#book<\/a> by Steve McConnell chapter 5: Working Classes <a href=\"https:\/\/t.co\/aWK3uWdBUr\">https:\/\/t.co\/aWK3uWdBUr<\/a><\/p>\n<p>&mdash; Nikola Bre\u017enjak (@HitmanHR) <a href=\"https:\/\/twitter.com\/HitmanHR\/status\/899532337444245504\">August 21, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I just love Steve McConnell&#8217;s classic book Code Complete 2, and I recommend it to everyone in the Software &#8216;world&#8217; who&#8217;s willing to progress and sharpen his skills.&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3572,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[],"class_list":["post-3624","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=3624"}],"version-history":[{"count":3,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3624\/revisions"}],"predecessor-version":[{"id":3627,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/3624\/revisions\/3627"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/3572"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=3624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=3624"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=3624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}