<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chirag Jain</title>
    <description>The latest articles on DEV Community by Chirag Jain (@cjthedev).</description>
    <link>https://dev.to/cjthedev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F55247%2Faba4d995-a248-4765-8ef5-718ecc14b152.jpg</url>
      <title>DEV Community: Chirag Jain</title>
      <link>https://dev.to/cjthedev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cjthedev"/>
    <language>en</language>
    <item>
      <title>Opening office hours for mock interviews</title>
      <dc:creator>Chirag Jain</dc:creator>
      <pubDate>Wed, 29 Apr 2020 15:47:12 +0000</pubDate>
      <link>https://dev.to/cjthedev/opening-office-hours-for-mock-interviews-36n7</link>
      <guid>https://dev.to/cjthedev/opening-office-hours-for-mock-interviews-36n7</guid>
      <description>&lt;p&gt;I'm opening office hours to help folks prepare for interviews.&lt;/p&gt;

&lt;p&gt;I'd conduct a mock interview.&lt;br&gt;
I'll share actionable feedback with relevant resources.&lt;/p&gt;

&lt;p&gt;You can book a slot here: &lt;a href="https://calendly.com/chirag-jain/mock-inteview"&gt;https://calendly.com/chirag-jain/mock-inteview&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>On Abstraction – Zach Tellman - ClojuTre 2017</title>
      <dc:creator>Chirag Jain</dc:creator>
      <pubDate>Sun, 24 Mar 2019 22:55:43 +0000</pubDate>
      <link>https://dev.to/cjthedev/on-abstraction--zach-tellman---clujutre-2017-42a3</link>
      <guid>https://dev.to/cjthedev/on-abstraction--zach-tellman---clujutre-2017-42a3</guid>
      <description>&lt;p&gt;Zach Tellman is the author of the book "Elements of Clojure". In this talk titled "On Abstraction" he tries to define what is an abstraction and how do we can build better systems with a better understanding of what goes into making an abstraction.&lt;/p&gt;

&lt;p&gt;The goal of the book was the best second book you read about Clojure, when you know what you can do with the language but you don't know what parts of the language to use to solve a particular problem.&lt;/p&gt;

&lt;p&gt;The first chapter was about names: "Naming and Necessity". Even though it is well known that naming is a hard problem, CS doesn't have enough literature tackling the problem. "The analytics school of psychology" has explored the topic in excruciating detail.&lt;/p&gt;

&lt;p&gt;The second chapter was about abstraction but there wasn't any literature directly targeting it and no other paradigm deals with this topic in depth.&lt;/p&gt;

&lt;h1&gt;
  
  
  Abstraction
&lt;/h1&gt;

&lt;p&gt;The word abstraction is used to refer to 2 very distinct concepts, demonstrated by the following 2 ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Church Numerals&lt;/p&gt;

&lt;p&gt;Alonzo Church's lambda calculus introduced these. The numbers are represented as functions, the number 3 is a function which takes a function and applies it 3 times to a value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons Cells&lt;/p&gt;

&lt;p&gt;Typically used to create linked lists, with the base case of &lt;code&gt;Nil&lt;/code&gt; representing an empty collection.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Church Numeral weren't used in Computer Science because representing numbers in computationally intensive, they have been widely used in mathematics (which is timeless). Cons Cells are widely used in CS, because following a link is fast, but the landscape has changed rapidly the computer processing has increased more rapidly than the decrease in memory latency.&lt;/p&gt;

&lt;p&gt;The most common formal definition of abstraction in CS literature comes from the paper: "Proof of Correctness of Data Representation" by Tony Hoare, who also brought us "Communicating Sequential Processes".&lt;/p&gt;

&lt;p&gt;The paper introduces 2 major concepts:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Abstractions model the internal model onto the external semantics.&lt;/p&gt;

&lt;p&gt;Invariant constrain the internal model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abstraction is the mapping of the internal implementation to the external interface. The invariant allows different implementations without being correct with respect to each other, they only have to satisfy the invariant. It however doesn't talk about the environment the object operates in.&lt;/p&gt;

&lt;p&gt;To define an abstraction we need 3 parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Model&lt;/p&gt;

&lt;p&gt;The implementation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Interface&lt;/p&gt;

&lt;p&gt;The means to interact with the Model&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Environment&lt;/p&gt;

