Your SlideShare is downloading. ×
Legacy codesmalltalk
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Legacy codesmalltalk

65
views

Published on


0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
65
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Legacy Code Quit Complaining, Start Fixing Saturday, February 15, 14
  • 2. What Is Legacy Code? Saturday, February 15, 14
  • 3. 34.                                         } 35.   36.                                 } else if (!data.getIsOffshore()) { // local 37.   38.                                         cash = data.getCashBalance(); 39.   40.                                         investment = data.getInvestmentBalance(); 41.   What Is Legacy Code? 42.                                 } 43.   44.                                 if (<hidden>.getmCurrentExchangeRate().getRate().compareTo(newBigDecimal("0.0000")) == 1) { 45.                                         // convert to current rate 46.                                         cash = cash.divide(<hidden>.getmCurrentExchangeRate().getRate(),BigDecimal.ROUND_UP); 47.                                         investment =investment.divide(<hidden>.getmCurrentExchangeRate().getRate(), BigDecimal.ROUND_UP); 48.                                 } 49.   50.                                 // investment slice 51.                                 item = new PieChartItem(); 52.                                 item.mLabel = res.getString(R.string.pcs_investment); 53.                                 item.mSliceValue = investment; 54.                                 item.mValue = investment.floatValue(); 55.                                 item.mColor = res.getColor(R.color.pcs_teal); 56.                                 slices.add(item); 57.   58.                                 // cash slice 59.                                 item = new PieChartItem(); 60.                                 item.mLabel = res.getString(R.string.pcs_cash); 61.                                 item.mSliceValue = cash; 62.                                 item.mValue = cash.floatValue(); 63.                                 item.mColor = res.getColor(R.color.pcs_biscuit); 64.                                 slices.add(item); 65.   66.                                 mPieChartList.add(slices); 67.                         } 68.   69.                 } 70.   Saturday, February 15, 14
  • 4. What Is Legacy Code? Code where the tests are an impediment, not a benefit Saturday, February 15, 14
  • 5. Steps Vent But get it out of your system Get it in a Harness Verify the code around your new code Add your Code Saturday, February 15, 14
  • 6. Seams A place where you can change existing behavior without editing code Objects, Linker, Preprocessor Enabling Point Saturday, February 15, 14
  • 7. var ParseRecurrenceDate = function (recurrencedata) { var StartTime = DTSTART.exec(recurrencedata)[1]; var EndTime = DTEND.exec(recurrencedata)[1]; if (StartTime.indexOf("T") > 0) { ... } var EndDate = RRULE.exec(recurrencedata)[1]; EndDate = new Date(parseInt(EndDate.substr(0, 4), 10), parseInt(EndDate.substr(4, 2), 10) - 1, parseInt(EndDate.substr(6, 2 10)); Saturday, February 15, 14
  • 8.      (will-mount [_]         (let [{:keys [id-key filter tag-fn]} opts               kill-chan (om/get-state owner :kill-chan)               tx-chan (om/get-shared owner :tx-chan)               txs (chan)]           (assert (not (nil? tx-chan))             "om-sync requires shared :tx-chan pub channel with :txs topic")           (async/sub tx-chan :txs txs)           (om/set-state! owner :txs txs)           (go (loop []                 (let [dpath (om/path coll)                       [{:keys [path new-value new-state] :as tx-data} _] (<! txs)                       ppath (popn (- (count path) (inc (count dpath))) path)]                   (when (and (subpath? dpath path)                              (or (nil? filter) (filter tx-data)))                     (let [tag (if-not (nil? tag-fn) Saturday, February 15, 14
  • 9. e void paintBackgroundDisabledAndWindowMaximized(Graphics2D g) {     roundRect = decodeRoundRect1();     g.setPaint(decodeGradient1(roundRect));     g.fill(roundRect);     roundRect = decodeRoundRect2();     g.setPaint(decodeGradient2(roundRect));     g.fill(roundRect);     rect = decodeRect1();     g.setPaint(color4);     g.fill(rect);     rect = decodeRect2();     g.setPaint(color5);     g.fill(rect);     rect = decodeRect3(); Saturday, February 15, 14
  • 10. Adapt Parameter Create New Interface That you can fake Wrap Hard to instantiate class Move to interfaces that communicate responsibilities not implementation - to avoid over-mocking Saturday, February 15, 14
  • 11. e void paintBackgroundDisabledAndWindowMaximized(GraphicsAdapter g) {     roundRect = decodeRoundRect1();     g.setPaint(decodeGradient1(roundRect));     g.fill(roundRect);     roundRect = decodeRoundRect2();     g.setPaint(decodeGradient2(roundRect));     g.fill(roundRect);     rect = decodeRect1();     g.setPaint(color4);     g.fill(rect);     rect = decodeRect2();     g.setPaint(color5);     g.fill(rect);     rect = decodeRect3(); Saturday, February 15, 14
  • 12. public class StubGraphicsAdapter implements GraphicsAdapter {   public void setPaint(java.awt.Color color) { } ... }   public class JavaAwtGraphicsAdapter implements GraphicsAdapter { private Graphics2D g; public JavaAwtGraphicsAdapter(Graphics2D g) { this.g = g; } public void setPaint(java.awt.Color color) { this.g.setPaint(color); } Saturday, February 15, 14
  • 13. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Signup Unsuccessful" message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL]; Saturday, February 15, 14
  • 14. Extract and Override Identify the call you want to extract Create a new method on the current class Override in test Saturday, February 15, 14
  • 15. UIAlertView *alert =[[[[self class] alertViewClass] alloc] initWithTitle:@"Signup message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL]; Saturday, February 15, 14
  • 16. +(Class) alertViewClass { return [UIAlertView class]; }   // In test file @interface LoginViewControllerWithTestAlert : LoginViewController @end   @implementation LoginViewControllerWithTestAlert   +(Class) alertViewClass { return [TestAlert class]; }   @end Saturday, February 15, 14
  • 17. Static Setter Allow Subclassing a Singleton Add a Static Setter Add a Clear or Reset to avoid Test Pollution Saturday, February 15, 14
  • 18. void MessageRouter::route(Message *message) { Dispatcher *dispatcher = ExternalRouter::instance()->getDispatcher(); if (dispatcher != NULL) dispatcher->sendMessage(message; } Saturday, February 15, 14
  • 19. class ExternalRouter { private: static ExternalRouter *_instance; ExternalRouter(); public: static ExternalRouter *instance(); }   ExternalRouter *ExternalRouter::_instance = 0;   ExternalRouter *ExternalRouter::instance() { if (_instance == 0) { _instance = new ExternalRouter(); } return _instance; } Saturday, February 15, 14
  • 20. class ExternalRouter { private: static ExternalRouter *_instance; protected: ExternalRouter(); public: static ExternalRouter *instance(); static void setTestingInstance(ExternalRouter *newInstance); }   void ExternalRouter::setTestingInstance(ExternalRouter *newInstance) { delete _instance; _instance = newInstance; }   class TestingExternalRouter : public ExternalRouter { public: virtual void Dispatcher *getDispatcher() const { return new FakeDispatcher(); } } Saturday, February 15, 14
  • 21. Higher Level Tests Characterization Tests In case of emergency break glass. Saturday, February 15, 14
  • 22. Resources Working Effectively With Legacy Code - Michael Feathers http://www.reddit.com/r/badcode @paytonrules (that’s me) Bullets suck Saturday, February 15, 14

×