-
Notifications
You must be signed in to change notification settings - Fork 0
/
BlogPrinciples.html
311 lines (302 loc) · 16.3 KB
/
BlogPrinciples.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<!DOCTYPE html>
<html>
<!--
Blog.html
Blog introduction
-->
<head>
<title>Blog Principles</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- <link rel="icon" type="image/x-icon" href="./images/favicon.ico" /> -->
<link rel="stylesheet" href="css/StylesPhoto.css" />
<link rel="stylesheet" href="css/StylesSizerComp.css" />
<!-- PageFrame infrastructure -->
<link rel="stylesheet" href="css/StylesPageFrameDefaults.css" />
<link rel="stylesheet" href="css/StylesPageFrameStructure.css" />
<link rel="stylesheet" href="css/StylesPageFrameMenus.css" />
<link rel="stylesheet" href="css/StylesPageFrameThemePython.css" />
<link rel="stylesheet" href="css/StylesWebComponents.css" />
<script src="js/ScriptsWebComponents.js"></script>
<!--<script src="js/ScriptsPageFrameDefaults.js"></script>-->
<script src="js/ScriptsPageFramePosts.js"></script>
<script src="js/ScriptsPageFramePagesPosts.js"></script>
<script src="js/ScriptsPageFrameKeyboard.js"></script>
<!-- No need for Pages script for pages with no next or prev pages -->
<!--<script src="js/ScriptsPageFramePages.js"></script>-->
<!-- <script src="js/ScriptsTemplate.js"></script>
<link rel="stylesheet" href="css/StylesTemplate.css" /> -->
<style>
h3 {
margin-top: 1.5em;
}
#subtitle {
margin-top: 0.4em;
margin-bottom: 0.3em;
}
#github header summary {
border: 1px solid var(--light);
}
#github summary {
padding-right: 2em;
}
/* #github .menuHead {
margin:0em -0.25em 0.0em -0.25em;
padding:0.25em 0.5em;
} */
</style>
<script>
function load() {
initialize();
//loadif();
}
</script>
<style>
#github note {
display: block;
width:max-content;
border:1px solid red;
padding:0.5em 1.0em;
margin:0.5em 0em;
}
#github .bargraph {
border: 1px solid var(--dark);
/* background-color: #bbb; */
padding: 0.1em 0.5em;
font-size:0.9em;
}
#github table {
border:2px solid var(--dark);
}
#github table td {
padding:0.25em 1.0em;
border:none;
}
body {
user-select:none;
}
</style>
<script>
function clickstat() {
// prevent parent click event handling
event.stopImmediatePropagation();
}
</script>
</head>
<body id="github" onload="load()" style="position:relative;">
<a id="Next" href="BlogOOD.html">Next</a>
<a id="Prev" href="BlogDesign.html">Prev</a>
<page-frame>
<frame-header>
<nav id="navbar"></nav>
</frame-header>
<main id="main">
<div id="about" onclick="this.style.display = 'none'">about</div>
<div id="page">Blog: Design Principles</div>
<div id="modified">11/23/2024</div>
<div id="hlp"></div>
<a id="top"></a>
<content style="height:100vh; position:relative;">
<header style="cursor:pointer;" onclick="loadif()">
<!-- <a target="_blank" class="repoLink" href="https://github.com/JimFawcett">github Repositories</a> -->
<hgroup id="pagetitle" style="border: 2px solid var(--dark);">
<h1 id="title">Blog: Design Principles</h1>
<h3 class="indent" id="subtitle">
SRP, FRP, EP, LKP, VSP, SRMP, LSP, OCP, DIP, ISP
</h3>
</hgroup>
<!-- <img style="width:100%; margin:-0.1em 0em; border:2px solid var(--dark); padding:0.5em; background-color:var(--light);" src="Pictures/officestrip3a.svg" /> -->
<div class="darkItem" onclick="loadif()" style="cursor:pointer; position:relative; padding:0.0em 0em 0.25em 0em; margin-top:-0.50em; border:2px solid var(--dark);">
<a class="repoLinks" target="_blank" href="https://github.com/JimFawcett" style="color:var(--atten); margin-left:1.5em;">About</a>
<div style="font-size:0.9em; position:absolute; top:0.1em; right:1.5em;">click to toggle Site Explorer</div>
<div style="height:0.5em;"></div>
</div>
</header>
<div style="height:1.5em;"></div>
This page provides summaries of design principles and ideas we've discussed in class.
<div>
<ol class="tight">
<li id="srp">
<h4>Single Responsibilitiy Principle (SRP)<sup>1</sup>:</h4>
<div>
Each software entity: function, class, package, module should have one responsibility.
That makes design, testing, maintanence easier, because it makes comprehension easier.
</div>
</li>
<li id="frp">
<h4>Full Responsibility Principle (FRP)</h4>
<div>
Each software entity should take full responsiblity for managing its state. This may
include filtering user requests to avoid inappropriate changes of state, returning error
codes or exceptions for requests that cannot be satisfied, and managing formats of returned state.
<spacer-10></spacer-10>
The intent is to consolidate all state management in the owning class, so users don't
have to understand it's design, nor replicate handling code at the site of invocations.
</div>
</li>
<li id="ep">
<h4>Encapsulation Principle (EP):</h4>
<div>
Encapsulation restricts access to a class's data to the member functions of that class. This means that,
for well designed classes, all transformations on the class's state result in valid data. That is something
that the designer cannot guarantee if the class isn't properly encapsulated.
<spacer-10></spacer-10>
We provide encapsulation by making all the class data private.
<spacer-10></spacer-10>
A weaker form of encapsulation allows some of the class's data to provide protected access. That means that
derived classes also have access to the protected data. So a correctly designed base class may break if a derived
class treats the protected data inappropriately.
</div>
</li>
<li id="lkp">
<h4>Least Knowledge Principle (LKP):</h4>
Most method calls are a form of client/server interaction. The client makes a call on the server
and the server's service does some computation and returns a response. Here the client and server
could be:
<ul>
<li>a method of an instance of one class invoking a method of an instance of another class</li>
<li>
a method of an instance of a class in one process invoking, through Inter-Process Communication (IPC), a method on
an instance of a class in another process.
</li>
<li>
a method of an instance of a class in a process on one machine invoking, through a proxy using Remote Proceedure Call (RPC),
to a method of an instance of a class hosted in a process on another machine.
</li>
</ul>
Ideally a client knows only the service interface and needs to know nothing of the service implementation.
We also want the server to be entirely ignorant of the client.
Ideally the server only knows that a request has been made and it responds based on the content of the request,
having nothing to do with the client's details.
</li>
<li id="vsp">
<h4>Value Semantics Principle (VSP):</h4>
<div>
The C++ language directly supports implementation of classes whose instances have value type behavior.
That means that we can copy them and assign the state of one instance to another instance with the result
that the instances have, at the moment of copying or assignment, the same state values, but thoses states are independent.
Should the state of one be changed using its class interface, the other will not suffer that change.
<spacer-10></spacer-10>
We implement value behavior by providing correctly implemented copy constructors, overloading assignment operators, and
providing correctly implemented destructors.
We also can, using C++11's move construction and move assignment, make changing ownership of an instance's values
very efficient. By default ownership is only moved from a temporary (r value) to a declared named instance (l value).
<spacer-10></spacer-10>
All of this is demonstrated in a simple way in the presentation on <a href="Resources/ValueType.pdf">Value Types</a>
and code for the <a href="STRCode.html">Str class</a>.
</div>
</li>
<li id="srmp">
<h4>Scoped-based Resource Management Principle (SRMP aka RAII):</h4>
The C++ language has a very elegant mechanism for managing allocation and deallocation of resources to instances
of a class. Resources are allocated in a constructor at the site of the declaration of an instance, may be augmented by
allocations in other member functions, and are deallocated
using the class destructor at the end of the scope in which the instance is declared.
<spacer-10></spacer-10>
This means that users of the class need know very little about its internal design and don't need to do anything
explicit to quickly return resources when the instance is no longer needed. These resources may be things that
are in limited supply in a process, like file handles, threads, database locks, etc..
</li>
<li id="lsp">
<h4>Liskov Substitution Principle (LSP)<sup>1</sup>:</h4>
Inheritance is a powerful mechanism, used by most Object Oriented Languages. Here's a statement:
<indent-block class="pad10">
"Functions that use pointers or references statically typed to some base class must be able to use
objects of classes derived from the base through those pointers or references, without any knowledge
specialized to the derived classes."
</indent-block>
<spacer-10></spacer-10>
LSP supports great flexibility in the implementation of programs using OOD. We will see many examples in code and
presentations in this site.
</li>
<li id="ocp">
<h4>Open/Closed Principle (OCP)<sup>1</sup>:</h4>
OCP is a very broad principle. It says that we should strive to extend or wrap existing code rather than change the
code to meet new requirements. Here's a statement:
<indent-block class="pad10">
"Software entities [classes, packages, functdions] should be open for extension, but closed for modification.
</indent-block>
<spacer-10></spacer-10>
This is a very important goal when we design software. In order to satisfy new or changing requirements, we try to extend,
through inheritance or template parameterization, existing code, or wrap parts of the code with new classes, using composition
or aggregation. That is not always possible, but that should be our first attempt to satisfy a need for change.
</li>
<li id="dip">
<h4>Dependency Inversion Principle (DIP)<sup>1</sup>:</h4>
Making references to concrete classes and functions binds the caller to a specific design and implementation, and makes
that software "brittle", e.g., hard to change without causing a lot of breakage. To avoid these brittle designs
we use DIP:
<indent-block class="pad10">
"High level components should not depend upon low level components. Instead, both should depend on abstractions."<br />
"Abstractions should not depend upon details. Details should depend on the abstractions."
</indent-block>
<spacer-10></spacer-10>
Here, abstractions refer to interfaces and object factories. We will discuss this many times in presentations and provide
demos of several variations.
</li>
<li id="isp">
<h4>Interface Segregation Principle (ISP)<sup>1</sup>:</h4>
When a class has many clients with differing needs, it is tempting to extend the class's interface and implementation to
satisfy the needs of each new client. However, the other clients may not need those new public methods, but must be
recompiled every time a method changes, even if they don't use the method.
<indent-block class="pad10">
"Clients should not be forced to depend upon interfaces they do not use.
</indent-block>
<spacer-10></spacer-10>
We usually satisfy the ISP by factoring a class into a core and specialized parts that can serve the specialized needs
of each client. One common way to do that uses multiple inheritance, allowing selection of what's needed for each
application with "mix-ins".
</li>
</ol>
</div>
<div style="height:1.25em;"></div>
<hr />
<div style="height:0.75em;"></div>
<ol>
<li>
<a target="_blank" href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">Principles of OOD - Robert Martin</a>
</li>
</ol>
<div style="height:1.25em;"></div>
<img class="photo" src="Pictures/campusStrip.jpg" alt="Hall of Languages" style="width:100%;" />
<div style="height:1.0em;"></div>
<a id="bottom"></a>
</content>
<page-TOC id="pages" style="display:none;">
</page-TOC>
<page-sections id="sections" style="display:none;">
<menu-elem style="width:0.0em"> </menu-elem>
<menu-elem class="secElem"><a href="#bottom">bottom</a></menu-elem>
<menu-elem class="secElem"><a href="#isp">ISP</a></menu-elem>
<menu-elem class="secElem"><a href="#dip">DIP</a></menu-elem>
<menu-elem class="secElem"><a href="#ocp">OCP</a></menu-elem>
<menu-elem class="secElem"><a href="#lsp">LSP</a></menu-elem>
<menu-elem class="secElem"><a href="#srmp">SRMP</a></menu-elem>
<menu-elem class="secElem"><a href="#vsp">VSP</a></menu-elem>
<menu-elem class="secElem"><a href="#lkp">LKP</a></menu-elem>
<menu-elem class="secElem"><a href="#ep">EP</a></menu-elem>
<menu-elem class="secElem"><a href="#frp">FRP</a></menu-elem>
<menu-elem class="secElem"><a href="#srp">SRP</a></menu-elem>
<menu-elem class="secElem"><a href="#top">top</a></menu-elem>
<div class='darkItem popupHeader' style="padding:0.25em 2.0em;" onclick="this.parentElement.style.display='none'">Sections</div>
</page-sections>
</main>
<frame-footer>
<menu-item style="width:2.0em;"> </menu-item>
<menu-elem id="nextLink2" onclick="bottomMenu.next()">Next</menu-elem>
<menu-elem id="prevLink2" onclick="bottomMenu.prev()">Prev</menu-elem>
<menu-elem id="pgbtn" onclick="bottomMenu.pages()">Pages</menu-elem>
<menu-elem onclick="bottomMenu.sections()">Sections</menu-elem>
<menu-elem onclick="bottomMenu.about()">About</menu-elem>
<menu-elem id="kysbtn" onclick="storyHlpMenu.keys()">Keys</menu-elem>
<menu-elem style="margin-right:1em">
<span id="loc" style="display:inline-block; font-weight:normal"></span>
</menu-elem>
</frame-footer>
</page-frame>
<script>
let loc = document.getElementById("loc");
let fn = window.location.href.split(/\/|\\/).pop();
loc.innerHTML = fn + ":";
</script>
</body>
</html>