&lt;p&gt;Everything else&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Model
&lt;/h2&gt;

&lt;p&gt;The model is initially empty, all the data comes from the environment hence in a way the model reflects the environment. This is close to what Physics does to create models for real world concepts. We can't do this in Software as Physics uses deductive reasoning to create a model based on observation and keep tweaking it until the predictions are correct, to model this in software would require a very rick model.&lt;/p&gt;

&lt;p&gt;50-60 years before physicists were actively involved in computer programming. In 1959 the first attempt at AI was made in a project called "General Problem Solver (GPS)" using means-end analysis.&lt;/p&gt;

&lt;p&gt;Most of software instead relies on inductive reasoning which is based on analogy, this allows us to skip a lot of details making the models a lot simpler. Example: A tick — It latches onto something generating heat or secreting butyric acid above a certain threshold. We cannot create a perfect model for this but we don't need to. The model just needs to be accurate enough.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The model can only satisfice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The book "The science of the artificial" by Herbert Simon (principal investigator for the GPS) coined the term satisfice for "pragmatically crappy solution".&lt;/p&gt;

&lt;p&gt;It's easy to make deductive model, but hard to make a useful one. We can reduce something in terms of arithmetic for a deductive model but it it doesn't mean that the predictions would be right.&lt;/p&gt;

&lt;p&gt;Models assume everything that they omit is either invariant or irrelevant. When assumptions leak out we have to use conventions. This doesn't make the assumption always valid, it makes it less likely to be invalid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interface
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Interfaces represent the intersection of many models or one model over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Consequences of our Model
&lt;/h2&gt;

&lt;p&gt;To abstract is to ignore.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To think is to forget a difference, to generalise, to abstract. In the overly refute world of Funes there were nothing but details, almost contiguous details.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can't take into account all the details of the world in our programs, we have to make assumptions to reason about things efficiently.&lt;/p&gt;

&lt;p&gt;An abstraction is useful only if the assumptions are sound given the context it's being used in.&lt;/p&gt;

&lt;p&gt;That means the usefulness of the software is a function of the context it's being used in.&lt;/p&gt;

&lt;p&gt;To know an abstraction's assumptions, we must know its model. Possession does not imply understanding.&lt;/p&gt;

&lt;p&gt;If the model assumes too much, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make the model larger&lt;/li&gt;
&lt;li&gt;Replace our model&lt;/li&gt;
&lt;li&gt;Narrow our intended usecase&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The following generations, who were not so fond of the study of cartography as their forebears had been, saw that the vast map was useless.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If an abstraction doesn't solve the user's problem, they can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discard the abstraction&lt;/li&gt;
&lt;li&gt;Wrap the abstraction&lt;/li&gt;
&lt;li&gt;Create Conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an abstraction can't be discarded it becomes coercive. What it doesn't see might disappear.&lt;/p&gt;

&lt;p&gt;Software would be easy, it it weren't for the changing environments.&lt;/p&gt;

&lt;p&gt;The environment consists of 3 things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The entire world&lt;/li&gt;
&lt;li&gt;Users&lt;/li&gt;
&lt;li&gt;Other software components&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Systems of abstractions
&lt;/h2&gt;

&lt;p&gt;There are 2 approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Principled&lt;/p&gt;

&lt;p&gt;Make everything predictably structured, so that the side-effects of changes can be predicted accurately.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Adaptable&lt;/p&gt;

&lt;p&gt;Make the parts sparsely connected such that when we make a change we only have to reason locally about the system.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are 2 kinds of cultures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Self-conscious&lt;/p&gt;

&lt;p&gt;There's an person called the architect, who is an expert in design and construction of buildings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unself-conscious&lt;/p&gt;

&lt;p&gt;Everyone builds their own home and there not many other structures that they create.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Principled systems have hierarchies. There's a place for everything and everything is in it's place.&lt;/p&gt;

&lt;p&gt;Adaptable systems are graph-like, they don't have a central organizing principle, we are able to make local changes to them.&lt;/p&gt;

&lt;p&gt;If abstraction is an island our code becomes Galapagos. Variation is only useful when it mirrors the problem being solved.&lt;/p&gt;

&lt;p&gt;Principled code is brittle and predictable. Adaptive code is flexible and unpredictable. There's no in between. What we can do is layer them.&lt;/p&gt;

