Legacy codesmalltalk
-
Upload
eric-smith -
Category
Documents
-
view
81 -
download
1
Transcript of Legacy codesmalltalk
![Page 1: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/1.jpg)
Legacy CodeQuit Complaining, Start Fixing
Saturday, February 15, 14
![Page 2: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/2.jpg)
What Is Legacy Code?
Saturday, February 15, 14
![Page 3: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/3.jpg)
What Is Legacy Code?
1. /**2. *3. * @param balanceData4. */5. public void populateCashAndInvestmentsForCurrency(List<BalanceData> balanceData, String currency) {6. 7. PieChartItem item = new PieChartItem();8. Resources res = getResources();9. 10. for (BalanceData data : balanceData) {11. 12. // if associated currency then do13. if (data.getCashBalanceCurrency().equals(currency)) {14. BigDecimal cash = BigDecimal.ZERO;15. BigDecimal investment = BigDecimal.ZERO;16. List<PieChartItem> slices = new ArrayList<PieChartItem>();17. 18. if (data.getIsOffshore()) { // offshore19. 20. cash = data.getCashBalance();21. 22. investment = data.getInvestmentBalance();23. 24. for (ExchangeRate rate : <hidden>.getExchangeRates()) {25. 26. if (rate.getCurrency().equals(data.getCashBalanceCurrency())) {27. 28. cash = cash.multiply(rate.getRate());29. 30. investment = investment.multiply(rate.getRate());31. 32. }33. 34. }35. 36. } else if (!data.getIsOffshore()) { // local37. 38. cash = data.getCashBalance();39. 40. investment = data.getInvestmentBalance();41. 42. }43. 44. if (<hidden>.getmCurrentExchangeRate().getRate().compareTo(newBigDecimal("0.0000")) == 1) {45. // convert to current rate46. cash = cash.divide(<hidden>.getmCurrentExchangeRate().getRate(),BigDecimal.ROUND_UP);47. investment =investment.divide(<hidden>.getmCurrentExchangeRate().getRate(),
BigDecimal.ROUND_UP);48. }49. 50. // investment slice51. 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 slice59. 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. 71. }
Saturday, February 15, 14
![Page 4: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/4.jpg)
What Is Legacy Code?
Code where the tests are an impediment, not a benefit
Saturday, February 15, 14
![Page 5: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/5.jpg)
Vent
But get it out of your system
Get it in a Harness
Verify the code around your new code
Add your Code
Steps
Saturday, February 15, 14
![Page 6: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/6.jpg)
Seams
A place where you can change existing behavior without editing code
Objects, Linker, Preprocessor
Enabling Point
Saturday, February 15, 14
![Page 7: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/7.jpg)
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
![Page 8: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/8.jpg)
(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
![Page 9: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/9.jpg)
private void paintBackgroundDisabledAndWindowMaximized(Graphics2D g) {166 roundRect = decodeRoundRect1();167 g.setPaint(decodeGradient1(roundRect));168 g.fill(roundRect);169 roundRect = decodeRoundRect2();170 g.setPaint(decodeGradient2(roundRect));171 g.fill(roundRect);172 rect = decodeRect1();173 g.setPaint(color4);174 g.fill(rect);175 rect = decodeRect2();176 g.setPaint(color5);177 g.fill(rect);178 rect = decodeRect3();
Saturday, February 15, 14
![Page 10: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/10.jpg)
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
![Page 11: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/11.jpg)
private void paintBackgroundDisabledAndWindowMaximized(GraphicsAdapter g) {166 roundRect = decodeRoundRect1();167 g.setPaint(decodeGradient1(roundRect));168 g.fill(roundRect);169 roundRect = decodeRoundRect2();170 g.setPaint(decodeGradient2(roundRect));171 g.fill(roundRect);172 rect = decodeRect1();173 g.setPaint(color4);174 g.fill(rect);175 rect = decodeRect2();176 g.setPaint(color5);177 g.fill(rect);178 rect = decodeRect3();
Saturday, February 15, 14
![Page 12: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/12.jpg)
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
![Page 13: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/13.jpg)
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Signup Unsuccessful" message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL];
Saturday, February 15, 14
![Page 14: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/14.jpg)
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
![Page 15: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/15.jpg)
UIAlertView *alert =[[[[self class] alertViewClass] alloc] initWithTitle:@"Signup message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL];
Saturday, February 15, 14
![Page 16: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/16.jpg)
+(Class) alertViewClass{ return [UIAlertView class];} // In test file@interface LoginViewControllerWithTestAlert : LoginViewController@end @implementation LoginViewControllerWithTestAlert +(Class) alertViewClass{ return [TestAlert class];} @end
Saturday, February 15, 14
![Page 17: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/17.jpg)
Static Setter
Allow Subclassing a Singleton
Add a Static Setter
Add a Clear or Reset to avoid Test Pollution
Saturday, February 15, 14
![Page 18: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/18.jpg)
void MessageRouter::route(Message *message) { Dispatcher *dispatcher = ExternalRouter::instance()->getDispatcher(); if (dispatcher != NULL) dispatcher->sendMessage(message;}
Saturday, February 15, 14
![Page 19: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/19.jpg)
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
![Page 20: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/20.jpg)
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
![Page 21: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/21.jpg)
Higher Level Tests
Characterization Tests
In case of emergency break glass.
Saturday, February 15, 14
![Page 22: Legacy codesmalltalk](https://reader030.fdocuments.us/reader030/viewer/2022032616/55a48b341a28ab8d6b8b46f3/html5/thumbnails/22.jpg)
Resources
Working Effectively With Legacy Code - Michael Feathers
http://www.reddit.com/r/badcode
@paytonrules (that’s me)
Bullets suck
Saturday, February 15, 14