Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eafeaab

Browse files
author
Matt Swanson
committed
adding changing plans, closes swanson#52
1 parent 7175340 commit eafeaab

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
layout: post
3+
title: "Changing Plans"
4+
categories:
5+
- blog
6+
---
7+
8+
There is some friction between agile methodologies and the desire for
9+
upfront formal requirements that has really been bugging me lately.
10+
11+
I often find myself wanting to have my cake and eat it too: I want clear and
12+
final requirements, but I don't want to be forced to design an entire system
13+
upfront and drown in UML diagrams.
14+
15+
Part of this stance is due to the fear of change; the desire to not code
16+
yourself into a corner later on in the project. No one wants to tell
17+
their boss (or worse, their client) that they've picked a design that doesn't
18+
accommodate the new changes that need to be made.
19+
20+
> You will never know less \[about your software\] than you do now. <cite style="float: right; display: block;"><a href="http://sandimetz.com/">Sandi Metz</a></cite>
21+
22+
This is a scary thought!
23+
24+
There will never be a time on this project when you will know less about how
25+
changes will impact the rest of the system then **right now**. Only with time
26+
and experience with the project will you begin to fully understand the
27+
consequences of your earlier design choices.
28+
29+
So should we just never code anything and twiddle our thumbs? Of course not.
30+
31+
But what can we do? What are some reasonable steps we can take to build a
32+
flexible system (but not end up with a pile of XML configuration files)?
33+
34+
### Recognize and manage dependencies
35+
36+
Dependency Injection (DI) gets a bad wrap and that is mainly because of some
37+
hairy DI *frameworks* that do a bunch of auto-wiring and other black magic. The
38+
principle of Dependency Injection is actually pretty simple: pass in objects
39+
you depend on as arguments.
40+
41+
Change from this:
42+
43+
{% highlight csharp %}
44+
public class Appraisal {
45+
private ComicBook comicBook { get; set; }
46+
47+
public Appraisal(long comicBookId) {
48+
comicBook = new ComicBookFinder.FindById(comicBookId);
49+
}
50+
51+
public Money ComputePrice() {
52+
var percentageModifier = new ComicBookGrader.Grade(comicBook.condition);
53+
return comicBook.ListPrice * percentageModifier;
54+
}
55+
}
56+
{% endhighlight %}
57+
58+
to this:
59+
60+
{% highlight csharp %}
61+
public class Appraisal {
62+
private ICollectible collectible { get; set; }
63+
private IGrader collectableGrader { get; set; }
64+
65+
public Appraisal(ICollectable collectible, IGrader collectableGrader) {
66+
this.collectible = collectible;
67+
this.collectableGrader = collectableGrader;
68+
}
69+
70+
public Money ComputePrice() {
71+
var percentageModifier = collectableGrader.Grade(collectible.condition);
72+
return collectible.ListPrice * percentageModifier;
73+
}
74+
}
75+
{% endhighlight %}
76+
77+
Did I have to define a Registry in an XML file? Is there some DI Container
78+
framework I have to setup? Nope, just a constructor argument.
79+
80+
Maybe we never need to appraise other types of collectibles with this app. But
81+
it was a trivial change and it will save us later down the road when the client
82+
now wants to expand to include Action Figures.
83+
84+
And as a nice little bonus, the second version is way easier to test.
85+
86+
### Build re-usable modules
87+
88+
Single Responsibility Principle (SRP) is another hotly-debated pattern in
89+
software design. I think this is because it is really damn confusing.
90+
91+
If you are asked, "What is the Single Responsibility of this class?" and you
92+
respond with "Well, it manages all of the business logic. That is the one thing
93+
it does!", you will probably get yelled at.
94+
95+
If you trace the [origin story of SRP][rdd], however, you will find the intention
96+
is a class that "has responsibilities that fulfill its purpose". Nothing about one
97+
discrete job, but rather that the class as a whole is cohesive.
98+
99+
[rdd]: http://en.wikipedia.org/wiki/Responsibility-driven_design
100+
101+
Well great! Except what the heck is a "cohesive class"?
102+
103+
[Sandi Metz][poodr] has an interesting technique that has been helpful to me:
104+
to help identify if a class is cohesive or not, imagine it as someone you are
105+
interrogating. For each public method, ask the object in the form of a question:
106+
107+
[poodr]: http://www.poodr.info/
108+
109+
{% highlight csharp %}
110+
public class QuarterlySalesReport {
111+
public FiscalQuarter SalesQuarter() { ... }
112+
public IEnumerable<Sales> AllSales() { ... }
113+
public Product MostProfitableProduct() { ... }
114+
}
115+
{% endhighlight %}
116+
117+
"Mr. `QuarterlySalesReport`, what sale quarter are you for?"
118+
119+
"Mr. `QuarterlySalesReport`, what are all of your sales?"
120+
121+
"Mr. `QuarterlySalesReport`, what was the most profitable product?"
122+
123+
The first two questions seem reasonable.
124+
125+
The third seems a bit out of place. There are many other objects that you might
126+
want to ask this same question to &mdash; a `YearlySalesReport`, a
127+
`StoreSalesReport`, a `ProductCatalogue`, etc.
128+
129+
Instead, we could ask the `QuarterlySalesReport` for the list of sales and pass
130+
that to a `ProfitCalculator`. When the company expands over-seas and we have
131+
to consider international tariffs and customs fees when calculation our profit,
132+
we will be thankful we only need to make changes in one place.
133+
134+
If you find that your class has questions that don't seem reasonable, this is a
135+
sign that your class is not cohesive and is holding on to too much behavior. Try
136+
extracting that logic in a smaller, re-usable piece.
137+
138+
---
139+
140+
Changing requirements will happen. We cannot anticipate how a project's plan may
141+
change, but we can take modest steps to make our systems more flexible and
142+
better equipped to handle it.
143+
144+
Do not fear change, but rather embrace it and accept that it is a part of the
145+
process.
146+
147+
Software that doesn't change is software that isn't used. And I, for one, would
148+
much rather work on projects that are actually used than a perfectly specified
149+
piece of adandonware.

0 commit comments

Comments
 (0)