&lt;p&gt;Adaptable components in a principled framework. The degrees of freedom become vestigial and disappear. There's nothing to adapt to if the environment doesn't change.&lt;/p&gt;

&lt;p&gt;Principled components in an adaptive framework are called complex adaptive systems. If the principled system is too small then we have to write a lot of glue code. If it's too large then the replacement cost becomes extremely high.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Assumptions that fail together, belong together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Principled components are smaller faster and can be understood incrementally.&lt;/p&gt;

&lt;p&gt;We tend to put our bias towards principled component too often due to our optimistic assumption about the environment due to lack of complete understanding.&lt;/p&gt;

&lt;p&gt;Balance is the key here things like logging libraries should be principle components, everyone doesn't need to roll their own. While custom requirements should form the adaptive surrounding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=x9pxbnFC4aQ"&gt;Original link to the talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my 4th post in this series do check out the previous ones :)&lt;/p&gt;

</description>
      <category>abstraction</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Get a wiff of this - RailsConf 2016 - Sandi Metz</title>
      <dc:creator>Chirag Jain</dc:creator>
      <pubDate>Sat, 09 Mar 2019 01:19:30 +0000</pubDate>
      <link>https://dev.to/cjthedev/get-a-wiff-of-this---railsconf-2016---sandi-metz-50d9</link>
      <guid>https://dev.to/cjthedev/get-a-wiff-of-this---railsconf-2016---sandi-metz-50d9</guid>
      <description>&lt;p&gt;This is my 3rd post in my talk notes series. &lt;br&gt;
Sandi Metz is a well known name. She has helped many teams refactor their systems from software rot. These are my notes on her RailsConf Talk about Code Smells.&lt;/p&gt;
&lt;h1&gt;
  
  
  Code Smells
&lt;/h1&gt;

&lt;p&gt;"Code smells" is a term coined by Kent Beck for regularly observed patterns in code.&lt;/p&gt;

&lt;p&gt;Martin Fowler wrote the "Refactoring" book on how to avoid duplication by encapsulating these patterns.&lt;/p&gt;

&lt;p&gt;Code smells are grouped based on similar traits as follows:&lt;/p&gt;
&lt;h2&gt;
  
  
  Bloaters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Long methods&lt;/li&gt;
&lt;li&gt;Large classes&lt;/li&gt;
&lt;li&gt;Data clumps&lt;/li&gt;
&lt;li&gt;Long parameter lists&lt;/li&gt;
&lt;li&gt;Primitive obsession&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Tool Abusers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Switch Statements&lt;/li&gt;
&lt;li&gt;Refused Bequest : A sub class overrides a base class method and throws an exception to denote that it doesn't implement that behavior.&lt;/li&gt;
&lt;li&gt;Alternative classes with different interfaces&lt;/li&gt;
&lt;li&gt;Temporary fields: Can be a method instead&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Change Preventers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Divergent Change: A change requires modifications at different branches of the same hierarchy.&lt;/li&gt;
&lt;li&gt;Shotgun Surgery&lt;/li&gt;
&lt;li&gt;Parallel inheritance hierarchies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's fine sometimes that theirs friction to change. It depends on context.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dispensable
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lazy classes: classes that don't do enough&lt;/li&gt;
&lt;li&gt;Speculative Generality: Making abstractions for anticipated future usecases&lt;/li&gt;
&lt;li&gt;Data Class: Classes with coupled data and behavior&lt;/li&gt;
&lt;li&gt;Duplicated Code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Couplers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Feature Envy: Sending more messages to other objects than yourself i.e. coupling&lt;/li&gt;
&lt;li&gt;Inappropriate Intimacy: Reaching into other object's private methods&lt;/li&gt;
&lt;li&gt;Message Chains: Send a message, receive an object, send a message to received object and it goes on. If the type of object changes in between then it's more concerning.&lt;/li&gt;
&lt;li&gt;Middle Man: An object with the sole purpose of routing messages to other objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Refactoring
&lt;/h1&gt;

&lt;p&gt;Refactorings have name and they come with very specific concrete recipes.&lt;/p&gt;

