Last active
June 3, 2016 07:43
-
-
Save luque/3bdc2af04a55a5cfa9437a363969d0dd to your computer and use it in GitHub Desktop.
Notes on Understanding 4 Rules of Simple Design
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Understanding the 4 Rules of Simple Design | |
========================================== | |
by Corey Haines. | |
# Highlighted Quotes | |
- If you simply follow Kent Beck's rules of simple design, then you'll see how every good design principle you've ever heard of reduces to some cobinations of "remove duplication" and "improve names". | |
- There are many levels of design decisions, ranging from the large up-front thinking to the almost continuous decisions made around things such as naming variables and extracting methods --> low-level design. | |
- The rules feed into each other iteratively --> More on this idea on Rainsberger's article [3] | |
- It is important to keep in mind that this does not mean you should strive for huge, xml-configuration-based systems, making everything configurable. Quite the opposite. When we plan and build explicit extension and configurability points, we are going against the idea of simple design. There is a second constant that we know to be true in software development: we don't know exactly what is going to need to change. Every configuration and extensibility point you explicitly plan and build is a belief about the evolution of the system... Rather than planning for change points, we build systems, by applying simple design principles, that can change easily at ANY point. | |
| | |
| | |
+-> Sandi Metz's Tweet: | |
"Don't write code that guesses the future, arrange code so you can adapt to the future when it arrives." | |
- Tests Pass --> If you can't verify that your system works, then it doesn't really matter how great your design is. | |
- Express Intent --> One of the most important qualities of a codebase, when it comes time to change, is how quickly you can find the part that should be changed. | |
- As we start to see structures getting large, the difficulty in finding an expressive name is a red flag that it is doing too much and should be refactored. | |
- No Duplication --> We tend to think of duplication at a code level. However, this rule isn't about code duplication; it is about knowledge duplication. | |
# Examples | |
## Test names should influence object's API | |
Focusing on the symmetry between a good test name and the code under tests is a subtle design technique. | |
## Duplication of knowledge about topology | |
A good way to detect knowledge duplication is to ask what happens if we want to change something. | |
Eliminating this duplication relies on a strategy of reification. Thi is the act of taking a concept and making it real by extraction. | |
When encountering poor names, we often can find a missing abstraction by thinking about what the poorly-named variables represent. | |
## Behavior attractors | |
By aggressively eliminating knowledge duplication through reification, we often find that we have built classes that naturally accept new behaviors that arise. They not only accept, but attract them; by the time we are looking to implement a new behavior, there is already a type that is an obvious place to put it. | |
We can use this idea to notice potentially missing abstractions. If we are working on a new behavior, but are not sure where to place it, this might be an indication that we have a concept that isn't expressed well in our syste.m | |
## Testing state vs testing behavior | |
## Don't have tests depend on previous tests | |
External callers can't actually use the base constructor for an object. Put another way: the outside world can't use new to instantiate an object with an expectation of a specific state. Instead, there must be an explicitly named builder method on the class to create an object in a specific, valid state. | |
| | |
| | |
+--> This pattern already appears in Beck's "Smalltalk Best Practice Patterns" | |
## Breaking abstraction level | |
## Naive duplication | |
I consider naive, mechanical elimitation of duplication: a refactoring that stems from a fundamental misunderstanding of the idea of DRY. | |
Just looking at code that appears similar and combining them misses the point of the DRY principle. | |
| | |
| | |
+--> Incidental duplication in [4]. Too much incidental duplication elimitation would cause "Ravioli Code"? | |
One good technique to keep from mistaking similar-looking code as actual knowledge duplication is to explicitly name the concepts before you try to eliminate the duplication. | |
## Procedural polimorphism --> Example of OCP | |
## Making assumptions about usage | |
## Unwrapping an object | |
## Inverted composition as a replacement for inheritance | |
# Further Readings | |
[1] [Beck Design Rules](http://martinfowler.com/bliki/BeckDesignRules.html) by Martin Fowler. | |
[2] [The Four Elements of Simple Design](http://blog.jbrains.ca/permalink/the-four-elements-of-simple-design) by J.B. Rainsberger | |
[3] [Putting an Age-Old Battle To Test](http://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest/) by J.B. Rainsberger | |
| | |
| | |
+--> The Simple Design Dynamo | |
[4] [Duplication in Software](https://www.justsoftwaresolutions.co.uk/design/duplication.html). | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment