1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <title>SOLID Design Principles | Object Oriented Design</title> 5 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <meta name="title" content="SOLID Design Principles" /> 9 <meta name="author" content="oodesign" /> 10 <meta name="description" content="The five SOLID principles, essential in object-oriented design, include: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation and Dependency Inversion. These principles are still highly valid and relevant, providing a framework for developing software that is easy to maintain and extend. " /> 11 <meta name="keywords" content="SOLID Design Principles, Software Design Principles, Design Patterns, Design Principles, Object Oriented Design, Java, C#, VB, Software Design Principles, Open Close Principle, Dependency Inversion Principle ,Interface Segregation Principle, Single Responsibility Principle, Liskov's Substitution Principle" /> 12 13 <meta name="Generator" content="Joomla! - Copyright (C) 2005 - 2006 Open Source Matters. All rights reserved." /> 14 <meta name="robots" content="index, follow" /> 15 16 <link rel="shortcut icon" href="https://www.oodesign.com/images/favicon.ico" /> 17 <link rel="amphtml" href="https://www.oodesign.com/amp/design-principles/"> 18 <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css" as="style" onload="this.rel='stylesheet'"> 19 <!--link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css" media="none" onload="if(media!='all')media='all'"--> 20
20<script async src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" onload="hljs.initHighlightingOnLoad();"></script>
20 21 <!--link rel='stylesheet' href='static/style.css' type='text/css' media='all' onload="if(media!='all')media='all'" /--> 22 <link rel="preload" href="/static/style.css" as="style" onload="this.rel='stylesheet'"> 23 24 <link rel="canonical" href="https://www.oodesign.com/design-principles/" /> 25 <base href="https://www.oodesign.com/"> 26 27 <style type="text/css"> 28 body { 29 font-size: 1rem; 30 font-family: Verdana; 31 color: #222; 32 margin: 0; 33 background: #D9E2D7; 34 } 35 36 .header{ 37 38 background-image: url(https://www.oodesign.com/templates/oodesign7/images/oo-design-header.jpg); 39 height:80px; 40 } 41 42 .container{ 43 margin: 0 auto; 44 } 45 46 .column-left { 47 float: left; 48 width: 178px; 49 padding-right:5px; 50 51 } 52 .column-center { 53 float: left; 54 55 } 56 .column-right { 57 float: left; 58 width: 172px; 59 padding-left:5px; 60 } 61 62 /* Clear floats after the columns */ 63 .row:after { 64 content: ""; 65 display: table; 66 clear: both; 67 } 68 69 .container {width: 1297px;} 70 71 .column-center {width: 850px;} 72 .column-left { width:254px;} 73 74 75 .tbl { 76 margin-top: 5px; 77 padding: 5px; 78 border: 1px solid #73786B; 79 background: #D9DBD2; 80 color: #000000; 81 } 82 .column-module { 83 margin-top: 5px; 84 margin-bottom: 5px; 85 padding-bottom: 3px; 86 border: 1px solid #73786B; 87 background: #B7CBD5; 88 line-height:1.5; 89 } 90 91 92 .column-module-header { 93 background-color: #007a98; 94 border-bottom: 1px solid #000000; 95 color: #ffffff; 96 font-weight: bold; 97 padding-top: 3px; 98 vertical-align: middle; 99 text-align: left; 100 padding-left: 15px; 101 min-height:18px; 102 } 103 104 a:link, a:visited { 105 color: #000000; 106 } 107 108 @media only screen and (max-width : 990px), 109 only screen and (max-device-width : 990px){ 110 .container {width: 100%;} 111 .column-center {width: 100%;} 112 .column-left { display:none;position:fixed;} 113 .column-right { width:100%;padding-left:0;} 114 .column-module-header { min-height:30px;} 115 .menu-button { display:inline-block;} 116 .closebtn {display:block;} 117 118 119 } 120 121 @media only screen and (max-width : 720px), 122 only screen and (max-device-width : 720px){ 123 .container {width: 100%;} 124 .column-center {width: 100%;} 125 .column-left { display:none;position:fixed;} 126 .column-right { width:100%;padding-left:0;} 127 .column-module-header { min-height:30px;} 128 .menu-button { display:inline-block;} 129 .closebtn {display:block;} 130 } 131 132 133 134 pre{ 135 overflow-x:auto; 136 } 137 138 139 140 </style> 141
141<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
141 142
142<script> 143 (adsbygoogle = window.adsbygoogle || []).push({ 144 google_ad_client: "ca-pub-4452501840155972", 145 enable_page_level_ads: true 146 }); 147 </script>
147 148</head> 149<body> 150 <div class="container"> 151 <div class="header"> 152 </div> 153 <div class="row"> 154 <div class="column-left" id="column-left"> 155 <div class="column-module"> 156 <div class="column-module-header"> 157 Main Menu 158 <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a> 159 </div> 160 <ul> 161 <li><a href="https://www.oodesign.com/" class="mainlevel">Home</a></li> 162 <li class="selected"><a href="https://www.oodesign.com/design-principles/"><b>Design Principles</b></a></li> 163 <li> 164 <ul> 165 <li><a href="https://www.oodesign.com/single-responsibility-principle/"><b>S</b>ingle Responsibility Principle</a></li> 166 <li><a href="https://www.oodesign.com/open-closed-principle/"><b>O</b>pen Closed Principle</a></li> 167 <li><a href="https://www.oodesign.com/liskov-s-substitution-principle/"><b>L</b>iskov's Substitution Principle</a></li> 168 <li><a href="https://www.oodesign.com/interface-segregation-principle/"><b>I</b>nterface Segregation Principle</a></li> 169 <li><a href="https://www.oodesign.com/dependency-inversion-principle/"><b>D</b>ependency Inversion Principle</a></li> 170 </ul> 171 </li> 172 <li><a href="https://www.oodesign.com/creational-patterns/"><b>Creational Patterns</b></a></li> 173 <li> 174 <ul> 175 <li><a href="https://www.oodesign.com/singleton-pattern/">Singleton</a></li> 176 <li><a href="https://www.oodesign.com/factory-pattern/">Factory</a></li> 177 <li><a href="https://www.oodesign.com/factory-method-pattern/">Factory Method</a></li> 178 <li><a href="https://www.oodesign.com/abstract-factory-pattern/" id="active_menu">Abstract Factory</a></li> 179 <li><a href="https://www.oodesign.com/builder-pattern/">Builder</a></li> 180 <li><a href="https://www.oodesign.com/prototype-pattern.html">Prototype</a></li> 181 <li><a href="https://www.oodesign.com/object-pool-pattern/">Object Pool</a></li> 182 </ul> 183 </li> 184 <li><a href="https://www.oodesign.com/behavioral-patterns/"><b>Behavioral Patterns</b></a></li> 185 <li> 186 <ul> 187 <li><a href="https://www.oodesign.com/chain-of-responsibility-pattern/">Chain of Responsibility</a></li> 188 <li><a href="https://www.oodesign.com/command-pattern/">Command</a></li> 189 <li><a href="https://www.oodesign.com/interpreter-pattern/">Interpreter</a></li> 190 <li><a href="https://www.oodesign.com/iterator-pattern/">Iterator</a></li> 191 <li><a href="https://www.oodesign.com/mediator-pattern/">Mediator</a></li> 192 <li><a href="https://www.oodesign.com/memento-pattern/">Memento</a></li> 193 <li><a href="https://www.oodesign.com/observer-pattern/">Observer</a></li> 194 <li><a href="https://www.oodesign.com/strategy-pattern/">Strategy</a></li> 195 <li><a href="https://www.oodesign.com/template-method-pattern/">Template Method</a></li> 196 <li><a href="https://www.oodesign.com/visitor-pattern/">Visitor</a></li> 197 <li><a href="https://www.oodesign.com/null-object-pattern/">Null Object</a></li> 198 </ul> 199 </li> 200 <li><a href="https://www.oodesign.com/structural-patterns/" class="mainlevel"><b>Structural Patterns</b></a></li> 201 <li> 202 <ul> 203 <li><a href="https://www.oodesign.com/adapter-pattern/">Adapter</a></li> 204 <li><a href="https://www.oodesign.com/bridge-pattern/">Bridge</a></li> 205 <li><a href="https://www.oodesign.com/composite-pattern/">Composite</a></li> 206 <li><a href="https://www.oodesign.com/decorator-pattern/">
206Decorator</a></li> 207 <li><a href="https://www.oodesign.com/flyweight-pattern/">Flyweight</a></li> 208 <li><a href="https://www.oodesign.com/proxy-pattern/">Proxy</a></li> 209 </ul> 210 </li> 211 </ul> 212 </div> 213 </div><!-- end column-left --> 214 215 <div class="column-center"> 216 <div class="tbl"> 217 <span class="menu-button" style="cursor:pointer;background-color:#007a98;color:white;" onclick="openNav()"> ☰ Menu </span> 218 <a href="https://www.oodesign.com/">Home</a> 219 <span style="color:#85a49e">»</span> 220 Design Principles 221 </div> 222 <div class="tbl"> 223 224 <h1>SOLID Design Principles</h1> 225 <div style="width:275px;height:20px;padding-bottom:15px;margin-left:3px;"> 226 <div style="width:80px;height:20px;float:left;margin-right:15px;"> 227 <iframe src="https://www.facebook.com/plugins/like.php?href=https%3A%2F%2Foodesign.com%2Fdesign-principles%2F&layout=standard&show_faces=false&width=80&action=like&font&colorscheme=light&height=20&layout=button_count" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:80px; height:20px;" allowTransparency="true"></iframe> 228 </div> 229 </div> 230 231 232 233 234 235<h2>What are SOLID Design Principles?</h2> 236 237<P>SOLID design principles represent a set of guidelines that helps us to avoid a bad design when designing and developing software. The design principles are associated to Robert Martin who gathered them in "Agile Software Development: Principles, Patterns, and Practices". According to Robert Martin there are 3 important characteristics of a bad design that should be avoided:<P> 238<ul> 239 <li>Rigidity - It is hard to change because every change affects too many other parts of the system.</li> 240 <li>Fragility - When you make a change, unexpected parts of the system break.</li> 241 <li>Immobility - It is hard to reuse in another application because it cannot be disentangled from the current application.</li> 242</ul> 243 244<p>S.O.L.I.D - is a acronym based on name of the design principles in the collection:</p> 245 246<ul> 247 <li><a href="#single-responsibility-principle"><b>S</b>ingle Responsibility Principle</a></li> 248 <li><a href="#open-close-principle"><b>O</b>pen Close Principle</a></li> 249 <li><a href="#liskov-s-substitution-principle"><b>L</b>iskov's Substitution Principle</a></li> 250 <li><a href="#interface-segregation-principle"><b>I</b>nterface Segregation Principle</a></li> 251 <li><a href="#dependency-inversion-principle"><b>D</b>ependency Inversion Principle</a></li> 252 253</ul> 254 255 256<H2><a id="single-responsibility-principle"></a><a href="https://www.oodesign.com/single-responsibility-principle/">Single Responsibility Principle</a></H2> 257<I><ul> 258<li>A class should have only one reason to change.</li> 259</ul></I> 260<P>In this context a responsibility is considered to be one reason to change. This principle states that if we have 2 reasons to change for a class, we have to split the functionality in two classes. Each class will handle only one responsibility and on future if we need to make one change we are going to make it in the class which handle it. When we need to make a change in a class having more responsibilities the change might affect the other functionality of the classes.</P> 261<div style="max-width:800px"> 262 <img src="https://oodesign.com/images/solid-design-principles/single-responsibility-principle.png" style="aspect-ratio:1176/536;max-width:100%;" 263 alt="Single Responsibility Principle Diagram"> 264</div> 265<P>Single Responsibility Principle was introduced Tom DeMarco in his book Structured Analysis and Systems Specification, 1979. Robert Martin reinterpreted the concept and defined the responsibility as a reason to change.</P> 266 267 268<H2><a id="open-close-principle"></a><a href="https://www.oodesign.com/open-close-principle/">Open Close Principle</a></H2> 269<I><ul> 270<li>Software entities like classes, modules and functions should be <B>open for extension</B> but <B>closed for modifications.</B></li> 271</ul></I> 272<P>OPC is a generic principle. You can consider it when writing your classes to make sure that when you need to extend their behavior you don't have to change the class but to extend it. The same principle can be applied for modules, packages, libraries. If you have a library containing a set of classes there are many reasons for which you'll prefer to extend it without changing the code that was already written (backward compatibility, regression testing, '). This is why we have to make sure our modules follow Open Closed Principle.</P> 273<P>When referring to the classes Open Close Principle can be ensured by use of Abstract Classes and concrete classes for implementing their behavior. This will enforce having Concrete Classes extending Abstract Classes instead of changing them. Some particular cases of this are Template Pattern and Strategy Pattern.</P> 274 275<H2><a id="liskov-s-substitution-principle"></a><a href="https://www.oodesign.com/liskov-s-substitution-principle/">Liskov's Substitution Principle</a></H2> 276<I><ul> 277<li>Derived types must be completely substitutable for their base types.</li> 278</ul></I> 279<P>This principle is just an extension of the Open Close Principle in terms of behavior meaning that we must make sure that new derived classes are extending the base classes without changing their behavior. The new derived classes should be able to replace the base classes without any change in the code.</P> 280<div style="max-width:800px"> 281 <img src="/images/solid-design-principles/liskov-s-substitution-principle.png" style="aspect-ratio:1073/717;max-width:100%;" 282 alt="Liskov's Substitution Principle Diagram"> 283</div> 284<P>Liskov's Substitution Principle was introduced by Barbara Liskov in a 1987 Conference on Object Oriented Programming Systems Languages and Applications, in <A href="https://portal.acm.org/citation.cfm?id=62141">Data abstraction and hierarchy</A></P> 285 286<H2><a id="interface-segregation-principle"></a><a href="https://www.oodesign.com/interface-segregation-principle/">Interface Segregation Principle</a></H2> 287<I><ul> 288<li>Clients should not be forced to depend upon interfaces that they don't use.</li> 289</ul></I> 290<P>This principle teaches us to take care how we write our interfaces. When we write our interfaces we should take care to add only methods that should be there. If we add methods that should not be there the classes implementing the interface will have to implement those methods as well. For example if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot?</P> 291<div style="max-width:800px"> 292 <img src="/images/solid-design-principles/interface-segregation-principle.png" style="aspect-ratio:970/583;max-width:100%;" 293 alt="Interface Segregation Principle Diagram"> 294</div> 295<P>As a conclusion Interfaces containing methods that are not specific to it are called polluted or fat interfaces. We should avoid them.</P> 296 297 298<H2><a id="dependency-inversion-principle"></a><a href="https://www.oodesign.com/dependency-inversion-principle/">Dependency Inversion Principle</a></H2> 299<I><ul> 300<li>High-level modules should not depend on low-level modules. Both should depend on abstractions.</li> 301<li>Abstractions should not depend on details. Details should depend on abstractions.</li> 302</ul></I> 303<P>Dependency Inversion Principle states that we should decouple high level modules from low level modules, introducing an abstraction layer between the high level classes and low level classes. Further more it inverts the dependency: instead of writing our abstractions based on details, the we should write the details based on abstractions.</P> 304 305<div style="max-width:800px"> 306 <img src="/images/solid-design-principles/dependency-inversion-principle.png" style="aspect-ratio:1070/583;max-width:100%;" 307 alt="Dependency Inversion Principle Diagram"> 308</div> 309 310<P>Dependency Inversion or Inversion of Control are better know terms referring to the way in which the dependencies are realized. In the classical way when a software module(class, framework, ') need some other module, it initializes and holds a direct reference to it. This will make the 2 modules tight coupled. In order to decouple them the first module will provide a hook(a property, parameter, ') and an external module controlling the dependencies will inject the reference to the second one.</P> 311<P>By applying the Dependency Inversion the modules can be easily changed by other modules just changing the dependency module. Factories and Abstract Factories can be used as dependency frameworks, but there are specialized frameworks for that, known as Inversion of Control Container.</P> 312 313 314 315 316 317 318 <div style="max-width:1050px;margin:0 auto;"> 319
319<script type="text/javascript"><!-- 320 google_ad_client = "ca-pub-4452501840155972"; 321 /* oodesign-leaderboard-principles */ 322 google_ad_slot = "6030003693"; 323 google_ad_width = 728; 324 google_ad_height = 90; 325 //--> 326 </script>
326 327
327<script type="text/javascript" 328 src="https://pagead2.googlesyndication.com/pagead/show_ads.js"> 329 </script>
329 330 </div> 331 332 333 334 335 336 337 338 339 340 341 <div class="pagenav-container"> 342 <span class="pagenav-left"><a href="https://www.oodesign.com/">< Design Patterns</a></span> 343 <span class="pagenav-right"><a href="https://www.oodesign.com/single-responsibility-principle/">Single Responsibility Principle ></a></span> 344 <div style="clear:both;"><!-- gg --></div> 345 </div> 346 </div> 347 </div><!--column-center end--> 348 <div class="column-right"> 349 <div class="column-module"> 350 </div> 351 </div> 352 </div><!-- row end --> 353 </div><!-- container end --> 354 355
355<script> 356 function openNav() { document.getElementById("column-left").style.display = "block"; } 357 function closeNav() { document.getElementById("column-left").style.display = "none"; } 358 </script>
358 359 360 <!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 66 bytes, lines 360-361
360 361 <script async src="https://www.googletagmanager.com/gtag/js?id=
361UA-648925-1
vendor: 14 bytes, lines 361-362
361"></script> 362
362<script> 363
vendor: 142 bytes, lines 363-367
363window.dataLayer = window.dataLayer || []; 364 function gtag(){dataLayer.push(arguments);} 365 gtag('js', new Date()); 366 367 gtag('config', '
367UA-648925-1
vendor: 6 bytes, lines 367-368
367'); 368
368</script>
368 369 370
370<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"9212a8e60aad4cb3bd0f81be4bc467d7","r":1,"spa":2}' crossorigin="anonymous"></script>
370 371</body> 372 373 374</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.