&lt;p&gt;Every code smell wraps to the curated refactoring recipe. This is a solved problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.industriallogic.com/blog/smells-to-refactorings-cheatsheet/"&gt;Smells to Refactorings Cheatsheet - Industrial Logic&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sale&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Expense&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]))).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cost'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;weekly_sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;start_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="n"&gt;end_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;:start_date&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expense_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;start_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;
    &lt;span class="n"&gt;end_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt;
    &lt;span class="no"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;:start_date&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Data Clump
&lt;/h2&gt;

&lt;p&gt;This code has a data clump for date range, after doing the "extract class" refactoring the code looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateRange&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ending&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialiaze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@starting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;
    &lt;span class="vi"&gt;@ending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="vi"&gt;@starting&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sale&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Expense&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;:range&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cost'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;weekly_sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;:range&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cost'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expense_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that the behavior is coalesced inside the class and is isolated in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message Chains
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Foo&lt;/code&gt;, &lt;code&gt;Bar&lt;/code&gt; and &lt;code&gt;Baz&lt;/code&gt; have message chains i.e. they make call to the objects returned by &lt;code&gt;Expense&lt;/code&gt; and &lt;code&gt;Sale&lt;/code&gt;. Now these classes are coupled with the internal working of their dependencies.&lt;/p&gt;

&lt;p&gt;When you are testing you should only need to mock the immediate collaborators of the object but in this case we'll have to mock the returned object. This generally means that we should extract pattern inside a method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateRange&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ending&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialiaze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@starting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;
    &lt;span class="vi"&gt;@ending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="vi"&gt;@starting&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sale&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
   &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Expense&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
   &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;date: &lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;weekly_sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expense_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We have extracted the chain inside the &lt;code&gt;total&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Related: what you want to test is a trade off. You can only emulate / introduce so much reality inside your tests. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=TU3glG08BJI"&gt;Rocky Mountain Ruby 2012 - To Mock or Not to Mock by Justin Searls&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coupling your tests to objects that are really far away then the test suite is going to get slow. If you couple your objects with slow things then your tests will get slower.&lt;/p&gt;

&lt;p&gt;Using "Dependency Injection" we can mock the "roles" that the objects play rather than the class they are. which is how we should think when doing Object Oriented Programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Duplicate Code
&lt;/h2&gt;

&lt;p&gt;Both &lt;code&gt;Expense&lt;/code&gt; and &lt;code&gt;Sale&lt;/code&gt; implement the same &lt;code&gt;total&lt;/code&gt; method. This duplication can be eliminated by the "pull up method" refactoring. Monkey patching the &lt;code&gt;Persistence&lt;/code&gt; class seems like a bad idea. So instead we pull out the logic inside a module and extend it from both the classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateRange&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ending&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialiaze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@starting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;
    &lt;span class="vi"&gt;@ending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="vi"&gt;@starting&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;ending&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="n"&gt;starting&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;starting&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Totalable&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;date_field: :date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;on: &lt;/span&gt;&lt;span class="s2"&gt;"cost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;date_field&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;within&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sale&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
 &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Totalable&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Expense&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Persistence&lt;/span&gt;
 &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Totalable&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;weekly_sales_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;week_range&lt;/span&gt;
    &lt;span class="no"&gt;Sale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expense_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;starting: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:starting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;ending: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ending&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;
    &lt;span class="no"&gt;Expense&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;within: &lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We have converted &lt;code&gt;total&lt;/code&gt; to have a more generalized API. This can be seen as "Speculative Generality" but until the methods are small this is a good trade off as the flexibility is much more than the added complexity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=PJjHfa5yxlU"&gt;Link to the original talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do check out my other posts in the series :)&lt;/p&gt;

</description>
      <category>oops</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>React Day Berlin 2018 - The Lonely and Dark Road to Styling in React -- Sara Vieira</title>
      <dc:creator>Chirag Jain</dc:creator>
      <pubDate>Thu, 20 Dec 2018 18:42:23 +0000</pubDate>
      <link>https://dev.to/cjthedev/react-day-berlin-2018---the-lonely-and-dark-road-to-styling-in-react----sara-vieira-dhk</link>
      <guid>https://dev.to/cjthedev/react-day-berlin-2018---the-lonely-and-dark-road-to-styling-in-react----sara-vieira-dhk</guid>
      <description>&lt;p&gt;This is my second post in the talk notes series. You can check out the first one &lt;a href="https://dev.to/cjthedev/clojure-conj-2018---maybe-not----rich-hickey-1196"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS is hard
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Link tags
&lt;/h2&gt;

