Code structures help fit code into your head
Code structure conveys intention, not function
function main()
const vat = 0.21;
print("Base price:")
var base_price = read(stdin)
var consumer_price = vat * base_price
print("Consumer price: "+consumer_price)
end
class VatCalculatorApp{
var console = getConsole()
function getConsole()
return new TerminalConsole()
// was: return new NetworkConsole("localhost",8080)
end
function getConfiguration()
return System.readConfiguration("vatcalculator.ini")
end
function getVat()
getConfiguration().getProperty("vat")
end
function computeVat(basePrice)
return basePrice * getVat()
end
function askForBasePrice()
console.print("Enter base price:")
return console.read()
end
function showConsumerPrice(consumer_price)
console.print("Consumer price: "+consumer_price)
end
function main()
var base_price = askForBasePrice()
var consumer_price = computeVat(base_price)
showConsumerPrice(consumer_price)
end
}
Code structures create dependencies
Code duplication guards against unintended change
function askForBasePrice()
do
console.print("Enter base price:")
var price = console.read()
if price < 0 then console.print("Price can't be negative")
while price<0
return price
end
Seems to make sense, right? It turns out that negative VAT makes sense elsewhere [2] and I just pissed off my Japanese users. By moving code into its own silos one creates dependencies which need to be met at compile- or run-time, leading to well-known dependency problems [1]. There are various approaches to keeping dependency problems at bay, like version management, private packaging, static compilation and containerisation.
Code duplication in the container age
The Go programming language [3] makes dependency management a major priority by taking the opinionated stance that programs should be compilable on all platforms and statically linked at compile time, which means nothing else than that all dependencies are packaged into the programme binary.
Build tools like Ivy and Maven, concepts like application containerisation (e.g. Docker) and micro services as an architectural deployment pattern all complement and advance decoupling as part of a defensive software architecture strategy [4] into what essentially is code duplication at scale bundled with the comfort of build automation.
By bundling entire applications with their dependencies, databases and even operating systems (e.g. VM images) a programmer most effectively defines a stable base for an application, shielding it against many compile- and run-time dependency incompatibilities. In this scenario, reusable code is deployed multiple times as multiple copies throughout a (distributed) system, being used at multiple places in the form of binary dependencies or remote services where most likely even different versions of the code are deployed and operable at the same time.
“But”, one might argue again, “this is not code duplication”. While indeed it may not seem like code duplication at the source code level, it certainly is code duplication at the runtime level and it forces the programmer to think about which versions are deployed where and what the implications are, ranging from nuisances like the precise meaning of a singleton [5] to service discovery [6] and API versioning [7]. Even better, by automatic code duplication through deployment automation, the pain of structuring code “just because” is deferred to even never, because each programme is complete in its isolated view.
Resources
[1] Dependency hell
https://en.wikipedia.org/wiki/Dependency_hell
[2] VAT implementations
https://en.wikipedia.org/wiki/Value-added_tax#Implementation
[3] Go
https://en.wikipedia.org/wiki/Go_(programming_language)#Language_design
[4] Defensive software architecture
https://georgovassilis.blogspot.com/2015/12/defensive-software-architecture.html
[5] Geek and poke pattern tip of the week
http://geekandpoke.typepad.com/geekandpoke/2010/12/the-geekpoke-pattern-tip-of-the-week.html
[6] Service discovery
https://en.wikipedia.org/wiki/Service_discovery
[7] Best practices for API versioning
http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
[8] Assembly tests
https://georgovassilis.blogspot.de/2016/01/assembly-tests.html
I'm a developer and like your thoughts on copying code. Great job George.
mark mail archive
LikeLike
Thanks Sneha
LikeLike