934 lines
75 KiB
HTML
934 lines
75 KiB
HTML
<!DOCTYPE html>
|
|
<html class='v2' dir='ltr' lang='en-GB'>
|
|
<head>
|
|
<link href='https://www.blogger.com/static/v1/widgets/3772415480-widget_css_mobile_2_bundle.css' rel='stylesheet' type='text/css'/>
|
|
<meta content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0' name='viewport'/>
|
|
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
|
|
<meta content='blogger' name='generator'/>
|
|
<link href='http://mikehadlow.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/>
|
|
<link href='http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html' rel='canonical'/>
|
|
<link rel="alternate" type="application/atom+xml" title="Code rant - Atom" href="http://mikehadlow.blogspot.com/feeds/posts/default" />
|
|
<link rel="alternate" type="application/rss+xml" title="Code rant - RSS" href="http://mikehadlow.blogspot.com/feeds/posts/default?alt=rss" />
|
|
<link rel="service.post" type="application/atom+xml" title="Code rant - Atom" href="https://www.blogger.com/feeds/15136575/posts/default" />
|
|
|
|
<link rel="alternate" type="application/atom+xml" title="Code rant - Atom" href="http://mikehadlow.blogspot.com/feeds/2125139449813877883/comments/default" />
|
|
<!--Can't find substitution for tag [blog.ieCssRetrofitLinks]-->
|
|
<link href='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/?imgmax=800' rel='image_src'/>
|
|
<meta content='http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html' property='og:url'/>
|
|
<meta content='The Configuration Complexity Clock' property='og:title'/>
|
|
<meta content='When I was a young coder, just starting out in the big scary world of enterprise software, an older, far more experienced chap gave me a ste...' property='og:description'/>
|
|
<meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/w1200-h630-p-k-no-nu/?imgmax=800' property='og:image'/>
|
|
<title>Code rant: The Configuration Complexity Clock</title>
|
|
<style id='page-skin-1' type='text/css'><!--
|
|
/*
|
|
-----------------------------------------------
|
|
Blogger Template Style
|
|
Name: Simple
|
|
Designer: Blogger
|
|
URL: www.blogger.com
|
|
----------------------------------------------- */
|
|
/* Content
|
|
----------------------------------------------- */
|
|
body {
|
|
font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif;
|
|
color: #666666;
|
|
background: #ffffff none repeat scroll top left;
|
|
padding: 0 0 0 0;
|
|
}
|
|
html body .region-inner {
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
width: auto;
|
|
}
|
|
h2 {
|
|
font-size: 22px;
|
|
}
|
|
a:link {
|
|
text-decoration:none;
|
|
color: #2288bb;
|
|
}
|
|
a:visited {
|
|
text-decoration:none;
|
|
color: #888888;
|
|
}
|
|
a:hover {
|
|
text-decoration:underline;
|
|
color: #33aaff;
|
|
}
|
|
.body-fauxcolumn-outer .fauxcolumn-inner {
|
|
background: transparent none repeat scroll top left;
|
|
_background-image: none;
|
|
}
|
|
.body-fauxcolumn-outer .cap-top {
|
|
position: absolute;
|
|
z-index: 1;
|
|
height: 400px;
|
|
width: 100%;
|
|
}
|
|
.body-fauxcolumn-outer .cap-top .cap-left {
|
|
width: 100%;
|
|
background: transparent none repeat-x scroll top left;
|
|
_background-image: none;
|
|
}
|
|
.content-outer {
|
|
-moz-box-shadow: 0 0 0 rgba(0, 0, 0, .15);
|
|
-webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .15);
|
|
-goog-ms-box-shadow: 0 0 0 #333333;
|
|
box-shadow: 0 0 0 rgba(0, 0, 0, .15);
|
|
margin-bottom: 1px;
|
|
}
|
|
.content-inner {
|
|
padding: 10px 40px;
|
|
}
|
|
.content-inner {
|
|
background-color: #ffffff;
|
|
}
|
|
/* Header
|
|
----------------------------------------------- */
|
|
.header-outer {
|
|
background: transparent none repeat-x scroll 0 -400px;
|
|
_background-image: none;
|
|
}
|
|
.Header h1 {
|
|
font: normal normal 40px 'Trebuchet MS',Trebuchet,Verdana,sans-serif;
|
|
color: #000000;
|
|
text-shadow: 0 0 0 rgba(0, 0, 0, .2);
|
|
}
|
|
.Header h1 a {
|
|
color: #000000;
|
|
}
|
|
.Header .description {
|
|
font-size: 18px;
|
|
color: #000000;
|
|
}
|
|
.header-inner .Header .titlewrapper {
|
|
padding: 22px 0;
|
|
}
|
|
.header-inner .Header .descriptionwrapper {
|
|
padding: 0 0;
|
|
}
|
|
/* Tabs
|
|
----------------------------------------------- */
|
|
.tabs-inner .section:first-child {
|
|
border-top: 0 solid #dddddd;
|
|
}
|
|
.tabs-inner .section:first-child ul {
|
|
margin-top: -1px;
|
|
border-top: 1px solid #dddddd;
|
|
border-left: 1px solid #dddddd;
|
|
border-right: 1px solid #dddddd;
|
|
}
|
|
.tabs-inner .widget ul {
|
|
background: transparent none repeat-x scroll 0 -800px;
|
|
_background-image: none;
|
|
border-bottom: 1px solid #dddddd;
|
|
margin-top: 0;
|
|
margin-left: -30px;
|
|
margin-right: -30px;
|
|
}
|
|
.tabs-inner .widget li a {
|
|
display: inline-block;
|
|
padding: .6em 1em;
|
|
font: normal normal 12px 'Trebuchet MS', Trebuchet, Verdana, sans-serif;
|
|
color: #000000;
|
|
border-left: 1px solid #ffffff;
|
|
border-right: 1px solid #dddddd;
|
|
}
|
|
.tabs-inner .widget li:first-child a {
|
|
border-left: none;
|
|
}
|
|
.tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover {
|
|
color: #000000;
|
|
background-color: #eeeeee;
|
|
text-decoration: none;
|
|
}
|
|
/* Columns
|
|
----------------------------------------------- */
|
|
.main-outer {
|
|
border-top: 0 solid #dddddd;
|
|
}
|
|
.fauxcolumn-left-outer .fauxcolumn-inner {
|
|
border-right: 1px solid #dddddd;
|
|
}
|
|
.fauxcolumn-right-outer .fauxcolumn-inner {
|
|
border-left: 1px solid #dddddd;
|
|
}
|
|
/* Headings
|
|
----------------------------------------------- */
|
|
div.widget > h2,
|
|
div.widget h2.title {
|
|
margin: 0 0 1em 0;
|
|
font: normal bold 11px 'Trebuchet MS',Trebuchet,Verdana,sans-serif;
|
|
color: #000000;
|
|
}
|
|
/* Widgets
|
|
----------------------------------------------- */
|
|
.widget .zippy {
|
|
color: #999999;
|
|
text-shadow: 2px 2px 1px rgba(0, 0, 0, .1);
|
|
}
|
|
.widget .popular-posts ul {
|
|
list-style: none;
|
|
}
|
|
/* Posts
|
|
----------------------------------------------- */
|
|
h2.date-header {
|
|
font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif;
|
|
}
|
|
.date-header span {
|
|
background-color: #bbbbbb;
|
|
color: #ffffff;
|
|
padding: 0.4em;
|
|
letter-spacing: 3px;
|
|
margin: inherit;
|
|
}
|
|
.main-inner {
|
|
padding-top: 35px;
|
|
padding-bottom: 65px;
|
|
}
|
|
.main-inner .column-center-inner {
|
|
padding: 0 0;
|
|
}
|
|
.main-inner .column-center-inner .section {
|
|
margin: 0 1em;
|
|
}
|
|
.post {
|
|
margin: 0 0 45px 0;
|
|
}
|
|
h3.post-title, .comments h4 {
|
|
font: normal normal 22px 'Trebuchet MS',Trebuchet,Verdana,sans-serif;
|
|
margin: .75em 0 0;
|
|
}
|
|
.post-body {
|
|
font-size: 110%;
|
|
line-height: 1.4;
|
|
position: relative;
|
|
}
|
|
.post-body img, .post-body .tr-caption-container, .Profile img, .Image img,
|
|
.BlogList .item-thumbnail img {
|
|
padding: 2px;
|
|
background: #ffffff;
|
|
border: 1px solid #eeeeee;
|
|
-moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);
|
|
-webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);
|
|
box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);
|
|
}
|
|
.post-body img, .post-body .tr-caption-container {
|
|
padding: 5px;
|
|
}
|
|
.post-body .tr-caption-container {
|
|
color: #666666;
|
|
}
|
|
.post-body .tr-caption-container img {
|
|
padding: 0;
|
|
background: transparent;
|
|
border: none;
|
|
-moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1);
|
|
-webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1);
|
|
box-shadow: 0 0 0 rgba(0, 0, 0, .1);
|
|
}
|
|
.post-header {
|
|
margin: 0 0 1.5em;
|
|
line-height: 1.6;
|
|
font-size: 90%;
|
|
}
|
|
.post-footer {
|
|
margin: 20px -2px 0;
|
|
padding: 5px 10px;
|
|
color: #666666;
|
|
background-color: #eeeeee;
|
|
border-bottom: 1px solid #eeeeee;
|
|
line-height: 1.6;
|
|
font-size: 90%;
|
|
}
|
|
#comments .comment-author {
|
|
padding-top: 1.5em;
|
|
border-top: 1px solid #dddddd;
|
|
background-position: 0 1.5em;
|
|
}
|
|
#comments .comment-author:first-child {
|
|
padding-top: 0;
|
|
border-top: none;
|
|
}
|
|
.avatar-image-container {
|
|
margin: .2em 0 0;
|
|
}
|
|
#comments .avatar-image-container img {
|
|
border: 1px solid #eeeeee;
|
|
}
|
|
/* Comments
|
|
----------------------------------------------- */
|
|
.comments .comments-content .icon.blog-author {
|
|
background-repeat: no-repeat;
|
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==);
|
|
}
|
|
.comments .comments-content .loadmore a {
|
|
border-top: 1px solid #999999;
|
|
border-bottom: 1px solid #999999;
|
|
}
|
|
.comments .comment-thread.inline-thread {
|
|
background-color: #eeeeee;
|
|
}
|
|
.comments .continue {
|
|
border-top: 2px solid #999999;
|
|
}
|
|
/* Accents
|
|
---------------------------------------------- */
|
|
.section-columns td.columns-cell {
|
|
border-left: 1px solid #dddddd;
|
|
}
|
|
.blog-pager {
|
|
background: transparent url(https://resources.blogblog.com/blogblog/data/1kt/simple/paging_dot.png) repeat-x scroll top center;
|
|
}
|
|
.blog-pager-older-link, .home-link,
|
|
.blog-pager-newer-link {
|
|
background-color: #ffffff;
|
|
padding: 5px;
|
|
}
|
|
.footer-outer {
|
|
border-top: 1px dashed #bbbbbb;
|
|
}
|
|
/* Mobile
|
|
----------------------------------------------- */
|
|
body.mobile {
|
|
background-size: auto;
|
|
}
|
|
.mobile .body-fauxcolumn-outer {
|
|
background: transparent none repeat scroll top left;
|
|
}
|
|
.mobile .body-fauxcolumn-outer .cap-top {
|
|
background-size: 100% auto;
|
|
}
|
|
.mobile .content-outer {
|
|
-webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15);
|
|
box-shadow: 0 0 3px rgba(0, 0, 0, .15);
|
|
}
|
|
.mobile .tabs-inner .widget ul {
|
|
margin-left: 0;
|
|
margin-right: 0;
|
|
}
|
|
.mobile .post {
|
|
margin: 0;
|
|
}
|
|
.mobile .main-inner .column-center-inner .section {
|
|
margin: 0;
|
|
}
|
|
.mobile .date-header span {
|
|
padding: 0.1em 10px;
|
|
margin: 0 -10px;
|
|
}
|
|
.mobile h3.post-title {
|
|
margin: 0;
|
|
}
|
|
.mobile .blog-pager {
|
|
background: transparent none no-repeat scroll top center;
|
|
}
|
|
.mobile .footer-outer {
|
|
border-top: none;
|
|
}
|
|
.mobile .main-inner, .mobile .footer-inner {
|
|
background-color: #ffffff;
|
|
}
|
|
.mobile-index-contents {
|
|
color: #666666;
|
|
}
|
|
.mobile-link-button {
|
|
background-color: #2288bb;
|
|
}
|
|
.mobile-link-button a:link, .mobile-link-button a:visited {
|
|
color: #ffffff;
|
|
}
|
|
.mobile .tabs-inner .section:first-child {
|
|
border-top: none;
|
|
}
|
|
.mobile .tabs-inner .PageList .widget-content {
|
|
background-color: #eeeeee;
|
|
color: #000000;
|
|
border-top: 1px solid #dddddd;
|
|
border-bottom: 1px solid #dddddd;
|
|
}
|
|
.mobile .tabs-inner .PageList .widget-content .pagelist-arrow {
|
|
border-left: 1px solid #dddddd;
|
|
}
|
|
|
|
--></style>
|
|
<style id='template-skin-1' type='text/css'><!--
|
|
body {
|
|
min-width: 960px;
|
|
}
|
|
.content-outer, .content-fauxcolumn-outer, .region-inner {
|
|
min-width: 960px;
|
|
max-width: 960px;
|
|
_width: 960px;
|
|
}
|
|
.main-inner .columns {
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
.main-inner .fauxcolumn-center-outer {
|
|
left: 0;
|
|
right: 0;
|
|
/* IE6 does not respect left and right together */
|
|
_width: expression(this.parentNode.offsetWidth -
|
|
parseInt("0") -
|
|
parseInt("0") + 'px');
|
|
}
|
|
.main-inner .fauxcolumn-left-outer {
|
|
width: 0;
|
|
}
|
|
.main-inner .fauxcolumn-right-outer {
|
|
width: 0;
|
|
}
|
|
.main-inner .column-left-outer {
|
|
width: 0;
|
|
right: 100%;
|
|
margin-left: -0;
|
|
}
|
|
.main-inner .column-right-outer {
|
|
width: 0;
|
|
margin-right: -0;
|
|
}
|
|
#layout {
|
|
min-width: 0;
|
|
}
|
|
#layout .content-outer {
|
|
min-width: 0;
|
|
width: 800px;
|
|
}
|
|
#layout .region-inner {
|
|
min-width: 0;
|
|
width: auto;
|
|
}
|
|
body#layout div.add_widget {
|
|
padding: 8px;
|
|
}
|
|
body#layout div.add_widget a {
|
|
margin-left: 32px;
|
|
}
|
|
--></style>
|
|
<link href='https://www.blogger.com/dyncss/15136575/authorization.css?zx=1b8b33dd-ae38-42f4-ac2b-2d4e449bb43a' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyncss/15136575/authorization.css?zx=1b8b33dd-ae38-42f4-ac2b-2d4e449bb43a' rel='stylesheet'/></noscript>
|
|
<meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/>
|
|
<meta name='google-adsense-platform-domain' content='blogspot.com'/>
|
|
|
|
</head>
|
|
<body class='loading mobile variant-simplysimple'>
|
|
<div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript">
|
|
function setAttributeOnload(object, attribute, val) {
|
|
if(window.addEventListener) {
|
|
window.addEventListener('load',
|
|
function(){ object[attribute] = val; }, false);
|
|
} else {
|
|
window.attachEvent('onload', function(){ object[attribute] = val; });
|
|
}
|
|
}
|
|
</script>
|
|
<script type="text/javascript">
|
|
(function() {
|
|
var script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js';
|
|
var head = document.getElementsByTagName('head')[0];
|
|
if (head) {
|
|
head.appendChild(script);
|
|
}})();
|
|
</script>
|
|
</div></div>
|
|
<div class='body-fauxcolumns'>
|
|
<div class='fauxcolumn-outer body-fauxcolumn-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='content'>
|
|
<div class='content-fauxcolumns'>
|
|
<div class='fauxcolumn-outer content-fauxcolumn-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='content-outer'>
|
|
<div class='content-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left content-fauxborder-left'>
|
|
<div class='fauxborder-right content-fauxborder-right'></div>
|
|
<div class='content-inner'>
|
|
<header>
|
|
<div class='header-outer'>
|
|
<div class='header-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left header-fauxborder-left'>
|
|
<div class='fauxborder-right header-fauxborder-right'></div>
|
|
<div class='region-inner header-inner'>
|
|
<div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'>
|
|
<div id='header-inner'>
|
|
<div class='titlewrapper'>
|
|
<h1 class='title'>
|
|
<a href='http://mikehadlow.blogspot.com/?m=1'>
|
|
Code rant
|
|
</a>
|
|
</h1>
|
|
</div>
|
|
<div class='descriptionwrapper'>
|
|
<p class='description'><span>Life as a mort.</span></p>
|
|
</div>
|
|
</div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='header-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div class='tabs-outer'>
|
|
<div class='tabs-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left tabs-fauxborder-left'>
|
|
<div class='fauxborder-right tabs-fauxborder-right'></div>
|
|
<div class='region-inner tabs-inner'>
|
|
<div class='tabs no-items section' id='crosscol' name='Cross-column'></div>
|
|
<div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div>
|
|
</div>
|
|
</div>
|
|
<div class='tabs-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='main-outer'>
|
|
<div class='main-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left main-fauxborder-left'>
|
|
<div class='fauxborder-right main-fauxborder-right'></div>
|
|
<div class='region-inner main-inner'>
|
|
<div class='columns fauxcolumns'>
|
|
<div class='fauxcolumn-outer fauxcolumn-center-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='fauxcolumn-outer fauxcolumn-left-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<div class='fauxcolumn-outer fauxcolumn-right-outer'>
|
|
<div class='cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left'>
|
|
<div class='fauxborder-right'></div>
|
|
<div class='fauxcolumn-inner'>
|
|
</div>
|
|
</div>
|
|
<div class='cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<!-- corrects IE6 width calculation -->
|
|
<div class='columns-inner'>
|
|
<div class='column-center-outer'>
|
|
<div class='column-center-inner'>
|
|
<div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'>
|
|
<div class='blog-posts hfeed'>
|
|
<div class='date-outer'>
|
|
<h2 class='date-header'><span>Monday, May 07, 2012</span></h2>
|
|
<div class='date-posts'>
|
|
<div class='post-outer'>
|
|
<div class='post hentry uncustomized-post-template' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'>
|
|
<meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/s72-c/?imgmax=800' itemprop='image_url'/>
|
|
<meta content='15136575' itemprop='blogId'/>
|
|
<meta content='2125139449813877883' itemprop='postId'/>
|
|
<a name='2125139449813877883'></a>
|
|
<h3 class='post-title entry-title' itemprop='name'>
|
|
The Configuration Complexity Clock
|
|
</h3>
|
|
<div class='post-header'>
|
|
<div class='post-header-line-1'></div>
|
|
</div>
|
|
<div class='post-body entry-content' id='post-body-2125139449813877883' itemprop='articleBody'>
|
|
<p>When I was a young coder, just starting out in the big scary world of enterprise software, an older, far more experienced chap gave me a stern warning about hard coding values in my software. “They <em>will</em> have to change at some point, and you don’t want to recompile and redeploy your application just to change the VAT tax rate.” I took this advice to heart and soon every value that my application needed was loaded from a huge .ini file. I still think it’s good advice, but be warned, like most things in software, it’s good advice <em>up to a point</em>. Beyond that point lies pain. </p> <p>Let me introduce you to my ‘Configuration Complexity Clock’.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK8r9A_8HWsRVsA-cTwHsjuQZzPxDYtefl4MD7uncO4XlSy7Leq1Pt7sQRqXpp9hvTEsUQ7iS80KEpWPTGaxckWgDC43qFBLbRixbXcJ-0epoSw-cv725phDVLbL1UR7PB4kr76Q/s1600-h/ConfigurationComplexityClock%25255B8%25255D.png"><img alt="ConfigurationComplexityClock" border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/?imgmax=800" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ConfigurationComplexityClock" width="280" /></a></p> <p>This clock tells a story. We start at midnight, 12 o’clock, with a simple new requirement which we quickly code up as a little application. It’s not expected to last very long, just a stop-gap in some larger strategic scheme, so we’ve hard-coded all the application’s values. Months pass, the application becomes widely used, but there’s a problem, some of the business values change, so we find ourselves rebuilding and re-deploying it just to change a few numbers. This is obviously wrong. The solution is simple, we’ll move those values out into a configuration file, maybe some appsettings in our App.config. Now we’re at 2 on the clock.</p> <p>Time passes and our application is now somewhat entrenched in our organisation. The business continues to evolve and as it does, more values are moved to our configuration file. Now appsettings are no longer sufficient, we have groups of values and hierarchies of values. If we’re good, by now we will have moved our configuration into a dedicated XML schema that gets de-serialized into a configuration model. If we’re not so good we might have shoe-horned repeated and multi-dimensional values into some strange tilda and pipe separated strings. Now we’re at 4 or 5 on the clock.</p> <p>More time passes, the irritating ‘chief software architect’ has been sacked and our little application is now core to our organisation. The business rules become more complex and so does our configuration. In fact there’s now a considerable learning curve before a new hire can successfully carry out a deployment. One of our new hires is a very clever chap, he’s seen this situation before. “What we need is a business rules engine” he declares. Now this looks promising. The configuration moves from its XML file into a database and has its own specialised GUI. Initially there was hope that non-technical business users would be able to use the GUI to configure the application, but that turned out to be a false hope; the mapping of business rules into the engine requires a level of expertise that only some members of the development team possess. We’re now at 6 on the clock.</p> <p>Frustratingly there are still some business requirements that can’t be configured using the new rules engine. Some logical conditions simply aren’t configurable using its GUI, and so the application has to be re-coded and re-deployed for some scenarios. Help is at hand, someone on the team reads <a href="http://www.manning.com/rahien/">Ayende’s DSLs book</a>. Yes, a DSL will allow us to write arbitrarily complex rules and solve all our problems. The team stops work for several months to implement the DSL. It’s a considerable technical accomplishment when it’s completed and everyone takes a well earned break. Surely this will mean the end of arbitrary hard-coded business logic? It’s now 9am on the clock.</p> <p>Amazingly it works. Several months go by without any changes being needed in the core application. The team spend most of their time writing code in the new DSL. After some embarrassing episodes, they now go through a complete release cycle before deploying any new DSL code. The DSL text files are version controlled and each release goes through regression testing before being deployed. Debugging the DSL code is difficult, there’s little tooling support, they simply don’t have the resources to build an IDE or a ReSharper for their new little language. As the DSL code gets more complex they also start to miss being able to write object-oriented software. Some of the team have started to work on a unit testing framework in their spare time.</p> <p>In the pub after work someone quips, “we’re back where we started four years ago, hard coding everything, except now in a much crappier language.” </p> <p>They’ve gone around the clock and are back at 12.</p> <p>Why tell this story? To be honest, I’ve never seen an organisation go all the way around the clock, but I’ve seen plenty that have got to 5, 6, or 7 and feel considerable pain. My point is this: </p> <p><em>At a certain level of complexity, hard-coding a solution may be the least evil option.</em></p> <p>You already have a general purpose programming language, before you go down the route of building a business rules engine or a DSL, or even if your configuration passes a certain level of complexity, consider that with a slicker build-test-deploy cycle, it might be far simpler just to hard code it.</p> <p>As you go clockwise around the clock, the technical implementation becomes successively more complex. Building a good  rules engine is hard, writing a DSL is harder still. Each extra hour you travel clockwise will lead to more complex software with more bugs and a harder learning curve for any new hires. The more complex the configuration, the more control and testing it will need before deployment. Soon enough you’ll find that there’s little difference in the length of time it takes between changing a line of code and changing a line of configuration. Rather than a commonly available skill, such as coding C#, you find that your organisation relies on a very rare skill: understanding your rules engine or DSL.</p> <p>I’m not saying that it’s never appropriate to implement complex configuration, a rules-engine or a DSL, Indeed I would jump at the chance of building a DSL given the right requirements, but I <em>am</em> saying that you should understand the implications and recognise where you are on the clock before you go down that route.</p>
|
|
<div style='clear: both;'></div>
|
|
</div>
|
|
<div class='post-footer'>
|
|
<div class='post-footer-line post-footer-line-1'>
|
|
<span class='post-author vcard'>
|
|
<span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
|
|
<meta content='https://www.blogger.com/profile/15393720749809796178' itemprop='url'/>
|
|
<a href='https://www.blogger.com/profile/15393720749809796178' rel='author' title='author profile'>
|
|
<span itemprop='name'>Mike Hadlow</span>
|
|
</a>
|
|
</span>
|
|
</span>
|
|
<span class='post-timestamp'>
|
|
at
|
|
<meta content='http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html' itemprop='url'/>
|
|
<a class='timestamp-link' href='http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?m=1' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2012-05-07T12:24:00+01:00'>12:24 pm</abbr></a>
|
|
</span>
|
|
<span class='post-comment-link'>
|
|
</span>
|
|
</div>
|
|
<div class='post-footer-line post-footer-line-2'>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='comments' id='comments'>
|
|
<a name='comments'></a>
|
|
<h4>17 comments:</h4>
|
|
<div class='comments-content'>
|
|
<script async='async' src='' type='text/javascript'></script>
|
|
<script type='text/javascript'>
|
|
(function() {
|
|
var items = null;
|
|
var msgs = null;
|
|
var config = {};
|
|
|
|
// <![CDATA[
|
|
var cursor = null;
|
|
if (items && items.length > 0) {
|
|
cursor = parseInt(items[items.length - 1].timestamp) + 1;
|
|
}
|
|
|
|
var bodyFromEntry = function(entry) {
|
|
var text = (entry &&
|
|
((entry.content && entry.content.$t) ||
|
|
(entry.summary && entry.summary.$t))) ||
|
|
'';
|
|
if (entry && entry.gd$extendedProperty) {
|
|
for (var k in entry.gd$extendedProperty) {
|
|
if (entry.gd$extendedProperty[k].name == 'blogger.contentRemoved') {
|
|
return '<span class="deleted-comment">' + text + '</span>';
|
|
}
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
var parse = function(data) {
|
|
cursor = null;
|
|
var comments = [];
|
|
if (data && data.feed && data.feed.entry) {
|
|
for (var i = 0, entry; entry = data.feed.entry[i]; i++) {
|
|
var comment = {};
|
|
// comment ID, parsed out of the original id format
|
|
var id = /blog-(\d+).post-(\d+)/.exec(entry.id.$t);
|
|
comment.id = id ? id[2] : null;
|
|
comment.body = bodyFromEntry(entry);
|
|
comment.timestamp = Date.parse(entry.published.$t) + '';
|
|
if (entry.author && entry.author.constructor === Array) {
|
|
var auth = entry.author[0];
|
|
if (auth) {
|
|
comment.author = {
|
|
name: (auth.name ? auth.name.$t : undefined),
|
|
profileUrl: (auth.uri ? auth.uri.$t : undefined),
|
|
avatarUrl: (auth.gd$image ? auth.gd$image.src : undefined)
|
|
};
|
|
}
|
|
}
|
|
if (entry.link) {
|
|
if (entry.link[2]) {
|
|
comment.link = comment.permalink = entry.link[2].href;
|
|
}
|
|
if (entry.link[3]) {
|
|
var pid = /.*comments\/default\/(\d+)\?.*/.exec(entry.link[3].href);
|
|
if (pid && pid[1]) {
|
|
comment.parentId = pid[1];
|
|
}
|
|
}
|
|
}
|
|
comment.deleteclass = 'item-control blog-admin';
|
|
if (entry.gd$extendedProperty) {
|
|
for (var k in entry.gd$extendedProperty) {
|
|
if (entry.gd$extendedProperty[k].name == 'blogger.itemClass') {
|
|
comment.deleteclass += ' ' + entry.gd$extendedProperty[k].value;
|
|
} else if (entry.gd$extendedProperty[k].name == 'blogger.displayTime') {
|
|
comment.displayTime = entry.gd$extendedProperty[k].value;
|
|
}
|
|
}
|
|
}
|
|
comments.push(comment);
|
|
}
|
|
}
|
|
return comments;
|
|
};
|
|
|
|
var paginator = function(callback) {
|
|
if (hasMore()) {
|
|
var url = config.feed + '?alt=json&v=2&orderby=published&reverse=false&max-results=50';
|
|
if (cursor) {
|
|
url += '&published-min=' + new Date(cursor).toISOString();
|
|
}
|
|
window.bloggercomments = function(data) {
|
|
var parsed = parse(data);
|
|
cursor = parsed.length < 50 ? null
|
|
: parseInt(parsed[parsed.length - 1].timestamp) + 1
|
|
callback(parsed);
|
|
window.bloggercomments = null;
|
|
}
|
|
url += '&callback=bloggercomments';
|
|
var script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = url;
|
|
document.getElementsByTagName('head')[0].appendChild(script);
|
|
}
|
|
};
|
|
var hasMore = function() {
|
|
return !!cursor;
|
|
};
|
|
var getMeta = function(key, comment) {
|
|
if ('iswriter' == key) {
|
|
var matches = !!comment.author
|
|
&& comment.author.name == config.authorName
|
|
&& comment.author.profileUrl == config.authorUrl;
|
|
return matches ? 'true' : '';
|
|
} else if ('deletelink' == key) {
|
|
return config.baseUri + '/comment/delete/'
|
|
+ config.blogId + '/' + comment.id;
|
|
} else if ('deleteclass' == key) {
|
|
return comment.deleteclass;
|
|
}
|
|
return '';
|
|
};
|
|
|
|
var replybox = null;
|
|
var replyUrlParts = null;
|
|
var replyParent = undefined;
|
|
|
|
var onReply = function(commentId, domId) {
|
|
if (replybox == null) {
|
|
// lazily cache replybox, and adjust to suit this style:
|
|
replybox = document.getElementById('comment-editor');
|
|
if (replybox != null) {
|
|
replybox.height = '250px';
|
|
replybox.style.display = 'block';
|
|
replyUrlParts = replybox.src.split('#');
|
|
}
|
|
}
|
|
if (replybox && (commentId !== replyParent)) {
|
|
replybox.src = '';
|
|
document.getElementById(domId).insertBefore(replybox, null);
|
|
replybox.src = replyUrlParts[0]
|
|
+ (commentId ? '&parentID=' + commentId : '')
|
|
+ '#' + replyUrlParts[1];
|
|
replyParent = commentId;
|
|
}
|
|
};
|
|
|
|
var hash = (window.location.hash || '#').substring(1);
|
|
var startThread, targetComment;
|
|
if (/^comment-form_/.test(hash)) {
|
|
startThread = hash.substring('comment-form_'.length);
|
|
} else if (/^c[0-9]+$/.test(hash)) {
|
|
targetComment = hash.substring(1);
|
|
}
|
|
|
|
// Configure commenting API:
|
|
var configJso = {
|
|
'maxDepth': config.maxThreadDepth
|
|
};
|
|
var provider = {
|
|
'id': config.postId,
|
|
'data': items,
|
|
'loadNext': paginator,
|
|
'hasMore': hasMore,
|
|
'getMeta': getMeta,
|
|
'onReply': onReply,
|
|
'rendered': true,
|
|
'initComment': targetComment,
|
|
'initReplyThread': startThread,
|
|
'config': configJso,
|
|
'messages': msgs
|
|
};
|
|
|
|
var render = function() {
|
|
if (window.goog && window.goog.comments) {
|
|
var holder = document.getElementById('comment-holder');
|
|
window.goog.comments.render(holder, provider);
|
|
}
|
|
};
|
|
|
|
// render now, or queue to render when library loads:
|
|
if (window.goog && window.goog.comments) {
|
|
render();
|
|
} else {
|
|
window.goog = window.goog || {};
|
|
window.goog.comments = window.goog.comments || {};
|
|
window.goog.comments.loadQueue = window.goog.comments.loadQueue || [];
|
|
window.goog.comments.loadQueue.push(render);
|
|
}
|
|
})();
|
|
// ]]>
|
|
</script>
|
|
<div id='comment-holder'>
|
|
<div class="comment-thread toplevel-thread"><ol id="top-ra"><li class="comment" id="c1012077880989438700"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/13855706515612188950" rel="nofollow">Richard OD</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1336463670531&m=1#c1012077880989438700">8:54 am</a></span></div><p class="comment-content">Great post Mike- oddly I saw it as a link in Google+ from Mark Seemann. Then I thought Code Rant- that sounds familiar. I then woke up. :-)</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="1012077880989438700">Reply</a><span class="item-control blog-admin blog-admin pid-1898508987"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/1012077880989438700">Delete</a></span></span></div><div class="comment-replies"><div id="c1012077880989438700-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c1012077880989438700-ra" class="thread-chrome thread-expanded"><div></div><div id="c1012077880989438700-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="1012077880989438700">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c1012077880989438700-ce"></div></li><li class="comment" id="c3394720192234672273"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/10017444373869046159" rel="nofollow">Bartosz Adamczewski</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1341494792251&m=1#c3394720192234672273">2:26 pm</a></span></div><p class="comment-content">Awesome post :-), it supposed to be called "THE DOOM CLOCK" ;-)</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="3394720192234672273">Reply</a><span class="item-control blog-admin blog-admin pid-2112481473"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/3394720192234672273">Delete</a></span></span></div><div class="comment-replies"><div id="c3394720192234672273-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c3394720192234672273-ra" class="thread-chrome thread-expanded"><div></div><div id="c3394720192234672273-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="3394720192234672273">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c3394720192234672273-ce"></div></li><li class="comment" id="c8686735983684834862"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/01281306154660757294" rel="nofollow">Marc Ziman</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1343903198119&m=1#c8686735983684834862">11:26 am</a></span></div><p class="comment-content">Mike - great post. I think it's dangerous to change config values on the fly. People can get it wrong and will bring down the app. So hardcode the values if you like or put it in a config file or whatever else - just make sure that you treat the change as any code change and run your full suite of tests before you deploy it. If your build and deploy process is solid it is no extra overhead to retest and deploy.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="8686735983684834862">Reply</a><span class="item-control blog-admin blog-admin pid-1270891356"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/8686735983684834862">Delete</a></span></span></div><div class="comment-replies"><div id="c8686735983684834862-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c8686735983684834862-ra" class="thread-chrome thread-expanded"><div></div><div id="c8686735983684834862-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="8686735983684834862">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c8686735983684834862-ce"></div></li><li class="comment" id="c1445748854476298674"><div class="avatar-image-container"><img src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFQxs5wBZI12TfthOR1jnCiUdb_m9tsplEzC2NxLyuEGvMrUOuFiiFuZySuC5GZgcVXpNpd6Sh3ySPzOrmRHXNCLrUiCZWtHsWAxuJjiJPVb5bvMesiDXBVCylXKGcrw/s45-c/TwitterPic.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/17940288175611154760" rel="nofollow">HolyTshirT</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1357049939090&m=1#c1445748854476298674">2:18 pm</a></span></div><p class="comment-content">Great post! Racing around the clock because you fear recompiling and redeploying, making this easy from the beginning, makes most of this problem go away. </p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="1445748854476298674">Reply</a><span class="item-control blog-admin blog-admin pid-213158011"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/1445748854476298674">Delete</a></span></span></div><div class="comment-replies"><div id="c1445748854476298674-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c1445748854476298674-ra" class="thread-chrome thread-expanded"><div></div><div id="c1445748854476298674-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="1445748854476298674">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c1445748854476298674-ce"></div></li><li class="comment" id="c2852103717952843526"><div class="avatar-image-container"><img src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4vz3rbnCGp0r8pCOavAUmukg2CNsaGtZObJ81LOb_vJIxq9d303uC4xcXaKIIlaPtgwbr_Z3tCwM2jWdaYU3DbwEK5410WJcHrCNWFeJwJbu_6xsy40Hyemw3XuattuQ/s45-c/photo.jpg%3Fsz%3D48" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/09268214549525093107" rel="nofollow">majkinetor</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1372110058726&m=1#c2852103717952843526">10:40 pm</a></span></div><p class="comment-content">Nice. Its probably the best to develop some nice devops solution in order to make deployment trivial and hard code things.<br><br>You need easy deployments anyway.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="2852103717952843526">Reply</a><span class="item-control blog-admin blog-admin pid-452087108"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/2852103717952843526">Delete</a></span></span></div><div class="comment-replies"><div id="c2852103717952843526-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c2852103717952843526-ra" class="thread-chrome thread-expanded"><div></div><div id="c2852103717952843526-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="2852103717952843526">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c2852103717952843526-ce"></div></li><li class="comment" id="c6389002651483066589"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/06626205218290678525" rel="nofollow">Steve M</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1411494133497&m=1#c6389002651483066589">6:42 pm</a></span></div><p class="comment-content">I love it. This is very similar to a pattern I've been thinking about for a while -- call it the Configuration Complexity Pendulum.<br><br>Year 0: Everything is done in code. <br><br>Year 1: Clever Programmer A realizes that he's writing the same code over and over. He parameterizes the code and moves the parameters into a configuration model. <br><br>Year 2: Requirements become more complex. Configuration model becomes more complex, and starts incorporating conditionals, exceptions, triggers... <br><br>Year 3: Clever Programmer B realizes that the XML has become a programming language in its own right -- a terrible one that takes 20 lines to say IF A THEN B. She starts writing an API or a DSL...<br><br>And thus, we swing back and forth between code and config, forever.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6389002651483066589">Reply</a><span class="item-control blog-admin blog-admin pid-340947693"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/6389002651483066589">Delete</a></span></span></div><div class="comment-replies"><div id="c6389002651483066589-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6389002651483066589-ra" class="thread-chrome thread-expanded"><div></div><div id="c6389002651483066589-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6389002651483066589">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6389002651483066589-ce"></div></li><li class="comment" id="c6570454548886645121"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/00651108358845555553" rel="nofollow">Unknown</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1445167100437&m=1#c6570454548886645121">12:18 pm</a></span></div><p class="comment-content">Great post and I recognise this pattern. These days I use Octopus deploy as part of a one-click deployment pipeline and it does help minimise the pain when you need to either update config or have hard coded values in your app. </p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6570454548886645121">Reply</a><span class="item-control blog-admin blog-admin pid-124592662"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/6570454548886645121">Delete</a></span></span></div><div class="comment-replies"><div id="c6570454548886645121-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6570454548886645121-ra" class="thread-chrome thread-expanded"><div></div><div id="c6570454548886645121-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6570454548886645121">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6570454548886645121-ce"></div></li><li class="comment" id="c3628154816008574136"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/05479636752592300779" rel="nofollow">Christopher Hoover</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1454824311920&m=1#c3628154816008574136">5:51 am</a></span></div><p class="comment-content">Perhaps if you use Common Lisp, the circle collapses to a point.<br></p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="3628154816008574136">Reply</a><span class="item-control blog-admin blog-admin pid-1560201580"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/3628154816008574136">Delete</a></span></span></div><div class="comment-replies"><div id="c3628154816008574136-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c3628154816008574136-ra" class="thread-chrome thread-expanded"><div></div><div id="c3628154816008574136-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="3628154816008574136">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c3628154816008574136-ce"></div></li><li class="comment" id="c8000196940795196079"><div class="avatar-image-container"><img src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6DJSoFPEae_HE-vEMX4mDLDn9fFhyN5Q-sIQkkvJMuPZEsQBLSjrxHHxHlD1zkVEmcLXiNFH-JHDYTXy3R5BP9DucygEZVv-rnfz6_Ax4AZfoJzNvtf0gCkqz4DOD8ikQlP3BqtoBqr8oBqCSrxvE9pBdH_SH-o1ZmPVwbC8plOJcSQ/s45/Profile%20170122%20APW%20-%20SolidTen%20Img2Img%20512x512%20-%20available.jpg" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/16072516650932490004" rel="nofollow">Graham Poulter</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1457001606835&m=1#c8000196940795196079">10:40 am</a></span></div><p class="comment-content">The example seems to be assuming a single deployment - one binary running in one place, and the configured variables vary over *time* but not over *space*.<br><br>However, if the packaged binary runs in many places, some values vary depending on where it is deployed: at a minimum things like what datacenter, what user, what backends to connect to, what paths to read from, as well as anything else that varies by user. <br><br>While "temporal" variations can easily be hardcoded if you have a short release cycle, "spatial" variations are not so easily hardcoded: you end up maintaining a source branch for each active variant.<br><br>And then what do you do if the spatial variations are enormous: a huge amount of information that differs between deployment? <br><br>Then you might consider hard-coding the spatially varying part separate from main application which does not vary: write a separate piece of code that generates a structured data format with all the config information, which the main application slurps in. <br><br>I suggest having three marks on the clock for such data: <br>12: nothing varies spatially, everything in main code<br>3: separate a few flags varying spatially (--input_path=/somewhere)<br>6: structured data format for a larger number of spatially-varying parameters (protobuf, INI, JSON, XML). <br>9: DSL, to generate the structured data. Skip this if at all possible!<br>12: Full-fledged programming language to generated the structured data.<br><br>For the things that vary temporally (having the same value in all deployments), now you have a choice of whether to hard-code it in the main application, or move it in to the config data, based on whether it changes more or less frequently than the release frequency of the main application.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="8000196940795196079">Reply</a><span class="item-control blog-admin blog-admin pid-1993467337"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/8000196940795196079">Delete</a></span></span></div><div class="comment-replies"><div id="c8000196940795196079-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c8000196940795196079-ra" class="thread-chrome thread-expanded"><div></div><div id="c8000196940795196079-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="8000196940795196079">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c8000196940795196079-ce"></div></li><li class="comment" id="c3341834029817722006"><div class="avatar-image-container"><img src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaid2gG6bt07rEOnEDRz3xgQtFXL6yg7YGbTm862zuG17WEsIAbSxvvTUyXxT4ij3pbxYypZ44HgoPC9Z1Yc1rop0rAhqOjQw-sp9Q50gnFcatVjudjJQVjUBOMPe69Q/s45-c/old_robot_fullsize%5B1%5D.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/12533760807956258274" rel="nofollow">Jonathan Gilbert</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1493150478726&m=1#c3341834029817722006">9:01 pm</a></span></div><p class="comment-content">On UNIX systems, configuration is often done in the form of a script that is technically capable of arbitrary programming complexity but whose base case <i>looks</i> declarative.<br><br>For instance, on one of my FreeBSD servers, /etc/rc.conf starts out with the following lines:<br><br>hostname="laliari.logiclrd.cx"<br><br>defaultrouter="184.71.82.245"<br>ifconfig_vtnet0="inet 10.0.0.1 netmask 255.128.0.0"<br>ifconfig_vtnet1="inet 184.71.82.246 netmask 255.255.255.252"<br><br>gateway_enable="YES"<br>natd_enable="YES"<br>natd_interface="vtnet1"<br>natd_flags=`/root/make_natd_flags/make_natd_flags`<br><br>(I'd have used a PRE tag for that but blogger.com doesn't allow it!)<br><br>Everything there looks pretty straightforward -- name equals value, repeat as necessary -- except, whoa, what's going on in that last line? I am actually running an external program to generate the flags to pass to natd.<br><br>This type of configuration, leveraging a common, system-wide scripting facility, means your users can do simple configuration without ever knowing the system isn't purely declarative, and more complicated configuration can use arbitrary programming techniques. In this example, make_natd_flags is actually a small C application, but it could be absolutely any command-line, or could even be implemented in shell script right inside the rc.conf file.<br><br>This mode of configuration has been the de facto standard for a <i>very</i> long time, and doesn't seem to be progressing around the clock. Where would you say the clock is stopped for this type of configuration? I find I can't really assign it a position on the clock; it seems to combine most of the advantages of most of the "times" you've described, without suffering unduly from the downsides. The only real problem I see with it is that a user who is terribly inexperienced, or who suffers greatly when it comes to attention to detail, is at greater risk of producing a configuration file with syntax errors, even if the syntax is as simple as 'name="value"'...</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="3341834029817722006">Reply</a><span class="item-control blog-admin blog-admin pid-1721326507"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/3341834029817722006">Delete</a></span></span></div><div class="comment-replies"><div id="c3341834029817722006-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c3341834029817722006-ra" class="thread-chrome thread-expanded"><div></div><div id="c3341834029817722006-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="3341834029817722006">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c3341834029817722006-ce"></div></li><li class="comment" id="c8938558998355814484"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/05266324397464608866" rel="nofollow">RMKnightStar</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1493341459903&m=1#c8938558998355814484">2:04 am</a></span></div><p class="comment-content">This struck nerve with me. I have been in technology for over 35 years and I have to say that I have seen this clock cycle, time after time after time. Though I really had never seen it illustrated like this. When ever I am thinking about a new system, the line between configuration and code generally gets a lot of thought. This is really good food for thought!</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="8938558998355814484">Reply</a><span class="item-control blog-admin blog-admin pid-1611360876"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/8938558998355814484">Delete</a></span></span></div><div class="comment-replies"><div id="c8938558998355814484-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c8938558998355814484-ra" class="thread-chrome thread-expanded"><div></div><div id="c8938558998355814484-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="8938558998355814484">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c8938558998355814484-ce"></div></li><li class="comment" id="c6276158804119870954"><div class="avatar-image-container"><img src="//resources.blogblog.com/img/blank.gif" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user">Anonymous</cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1494389363299&m=1#c6276158804119870954">5:09 am</a></span></div><p class="comment-content">Awesome post !! definitely could relate to it to some of the projects i had been working on now. </p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6276158804119870954">Reply</a><span class="item-control blog-admin blog-admin pid-1134234061"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/6276158804119870954">Delete</a></span></span></div><div class="comment-replies"><div id="c6276158804119870954-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6276158804119870954-ra" class="thread-chrome thread-expanded"><div></div><div id="c6276158804119870954-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6276158804119870954">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6276158804119870954-ce"></div></li><li class="comment" id="c4932463847057046737"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/03776425973161864367" rel="nofollow">pt</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1494423682972&m=1#c4932463847057046737">2:41 pm</a></span></div><p class="comment-content">You left out the step where the config values are put into a database. The boss likes Lotus Notes despite the fact it isn't relational and isn't really a database, so that's where config values go. Nine months later he's gone and the team takes the opportunity to move the data to Oracle, except the two people who quit because they hate Oracle. Nine months later Oracle raises prices so the dB gets migrated to SQL Server. Another developer quits because he hates Microsoft.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="4932463847057046737">Reply</a><span class="item-control blog-admin blog-admin pid-938301485"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/4932463847057046737">Delete</a></span></span></div><div class="comment-replies"><div id="c4932463847057046737-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c4932463847057046737-ra" class="thread-chrome thread-expanded"><div></div><div id="c4932463847057046737-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="4932463847057046737">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c4932463847057046737-ce"></div></li><li class="comment" id="c5447521052242060318"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/10621655805082979910" rel="nofollow">Scott Cooper</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1588275965771&m=1#c5447521052242060318">8:46 pm</a></span></div><p class="comment-content">Reminds me of Ivan Sutherland's Wheel of Reincarnation: http://cva.stanford.edu/classes/cs99s/papers/myer-sutherland-design-of-display-processors.pdf</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="5447521052242060318">Reply</a><span class="item-control blog-admin blog-admin pid-1009441534"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/5447521052242060318">Delete</a></span></span></div><div class="comment-replies"><div id="c5447521052242060318-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c5447521052242060318-ra" class="thread-chrome thread-expanded"><div></div><div id="c5447521052242060318-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="5447521052242060318">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c5447521052242060318-ce"></div></li><li class="comment" id="c2304100423456379351"><div class="avatar-image-container"><img src="//www.blogger.com/img/blogger_logo_round_35.png" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/00934389605618434836" rel="nofollow">Xeno PuTtSs</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1594930380116&m=1#c2304100423456379351">9:13 pm</a></span></div><p class="comment-content">Just want to say, its the year 2020 now and I am still using this document almost 3 times a year to show this same pattern. This is one of those things that hasn't yet changed.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="2304100423456379351">Reply</a><span class="item-control blog-admin blog-admin pid-963430594"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/2304100423456379351">Delete</a></span></span></div><div class="comment-replies"><div id="c2304100423456379351-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c2304100423456379351-ra" class="thread-chrome thread-expanded"><div></div><div id="c2304100423456379351-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="2304100423456379351">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c2304100423456379351-ce"></div></li><li class="comment" id="c3389589970787810323"><div class="avatar-image-container"><img src="//4.bp.blogspot.com/_17f8J0-AILs/SasqAYMZYzI/AAAAAAAAAF0/zL6EqFcyCVA/S45-s35/107364148_d20c328584_m.jpg" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/17024579990613770367" rel="nofollow">Dan Nugent</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1598630180730&m=1#c3389589970787810323">4:56 pm</a></span></div><p class="comment-content">I think there's a way out: Use sqlite for storing configurable values. It's a self-contained file format, it has a way to dump to a reviewable, versionable text representation for tracking, it's fast enough to access online so you can modify things during runtime, it's got a lot of tooling support, it uses a real language, it's extensible, there are specific rules for how to migrate data and if you adhere to the generally advised notion of never directly accessing data through tables and only using views, straightforward migrations of the configurations are possible.<br><br>If there's a significant drawback it's that the types are a bit too flexible, but not much worse than many other text formats.</p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="3389589970787810323">Reply</a><span class="item-control blog-admin blog-admin pid-796958054"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/3389589970787810323">Delete</a></span></span></div><div class="comment-replies"><div id="c3389589970787810323-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c3389589970787810323-ra" class="thread-chrome thread-expanded"><div></div><div id="c3389589970787810323-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="3389589970787810323">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c3389589970787810323-ce"></div></li><li class="comment" id="c6378402402338750504"><div class="avatar-image-container"><img src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAteAqrBP5eh8lxR10ZJMyD7CEDE8LtRMiKFcoHNanvu0hc7fqOQa8QSnbdK4EoZIxi3JTlam8kliSGPn57z04FXYRhBCr0SFfV9zPHZV36lQ-zDhYmBTGR59gzTJIHw/s45-c/IMG_7907.JPG" alt=""/></div><div class="comment-block"><div class="comment-header"><cite class="user"><a href="https://www.blogger.com/profile/16917852879964673515" rel="nofollow">geeklinda</a></cite><span class="icon user "></span><span class="datetime secondary-text"><a rel="nofollow" href="http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?showComment=1607994935472&m=1#c6378402402338750504">1:15 am</a></span></div><p class="comment-content">Oh no, it me :( :( </p><span class="comment-actions secondary-text"><a class="comment-reply" target="_self" data-comment-id="6378402402338750504">Reply</a><span class="item-control blog-admin blog-admin pid-100303103"><a target="_self" href="https://www.blogger.com/comment/delete/15136575/6378402402338750504">Delete</a></span></span></div><div class="comment-replies"><div id="c6378402402338750504-rt" class="comment-thread inline-thread hidden"><span class="thread-toggle thread-expanded"><span class="thread-arrow"></span><span class="thread-count"><a target="_self">Replies</a></span></span><ol id="c6378402402338750504-ra" class="thread-chrome thread-expanded"><div></div><div id="c6378402402338750504-continue" class="continue"><a class="comment-reply" target="_self" data-comment-id="6378402402338750504">Reply</a></div></ol></div></div><div class="comment-replybox-single" id="c6378402402338750504-ce"></div></li></ol><div id="top-continue" class="continue"><a class="comment-reply" target="_self">Add comment</a></div><div class="comment-replybox-thread" id="top-ce"></div><div class="loadmore hidden" data-post-id="2125139449813877883"><a target="_self">Load more...</a></div></div>
|
|
</div>
|
|
</div>
|
|
<p class='comment-footer'>
|
|
<div class='comment-form'>
|
|
<a name='comment-form'></a>
|
|
<p>
|
|
</p>
|
|
<p>Note: only a member of this blog may post a comment.</p>
|
|
<a href='https://www.blogger.com/comment/frame/15136575?po=2125139449813877883&hl=en-GB&saa=85391&origin=http://mikehadlow.blogspot.com&m=1' id='comment-editor-src'></a>
|
|
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' frameborder='0' height='410px' id='comment-editor' name='comment-editor' src='' style='display: none' width='100%'></iframe>
|
|
<script src='https://www.blogger.com/static/v1/jsbin/3790099508-comment_from_post_iframe.js' type='text/javascript'></script>
|
|
<script type='text/javascript'>
|
|
BLOG_CMT_createIframe('https://www.blogger.com/rpc_relay.html');
|
|
</script>
|
|
</div>
|
|
</p>
|
|
<div id='backlinks-container'>
|
|
<div id='Blog1_backlinks-container'>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class='blog-pager' id='blog-pager'>
|
|
<div class='mobile-link-button' id='blog-pager-newer-link'>
|
|
<a class='blog-pager-newer-link' href='http://mikehadlow.blogspot.com/2012/05/easynetq-breaking-change.html?m=1' id='Blog1_blog-pager-newer-link' title='Newer Post'>‹</a>
|
|
</div>
|
|
<div class='mobile-link-button' id='blog-pager-older-link'>
|
|
<a class='blog-pager-older-link' href='http://mikehadlow.blogspot.com/2012/05/how-do-i-detect-when-client-thread.html?m=1' id='Blog1_blog-pager-older-link' title='Older Post'>›</a>
|
|
</div>
|
|
<div class='mobile-link-button' id='blog-pager-home-link'>
|
|
<a class='home-link' href='http://mikehadlow.blogspot.com/?m=1'>Home</a>
|
|
</div>
|
|
<div class='mobile-desktop-link'>
|
|
<a class='home-link' href='http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?m=0'>View web version</a>
|
|
</div>
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='column-left-outer'>
|
|
<div class='column-left-inner'>
|
|
<aside>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
<div class='column-right-outer'>
|
|
<div class='column-right-inner'>
|
|
<aside>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style='clear: both'></div>
|
|
<!-- columns -->
|
|
</div>
|
|
<!-- main -->
|
|
</div>
|
|
</div>
|
|
<div class='main-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
<footer>
|
|
<div class='footer-outer'>
|
|
<div class='footer-cap-top cap-top'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
<div class='fauxborder-left footer-fauxborder-left'>
|
|
<div class='fauxborder-right footer-fauxborder-right'></div>
|
|
<div class='region-inner footer-inner'>
|
|
<div class='foot no-items section' id='footer-1'></div>
|
|
<!-- outside of the include in order to lock Attribution widget -->
|
|
<div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'>
|
|
<div class='widget-content' style='text-align: center;'>
|
|
Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>.
|
|
</div>
|
|
<div class='clear'></div>
|
|
</div></div>
|
|
</div>
|
|
</div>
|
|
<div class='footer-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
<!-- content -->
|
|
</div>
|
|
</div>
|
|
<div class='content-cap-bottom cap-bottom'>
|
|
<div class='cap-left'></div>
|
|
<div class='cap-right'></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type='text/javascript'>
|
|
window.setTimeout(function() {
|
|
document.body.className = document.body.className.replace('loading', '');
|
|
}, 10);
|
|
</script>
|
|
|
|
<script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/1363620594-widgets.js"></script>
|
|
<script type='text/javascript'>
|
|
var BLOG_BASE_IMAGE_URL = 'https://resources.blogblog.com/img';var BLOG_LANG_DIR = 'ltr';window['__wavt'] = 'AAPvtVnvos58KXVN0oOkGlODDLiv:1789171811146';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d15136575','//mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?m\x3d1','15136575');
|
|
_WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '15136575', 'title': 'Code rant', 'url': 'http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?m\x3d1', 'canonicalUrl': 'http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html', 'homepageUrl': 'http://mikehadlow.blogspot.com/?m\x3d1', 'searchUrl': 'http://mikehadlow.blogspot.com/search', 'canonicalHomepageUrl': 'http://mikehadlow.blogspot.com/', 'blogspotFaviconUrl': 'http://mikehadlow.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': '', 'encoding': 'UTF-8', 'locale': 'en-GB', 'localeUnderscoreDelimited': 'en_gb', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': true, 'isMobileRequest': true, 'mobileClass': ' mobile', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Code rant - Atom\x22 href\x3d\x22http://mikehadlow.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Code rant - RSS\x22 href\x3d\x22http://mikehadlow.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Code rant - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/15136575/posts/default\x22 /\x3e\n\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Code rant - Atom\x22 href\x3d\x22http://mikehadlow.blogspot.com/feeds/2125139449813877883/comments/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'isGoogleEverywhereLinkTooltipEnabled': true, 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/1890a9484e710b1c', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en_GB\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'item', 'postId': '2125139449813877883', 'postImageThumbnailUrl': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/s72-c/?imgmax\x3d800', 'postImageUrl': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/?imgmax\x3d800', 'pageName': 'The Configuration Complexity Clock', 'pageTitle': 'Code rant: The Configuration Complexity Clock'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard', 'ok': 'Ok', 'postLink': 'Post link'}}, {'name': 'template', 'data': {'name': 'Simple', 'localizedName': 'Simple', 'isResponsive': false, 'isAlternateRendering': true, 'isCustom': false, 'variant': 'simplysimple', 'variantId': 'simplysimple'}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': true, 'title': 'The Configuration Complexity Clock', 'description': 'When I was a young coder, just starting out in the big scary world of enterprise software, an older, far more experienced chap gave me a ste...', 'featuredImage': 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_s1ytB4dVQjhyXfUOe-381ycBjdoauKD5w7c4rFnajVPYumENd6M9A6a0ySa3LP2XI-gWOzqjlkeN82PqWZpxxcLMG0c6IaAugivnUbOjh_IaEDPMEd5BAL1GdNoRakXxEsz9zg/?imgmax\x3d800', 'url': 'http://mikehadlow.blogspot.com/2012/05/configuration-complexity-clock.html?m\x3d1', 'type': 'item', 'isSingleItem': true, 'isMultipleItems': false, 'isError': false, 'isPage': false, 'isPost': true, 'isHomepage': false, 'isArchive': false, 'isLabelSearch': false, 'postId': 2125139449813877883}}]);
|
|
_WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'mobile': true}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull'));
|
|
_WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull'));
|
|
</script>
|
|
</body>
|
|
</html> |