&lt;p&gt;Blocks rendering, only ship the CSS you need i.e. critical CSS&lt;/p&gt;

&lt;h2&gt;
  
  
  BEM (&lt;a href="http://getbem.com/"&gt;Block Element Modifier&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;.block__element—modifier&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to setup&lt;/li&gt;
&lt;li&gt;Framework/Library agnostic&lt;/li&gt;
&lt;li&gt;Fixes some specificity issue&lt;/li&gt;
&lt;li&gt;Rigid Structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming is hard&lt;/li&gt;
&lt;li&gt;Need to memorise the rules and strictly follow them&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preprocessors
&lt;/h2&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nesting&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;SSR just works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Over Nesting&lt;/li&gt;
&lt;li&gt;More dependencies&lt;/li&gt;
&lt;li&gt;Makes it hard to author library → to modify, you need to run the preprocessor&lt;/li&gt;
&lt;li&gt;Not optimised for a component based workflow&lt;/li&gt;
&lt;li&gt;No dynamic styles based on runtime values&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CSS Modules
&lt;/h2&gt;

&lt;p&gt;Write normal CSS with classes and use them inside your components. In the end these will be replaced by random class names.&lt;/p&gt;

&lt;p&gt;Use it via &lt;a href="https://postcss.org/"&gt;PostCss&lt;/a&gt; (Babel for CSS)&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can use all new CSS features&lt;/li&gt;
&lt;li&gt;Autoprefixes CSS&lt;/li&gt;
&lt;li&gt;SSR just works&lt;/li&gt;
&lt;li&gt;More component based and maintainable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unreadable class names&lt;/li&gt;
&lt;li&gt;More dependencies&lt;/li&gt;
&lt;li&gt;Needs to be paired with a pre-processor for variable support&lt;/li&gt;
&lt;li&gt;Global class names can be abused&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CSS-in-JS (&lt;a href="https://www.styled-components.com/"&gt;Styled Components&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Just react components. No SSR support out of the box which can be mitigated by using Razzle (It will extract all the styles and give you style tags to insert into the HTML)&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic styles (based on state and prop of the component)&lt;/li&gt;
&lt;li&gt;Theming is super easy using the &lt;code&gt;ThemeProvider&lt;/code&gt; component, It will pass the theme as a &lt;code&gt;prop&lt;/code&gt; to the child component.&lt;/li&gt;
&lt;li&gt;Can still use the cascade but the whole point is that the styles for your component are only for that component.&lt;/li&gt;
&lt;li&gt;No more specificity problems.&lt;/li&gt;
&lt;li&gt;Autoprefixes everything&lt;/li&gt;
&lt;li&gt;No need to worry about naming things&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Needs to change the way you think about CSS&lt;/li&gt;
&lt;li&gt;Another thing to learn across the team&lt;/li&gt;
&lt;li&gt;The library you are using might only support object based CSS&lt;/li&gt;
&lt;li&gt;SSR is hard to implement yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is nor Right / Wrong answer. Context / use-case matters when choosing a solution. For example: For prototyping you might want to use &lt;a href="https://tachyons.io/"&gt;tachyons&lt;/a&gt; while if you need scalability you would probably go for something different or make something over it to avoid repeating classnames.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=M3AceCsW0oM"&gt;Link to the original Talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you liked this do check out other posts in the series :)&lt;/p&gt;

</description>
      <category>react</category>
      <category>cssinjs</category>
    </item>
    <item>
      <title>Clojure Conj 2018 - Maybe Not -- Rich Hickey</title>
      <dc:creator>Chirag Jain</dc:creator>
      <pubDate>Wed, 19 Dec 2018 18:07:33 +0000</pubDate>
      <link>https://dev.to/cjthedev/clojure-conj-2018---maybe-not----rich-hickey-1196</link>
      <guid>https://dev.to/cjthedev/clojure-conj-2018---maybe-not----rich-hickey-1196</guid>
      <description>&lt;p&gt;This is my first post in the series. Rich Hickey is the creator of the Clojure Language. He is widely known for his clear thinking and unique approach towards software. These are my notes for his talk titled "Maybe Not", which he gave at at Clojure Conj 2018.&lt;/p&gt;

&lt;h2&gt;
  
  
  NULL
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I call it my billion-dollar mistake. It was the invention of the null reference in 1965. — Tony Hoare&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why are nulls / options used?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Optional requirements

&lt;ul&gt;
&lt;li&gt;Clojure mitigates this by providing varaidics and kw-args (keyword args)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Conditional provision (returns)&lt;/li&gt;
&lt;li&gt;Managing partial information (aggregates)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Maybe ?
&lt;/h2&gt;

&lt;p&gt;If we make an arguments optional or make the return value optional by wrapping them in a &lt;code&gt;maybe&lt;/code&gt;, both break all the API whereas It should be compatible change as we are making things optional.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt;/&lt;code&gt;Either&lt;/code&gt; are not type system's &lt;code&gt;or&lt;/code&gt;/&lt;code&gt;union&lt;/code&gt; type, rather evidence of lack of first-class union types&lt;/p&gt;

&lt;p&gt;Kotlin solves this by providing Nullable and Non-nullable types&lt;/p&gt;

&lt;p&gt;Dotty (Successor to Scala): Union types are dual of intersection types. Values of type &lt;code&gt;A | B&lt;/code&gt; are all values of type &lt;code&gt;A&lt;/code&gt; and all values of type &lt;code&gt;B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;|&lt;/code&gt; is commutative i.e. &lt;code&gt;A | B&lt;/code&gt; is the same type as &lt;code&gt;B | A&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aggregate → Flock/Herd that moves together&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Maps vs Records/Fields/Product Types
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Maps

&lt;ul&gt;
&lt;li&gt;maps are mathematical functions&lt;/li&gt;
&lt;li&gt;Simplest functions in programming

&lt;ul&gt;
&lt;li&gt;Key → value&lt;/li&gt;
&lt;li&gt;No code, No categories&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Records

&lt;ul&gt;
&lt;li&gt;Place-oriented programming&lt;/li&gt;
&lt;li&gt;Even with named fields

&lt;ul&gt;
&lt;li&gt;Names are not first class indices&lt;/li&gt;
&lt;li&gt;thus are not functions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Product types complect meaning and place

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;data Person =  Person String String&lt;/code&gt; there's no way to tell what the first string stores and what does the second&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;But records are more restrictive (which is good)&lt;/li&gt;
&lt;li&gt;spec/keys

&lt;ul&gt;
&lt;li&gt;Independent, reusable attributes, RDF-style&lt;/li&gt;
&lt;li&gt;aggregate attributes to form a schema&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Optionality and aggregates
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When something is missing from a set → leave it out&lt;/li&gt;
&lt;li&gt;Maps are enumerable, so if we leave out what we don't know, then their are no empty slots&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;RDF style attributes are context free&lt;/p&gt;

&lt;p&gt;No maybes → Either you know a model or you don't.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A name is always a string, the fact that you know it or not is an orthogonal idea and binding them together using a type is wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a mistake to put optionality in aggregate definitions because unlike args and returns there is no usage context.&lt;/p&gt;

&lt;h2&gt;
  
  
  We want
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Maximum schema re-use, as defining multiple context specific schemas for the same idea leads to disconnect between the various schema definitions.&lt;/li&gt;
&lt;li&gt;Support symmetric request/response&lt;/li&gt;
&lt;li&gt;Information building pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Schemas are deep
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;schemas can nest&lt;/li&gt;
&lt;li&gt;attribute values can be collections&lt;/li&gt;
&lt;li&gt;optionality specs should be deep&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fix
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Split apart the schema(shape) and the selection(optionality for current context)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The schema will only mentions the structure not optionality&lt;/p&gt;

&lt;p&gt;The selection will described in the method signature, so that the it can be clearly specified what parts of the schema are required.&lt;/p&gt;

&lt;p&gt;Separate requiring attribute from requirements of the attribute, example: address is optional but if address is provided then the zip-code is required&lt;/p&gt;

&lt;p&gt;This system is flexible to allow you to specify your assumptions of the incoming data while making the default to allow everything.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make systems that are extensible, that you can change and enhance over time&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=YR5WdGrpoug"&gt;Link to the original talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like this do check out the other posts in the series :)&lt;/p&gt;

</description>
      <category>typesystems</category>
    </item>
  </channel>
</rss>
