|
|
<!DOCTYPE HTML>
|
|
|
<html lang="en" class="sidebar-visible no-js rust">
|
|
|
<head>
|
|
|
<!-- Book generated using mdBook -->
|
|
|
<meta charset="UTF-8">
|
|
|
<title>Design principles - Rust Design Patterns</title>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
|
|
|
|
|
|
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
|
<meta name="description" content="A catalogue of Rust design patterns, anti-patterns and idioms">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
<meta name="theme-color" content="#ffffff" />
|
|
|
|
|
|
|
|
|
<link rel="icon" href="../favicon.svg">
|
|
|
|
|
|
|
|
|
<link rel="shortcut icon" href="../favicon.png">
|
|
|
|
|
|
<link rel="stylesheet" href="../css/variables.css">
|
|
|
<link rel="stylesheet" href="../css/general.css">
|
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
|
|
|
|
|
|
|
|
<!-- Fonts -->
|
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
|
|
|
|
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
|
<link rel="stylesheet" href="../highlight.css">
|
|
|
<link rel="stylesheet" href="../tomorrow-night.css">
|
|
|
<link rel="stylesheet" href="../ayu-highlight.css">
|
|
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
<body>
|
|
|
<!-- Provide site root to javascript -->
|
|
|
<script type="text/javascript">
|
|
|
var path_to_root = "../";
|
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "rust";
|
|
|
</script>
|
|
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
|
<script type="text/javascript">
|
|
|
try {
|
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
|
}
|
|
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
|
}
|
|
|
} catch (e) { }
|
|
|
</script>
|
|
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
|
<script type="text/javascript">
|
|
|
var theme;
|
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
|
var html = document.querySelector('html');
|
|
|
html.classList.remove('no-js')
|
|
|
html.classList.remove('rust')
|
|
|
html.classList.add(theme);
|
|
|
html.classList.add('js');
|
|
|
</script>
|
|
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
|
<script type="text/javascript">
|
|
|
var html = document.querySelector('html');
|
|
|
var sidebar = 'hidden';
|
|
|
if (document.body.clientWidth >= 1080) {
|
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
|
sidebar = sidebar || 'visible';
|
|
|
}
|
|
|
html.classList.remove('sidebar-visible');
|
|
|
html.classList.add("sidebar-" + sidebar);
|
|
|
</script>
|
|
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
|
<div class="sidebar-scrollbox">
|
|
|
<ol class="chapter"><li class="chapter-item expanded "><a href="../intro.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="../idioms/index.html"><strong aria-hidden="true">2.</strong> Idioms</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../idioms/coercion-arguments.html"><strong aria-hidden="true">2.1.</strong> Use borrowed types for arguments</a></li><li class="chapter-item expanded "><a href="../idioms/concat-format.html"><strong aria-hidden="true">2.2.</strong> Concatenating Strings with format!</a></li><li class="chapter-item expanded "><a href="../idioms/ctor.html"><strong aria-hidden="true">2.3.</strong> Constructor</a></li><li class="chapter-item expanded "><a href="../idioms/default.html"><strong aria-hidden="true">2.4.</strong> The Default Trait</a></li><li class="chapter-item expanded "><a href="../idioms/deref.html"><strong aria-hidden="true">2.5.</strong> Collections Are Smart Pointers</a></li><li class="chapter-item expanded "><a href="../idioms/dtor-finally.html"><strong aria-hidden="true">2.6.</strong> Finalisation in Destructors</a></li><li class="chapter-item expanded "><a href="../idioms/mem-replace.html"><strong aria-hidden="true">2.7.</strong> mem::replace(_)</a></li><li class="chapter-item expanded "><a href="../idioms/on-stack-dyn-dispatch.html"><strong aria-hidden="true">2.8.</strong> On-Stack Dynamic Dispatch</a></li><li class="chapter-item expanded "><a href="../idioms/ffi-intro.html"><strong aria-hidden="true">2.9.</strong> Foreign function interface usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../idioms/ffi-errors.html"><strong aria-hidden="true">2.9.1.</strong> Idiomatic Errors</a></li><li class="chapter-item expanded "><a href="../idioms/ffi-accepting-strings.html"><strong aria-hidden="true">2.9.2.</strong> Accepting Strings</a></li><li class="chapter-item expanded "><a href="../idioms/ffi-passing-strings.html"><strong aria-hidden="true">2.9.3.</strong> Passing Strings</a></li></ol></li><li class="chapter-item expanded "><a href="../idioms/option-iter.html"><strong aria-hidden="true">2.10.</strong> Iterating over an Option</a></li><li class="chapter-item expanded "><a href="../idioms/pass-var-to-closure.html"><strong aria-hidden="true">2.11.</strong> Pass Variables to Closure</a></li><li class="chapter-item expanded "><a href="../idioms/priv-extend.html"><strong aria-hidden="true">2.12.</strong> Privacy For Extensibility</a></li><li class="chapter-item expanded "><a href="../idioms/rustdoc-init.html"><strong aria-hidden="true">2.13.</strong> Easy doc initialization</a></li><li class="chapter-item expanded "><a href="../idioms/temporary-mutability.html"><strong aria-hidden="true">2.14.</strong> Temporary mutability</a></li></ol></li><li class="chapter-item expanded "><a href="../patterns/index.html"><strong aria-hidden="true">3.</strong> Design Patterns</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../patterns/builder.html"><strong aria-hidden="true">3.1.</strong> Builder</a></li><li class="chapter-item expanded "><a href="../patterns/compose-structs.html"><strong aria-hidden="true">3.2.</strong> Compose Structs</a></li><li class="chapter-item expanded "><a href="../patterns/entry.html"><strong aria-hidden="true">3.3.</strong> Entry API</a></li><li class="chapter-item expanded "><a href="../patterns/ffi-intro.html"><strong aria-hidden="true">3.4.</strong> Foreign function interface usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../patterns/ffi-export.html"><strong aria-hidden="true">3.4.1.</strong> Object-Based APIs</a></li><li class="chapter-item expanded "><a href="../patterns/ffi-wrappers.html"><strong aria-hidden="true">3.4.2.</strong> Type Consolidation into Wrappers</a></li></ol></li><li class="chapter-item expanded "><a href="../patterns/fold.html"><strong aria-hidden="true">3.5.</strong> Fold</a></li><li class="chapter-item expanded "><a href="../patterns/newtype.html"><strong aria-hidden="true">3.6.</strong> Newtype</a></li><li class="chapter-item expanded "><a href="../patterns/RAII.html"><strong aria-hidden="true">3.7.</strong> RAII Guards</a></li><li class="chapter-item expanded "><a href="../patterns/small-crates.html"><strong aria-hidden="true">3.8.</strong> Prefer Small Crates</a></li><li class="chapter-item expanded "><a href="../patterns/unsafe-mods.html"><strong aria-hidden="true">3.9.</strong> Contain unsafety in small modules</a></li><li class="chapter-item expanded "><a href="../patterns/visitor.html"><strong aria-hidden="true">3.10.</strong> Visitor</a></li></ol></li><li class="chapter-item expanded "><a href="../anti_patterns/index.html"><strong aria-hidden="true">4.</strong> Anti-patterns</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../anti_patterns/deny-warnings.html"><strong aria-hidden="true">4.1.</strong> #[deny(warnings)]</a></li><li class="chapter-item expanded "><a href="../anti_patterns/deref.html"><strong aria-hidden="true">4.2.</strong> Deref Polymorphism</a></li></ol></li><li class="chapter-item expanded "><a href="../functional/index.html"><strong aria-hidden="true">5.</strong> Functional Programming</a></li><li class="chapter-item expanded "><a href="../additional_resources/index.html"><strong aria-hidden="true">6.</strong> Additional Resources</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../additional_resources/design-principles.html" class="active"><strong aria-hidden="true">6.1.</strong> Design principles</a></li></ol></li></ol>
|
|
|
</div>
|
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
|
|
</nav>
|
|
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
|
|
<div class="page">
|
|
|
|
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
|
<div id="menu-bar" class="menu-bar sticky bordered">
|
|
|
<div class="left-buttons">
|
|
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
|
<i class="fa fa-bars"></i>
|
|
|
</button>
|
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
|
<i class="fa fa-paint-brush"></i>
|
|
|
</button>
|
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust (default)</button></li>
|
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
|
</ul>
|
|
|
|
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|
|
<i class="fa fa-search"></i>
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<h1 class="menu-title">Rust Design Patterns</h1>
|
|
|
|
|
|
<div class="right-buttons">
|
|
|
|
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
<a href="https://github.com/rust-unofficial/patterns" title="Git repository" aria-label="Git repository">
|
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
|
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
|
</form>
|
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
|
<ul id="searchresults">
|
|
|
</ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
|
<script type="text/javascript">
|
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<div id="content" class="content">
|
|
|
<main>
|
|
|
<h1><a class="header" href="#design-principles" id="design-principles">Design principles</a></h1>
|
|
|
<h2><a class="header" href="#a-brief-overview-over-common-design-principles" id="a-brief-overview-over-common-design-principles">A brief overview over common design principles</a></h2>
|
|
|
<hr />
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikisolidsolida" id="a-hrefhttpsenwikipediaorgwikisolidsolida"><a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a></a></h2>
|
|
|
<ul>
|
|
|
<li><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">Single Responsibility Principle (SRP)</a>:
|
|
|
A class should only have a single responsibility, that is, only changes to one part of the software's
|
|
|
specification should be able to affect the specification of the class.</li>
|
|
|
<li><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Open/Closed Principle (OCP)</a>:
|
|
|
"Software entities ... should be open for extension, but closed for modification."</li>
|
|
|
<li><a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liscov Substitution Principle (LSP)</a>:
|
|
|
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness
|
|
|
of that program."</li>
|
|
|
<li><a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle (ISP)</a>:
|
|
|
"Many client-specific interfaces are better than one general-purpose interface."</li>
|
|
|
<li><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle (DIP)</a>:
|
|
|
One should "depend upon abstractions, [not] concretions."</li>
|
|
|
</ul>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikidon27t_repeat_yourselfdry-dont-repeat-yourselfa" id="a-hrefhttpsenwikipediaorgwikidon27t_repeat_yourselfdry-dont-repeat-yourselfa"><a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY (Don’t Repeat Yourself)</a></a></h2>
|
|
|
<p>"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system"</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikikiss_principlekiss-principlea" id="a-hrefhttpsenwikipediaorgwikikiss_principlekiss-principlea"><a href="https://en.wikipedia.org/wiki/KISS_principle">KISS principle</a></a></h2>
|
|
|
<p>most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikilaw_of_demeterlaw-of-demeter-loda" id="a-hrefhttpsenwikipediaorgwikilaw_of_demeterlaw-of-demeter-loda"><a href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter (LoD)</a></a></h2>
|
|
|
<p>a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents), in accordance with the principle of "information hiding"</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikidesign_by_contractdesign-by-contract-dbca" id="a-hrefhttpsenwikipediaorgwikidesign_by_contractdesign-by-contract-dbca"><a href="https://en.wikipedia.org/wiki/Design_by_contract">Design by contract (DbC)</a></a></h2>
|
|
|
<p>software designers should define formal, precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikiencapsulation_computer_programmingencapsulationa" id="a-hrefhttpsenwikipediaorgwikiencapsulation_computer_programmingencapsulationa"><a href="https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)">Encapsulation</a></a></h2>
|
|
|
<p>bundling of data with the methods that operate on that data, or the restricting of direct access to some of an object's components. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikicommande28093query_separationcommand-query-separationcqsa" id="a-hrefhttpsenwikipediaorgwikicommande28093query_separationcommand-query-separationcqsa"><a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">Command-Query-Separation(CQS)</a></a></h2>
|
|
|
<p>“Functions should not produce abstract side effects...only commands (procedures) will be permitted to produce side effects.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
<h2><a class="header" href="#a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa" id="a-hrefhttpsenwikipediaorgwikiprinciple_of_least_astonishmentprinciple-of-least-astonishment-polaa"><a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">Principle of least astonishment (POLA)</a></a></h2>
|
|
|
<p>a component of a system should behave in a way that most users will expect it to behave. The behavior should not astonish or surprise users</p>
|
|
|
<h2><a class="header" href="#linguistic-modular-units" id="linguistic-modular-units">Linguistic-Modular-Units</a></h2>
|
|
|
<p>“Modules must correspond to syntactic units in the language used.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
<h2><a class="header" href="#self-documentation" id="self-documentation">Self-Documentation</a></h2>
|
|
|
<p>“The designer of a module should strive to make all information about the module part of the module itself.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
<h2><a class="header" href="#uniform-access" id="uniform-access">Uniform-Access</a></h2>
|
|
|
<p>“All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
<h2><a class="header" href="#single-choice" id="single-choice">Single-Choice</a></h2>
|
|
|
<p>“Whenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
<h2><a class="header" href="#persistence-closure" id="persistence-closure">Persistence-Closure</a></h2>
|
|
|
<p>“Whenever a storage mechanism stores an object, it must store with it the dependents of that object. Whenever a retrieval mechanism retrieves a previously stored object, it must also retrieve any dependent of that object that has not yet been retrieved.” - Bertrand Meyer: Object Oriented Software Construction</p>
|
|
|
|
|
|
</main>
|
|
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
|
<!-- Mobile navigation buttons -->
|
|
|
|
|
|
<a rel="prev" href="../additional_resources/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
|
<i class="fa fa-angle-left"></i>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div style="clear: both"></div>
|
|
|
</nav>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
|
|
|
|
<a rel="prev" href="../additional_resources/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
|
<i class="fa fa-angle-left"></i>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
window.playground_copyable = true;
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
|
|
|
|
|
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
</html>
|