Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

Code might be unfactored because you weren&#x2019;t good enough to see the refactorings earlier.

No tests - how do you have confidence? You could have well-designed code with no tests... &#x201C;clean room&#x201D;...falcon circling the sky then strikes Bad design Dependencies (Rails makes you not care. Stuff like const_missing is great but hides pain points, association chains)

The more debt you have, the harder it is to adapt to changing requirements. Systems become large, it&#x2019;s important for them to be designed and architected such that you can reason about subsystems. Eventually, programmers want the Big Rewrite. We&#x2019;ve both advocated for the Big Rewrite on a project that hadn&#x2019;t even launched yet.

*** Choosing Rails &#xA0;&#xA0;- Pros: we know them &#xA0;&#xA0;- Cons: Locked into Ruby (issue when you need to have multithreaded code). &#xA0;Opinionated - when your business expands past those opinions, must pay down debt. &#xA0;Example: AR assumes one database. &#xA0;Need to write libraries/rearchitect to support clustering *** Choosing mediawiki &#xA0;&#xA0;- Pros: Easy to get the site up and running &#xA0;&#xA0;- Cons: Difficult to extend, difficult to scale &#xA0;&#xA0;- Result: Spent a year+ replacing it piece-by-piece with Rails *** Using ActiveScaffold &#xA0;&#xA0;- &#xA0;Pros: Get scaffolding quickly and easily &#xA0;&#xA0;- Cons: Internal code is a mess, untested, difficult to extend *** Code you write &#xA0;&#xA0;- Not refactoring / writing tests - Poorly tested code is almost as bad as not testing at all.

has_many => &#xA0;has_many :through &#xA0;(clear migration path)

one database server => multiple database servers (requires community to create new tools. no clear migration path out of the box)

** Could spend six months designing the system so that it supports all the functionality and has extensibility points *** We know that doesn't actually work *** Plus you don't have working software * Agile approach &#xA0;&#xA0;** Do simple things to add value right now &#xA0;&#xA0;** Technical debt is central to Agile development - embrace it

** RATFT &#xA0;&#xA0;- Antipattern: red/green deploy Just because you have tests for your 70 line controller method, doesn't mean it's good or that you're done. &#xA0;&#xA0;- red/green/REFACTOR deploy &#xA0;&#xA0;- Get to green, take the time to make your code nice. &#xA0;You should spend equal or more time refactoring than making your tests green.

AboutUs: 2-3 deployments per day. No staging.

Legacy systems provide existing value. &#xA0;The foremost requirement when making changes to a system is not to lose the existing value. Automated tests provide the safety net.

* You need to write tests, what do you do? Unit Tests or Acceptance Tests? A. Acceptance (originally called functional)

* Con isn&#x2019;t really a con. New Ruby programmers won&#x2019;t stay new for long * If they learn this, they&#x2019;ll start to write code this way

* I didn&#x2019;t realize how easy that was until I did it from scratch * It &#x201C;just worked&#x201D;

*This is considdered by most people as a &#x201C;clean/skinny&#x201D; controller.

Why refactor? So you can do this We realize that legacy controllers aren&#x2019;t even this clean. We never said it would be easy. Refactor your code, then you can make it sex This is the goal

Transactions in the controller are an anti-pattern.

No explicit transactions You can use a framework

Code is tougher to understand due to indirection

Transaction semantics without an explicit transaction Account and project focused on domain responsibilities AccountRegistration provides natural point for stuff like sending a verification email (also helps with testing) AccountRegistration can get sophisticated without muddling model - validates_associated project and video, if you want You could write a script to clean up AccountRegistration records when they&#x2019;re no longer needed, depending on domain

* Can use a mock or a simpler fake object * Every Java programmer asks &#x201C;what library to use for DI&#x201D; * Ruby programmers say &#x201C;don&#x2019;t use it&#x201D; * Misses the point. Don&#x2019;t use a framework. Use Ruby

* Problem: this will break all clients

Learn the hooks (inherit, included, etc) Understand how has_many works - it&#x2019;s not magic! This lets you be very creative and have fun Working Effectively...gives you concrete strategies for getting a code base under test

Working Effectively With Legacy Code

1.
WORKING EFFECTIVELY WITH LEGACY RAILS
Pat Maddox & BJ Clark

2.
Why Care About Legacy Code?
Rails is almost 5 years old
Lots of $$ to be made
Everyone writes legacy code

3.
What is Legacy Code?
Code written >3 months ago
Code written by someone else

4.
What is Legacy Code?
Michael Feathers - “Code Without Tests”
Ward Cunningham - “Accumulated technical debt”
DHH - “Code you wrote when weren’t as good as you are now”

7.
What is Technical Debt?
“During the planning or execution of a software project, decisions are
made to defer necessary work, this is creating technical debt”
http://c2.com/cgi/wiki?TechnicalDebt
Why is it bad?
Not necessarily bad (good vs bad debt)

43.
A little more
describe AccountsController, quot;POST createquot; do
def do_post
post :create, :account => {:name => quot;Nikequot;}
end
it quot;should create a project for the accountquot; do
do_post
Account.first.should have(1).project
end
it quot;should create a video for the projectquot; do
do_post
Account.first.projects.first.should have(1).video
end
end