Thick Bread Smell

Where nesting spreads apart the beginning and ending of the "bread" in a proverbial sandwich. This can harm readability and reuse. The solution is to reference the innards by name or variable instead of physically nest them.

Example:

Before fix:

  foo(a b c d (sdfasdf asdf as df asdf asdf as df asdf) e f g h)

After fix:

  x = (sdfasdf asdf as df asdf asdf as df asdf)
  foo(a b c d (x) e f g h)

Here, related items (a through h) are pushed apart in the first variation, making their relationship harder to see. SQL is the most common perpetrator of this sin in my opinion (See SqlFlaws). However, I see it a lot in what I consider bad programming.

- top


Would ThickNestedBreadSmell? be a better name? Perhaps OverlyNestedSandwich?? SplitSandwichSmell??

ThickSandwichFillingSmell?, I would say. It's not the "bread" which is "thick" here.

Although I'm not sold on the suggestions given so far, I agree the topic name could use a deeper rethink to better tune the analogy. "Thick Sandwich Smell" is currently my top vote-getter.

Dagwooding?


TheEnd has some examples of this smell.

One solution is to use IntermediateValues. However, they may not necessarily be values, but could be statements that use some kind of code or macro expansion or substitution before actual execution.

Another solution doesn't introduce any intermediate values, but rewrites a deeply nested expression as a composition of functions. For example ClojureLanguage has the -> macro, which you use to rearrange things to put the filling before the bread, as it were:

	(g (f (h (j arg-to-j) arg-to-h) arg-to-f) arg-to-g)
becomes
	(-> arg-to-j j (h arg-to-h) (f arg-to-f) (g arg-to-g))


TutorialDee provides a WITH clause to introduce syntactic IntermediateValues into queries to enhance human readability.

E.g.:

 WITH s {a, b, c} AS t1,
	p {a, b, c} AS t2,
	q {a, b, c} AS t3:
	  t1 UNION t2 UNION t3

SmeQl also has named reference. I've read that PostgreSql has a way to do it also in it's SQL dialect, although it was a bit wordy as I remember it.

SQL itself has a WITH construct in query expressions (requirements T121 and T122 in the nomenclature of SQL2011).

  WITH regional_sales AS (
         SELECT region, SUM(amount) AS total_sales
         FROM orders
         GROUP BY region
      ), top_regions AS (
         SELECT region
         FROM regional_sales
         WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
      )
 SELECT region,
        product,
        SUM(quantity) AS product_units,
        SUM(amount) AS product_sales
 FROM orders
 WHERE region IN (SELECT region FROM top_regions)
 GROUP BY region, product;


CategoryCodeSmell

EditText of this page (last edited August 29, 2013) or FindPage with title or text search