Designing and Maintaining Software (DAMS) Louis Rose
Habitable Software Leaner
Avoids Duplication
Less Complex
Clearer
Loosely Coupled
More Extensible
More Cohesive
???
Tactics Favour shorter methods (and classes) Favour “functional style” to loops Favour method calls to conditionals
Loops Conjecture 1: Looping is a low-level evil class Pizza def title if @toppings.empty? "Margherita" else title = "" @toppings.each do |topping| title += " and " unless title.empty? title += topping end title end end end
Loop like it’s 1999 Remember this? class Pizza def title if @toppings.empty? "Margherita" else title = "" index = 0 while index < @toppings.length topping = @toppings[index] title += " and " unless title.empty? title += topping index += 1 end title end end end
Loop like it’s 1999 Or was it this? class Pizza def title if @toppings.empty? "Margherita" else title = "" index = 0 while index <= @toppings.length topping = @toppings[index] title += " and " unless title.empty? title += topping index += 1 end title end end end
Loop like it’s 1999 Or this??! class Pizza def title if @toppings.empty? "Margherita" else title = "" index = 0 while index <= @toppings.length - 1 topping = @toppings[index] title += " and " unless title.empty? title += topping index += 1 end title end end end
Loop like it’s 2099 Let’s never do that again class Pizza def title if @toppings.empty? "Margherita" else title = "" @toppings.each do |topping| title += " and " unless title.empty? title += topping end title end end end
Loop like it’s 2099 And most modern languages have now learnt from FP class Pizza def title if @toppings.empty? "Margherita" else title = "" @toppings.each do |topping| title += " and " unless title.empty? title += topping end title end end end
Loop like it’s 2099 Ruby: see the Enumerable API
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Loop like it’s 2099 Ruby: see the Enumerable API
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Conditionals Conjecture 2: Conditionals are a low-level evil
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Conditionals Toppings is an array. Is it the right abstraction?
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Conditionals Toppings is an array. Is it the right abstraction?
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Conditionals Toppings is an array. Is it the right abstraction?
class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end end
Conditionals If only Ruby arrays knew about pizzas…
class Pizza def title @toppings.pizzaify end end
Conditionals Array is not the right abstraction.
class Pizza def initialize(toppings = []) @toppings = toppings end def title @toppings.pizzaify end end
Conditionals Array is not the right abstraction. class Pizza def initialize(toppings = []) if toppings.empty? @toppings = Plain.new else @toppings = Topped.new(toppings) end end def title @toppings.pizzaify end end
Conditionals Abstractions should come from the problem domain. class Pizza def initialize(toppings = []) if toppings.empty? @toppings = Plain.new else @toppings = Topped.new(toppings) end end def title @toppings.pizzaify end end
class Plain def pizzaify "Margherita" end end class Topped def initialize(toppings = []) @toppings = toppings end def pizzaify @toppings.join(“ and ") end end
Conditionals Pizzaify wasn’t the greatest name… class Pizza def initialize(toppings = []) if toppings.empty? @toppings = Plain.new else @toppings = Topped.new(toppings) end end def title @toppings.title end end
class Plain def title "Margherita" end end class Topped def initialize(toppings = []) @toppings = toppings end def title @toppings.join(" and ") end end
Hang on… Classes
Methods
LOC
Cyclomatic Complexity (>1)
1
2
12
Pizza#title
3
5
25
Pizza#initialize
Conditionals But these kinds of conditionals tend to breed… class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end def cost cost = 4 if @toppings.empty? cost += 1 else cost += @toppings.size * 2 end end end
Conditionals But these kinds of conditionals tend to breed… class Pizza def title if @toppings.empty? "Margherita" else @toppings.join(" and ") end end def cost cost = 4 if @toppings.empty? cost += 1 else cost += @toppings.size * 2 end end end
Conditionals Prefer method calls to conditionals. class Plain def title "Margherita" end
class Pizza def title @toppings.title end def cost @toppings.cost + 4 end end
def cost 1 end end class Topped def title @toppings.join(" and ") end def cost @toppings.size * 2 end end
Aha! Classes
Methods
LOC
Cyclomatic Complexity (>1)
1
3
20
Pizza#title Pizza#cost
3
8
34
Pizza#initialize
Null Object Pattern Encapsulate the absence of an object
Active Nothing
Summary Complex methods hinder habitability. Avoid loops by using a declarative, functional style. Avoid conditionals by using objects and method calls.
Also important Strategy and Visitor patterns for avoiding conditionals in other situations. Further resources on designing to avoid conditionals: “Nothing is Something” Sandi Metz (RailsConf 2015) “Unconditional Programming” Michael Feathers (2013 blog post)
Sequential consistency (SC) is arguably the most intuitive behavior for a shared-memory multithreaded program. It is widely accepted that language-level SC could significantly improve programmability of a multiprocessor system. How- ever, efficiently
domain = meq.domain(10,20,0,10); cells = meq.cells(domain,num_freq=200, num_time=100); ...... This is now contaminator-free. â Observe the ghosts. Optional ...
data can only be âcorrectedâ for a single point on the sky. ... sufficient to predict it at the phase center (shifting ... errors (well this is actually good news, isn't it?)
Mar 30, 2001 - M.I.T. Laboratory for Computer Science ... The argument appeals to application requirements, and provides ... the application provide the basis for a class of arguments, which go as follows: ... correctly onto the disk at host A, if re
A service level agreement (SLA) is the contract by which requests for a certain QoS are specified between the user and the Internet service provider (ISP).
Large Vocabulary Continuous Speech Recognition with TensorFlow. Ehsan Variani ... to batching of training data, unrolling of recurrent acoustic models, and ...
When the encryption completes, the ransomware displays a ransom note on the host's screen, informing the user that those files are held for ransom, payable in ...... file system, we place documents that Cerber is known to encrypt [11]. We also instru
Previous studies have reported statistics and character- ... The percentages of RO observed on data ... the analysis of the data collected in our four measure-.
architecture has performed better than traditional DNNs , and the use of temporal ..... pass large vocabulary continuous speech recognition using bi- directional ...
and services running on top of the network infrastructure. Since changes ... ROUTE. CAPACITY. Fig. 1. Correlations in different e2e network metrics along with.
High combines several different data sources such as BGP tables from routers, mapping of ... In Section 4, we describe the WhyHigh system that we developed to diagnose ... the nameserver. Redirection decisions made at the granularity of.
Jul 13, 2009 - Different wireless technologies and different types of communication interfaces .... WiFi and a 3G interface, and can be a laptop, a PDA or a 3G.
End-to-end service deployment of Network Functions Vir- ... 1. Service graph deployment in a multi-domain environment. the proper network parameters, thus ...
J.-W. Lee is with CITY-Center for Information Technology of Yonsei. University, Department .... we need a central controller to collect the information of each link and perform the ...... degree in Electrical and Computer Engineer- ing from Purdue ..
bi mod 2, i = 1...N. It is easy to see the relationship â¼ is an equivalence relationship. Therefore, it defines a partition over Î. 1) Depending on the values of ai âbi ...