Evergreen Legacy Applications

F863e9eb811851834773398e72614dc1?s=47 Harry Wolff
September 27, 2019

Evergreen Legacy Applications

Let’s make what’s old, new!

F863e9eb811851834773398e72614dc1?s=128

Harry Wolff

September 27, 2019
Tweet

Transcript

  1. 1.
  2. 2.
  3. 3.

  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 10.
  9. 12.
  10. 13.
  11. 14.
  12. 15.
  13. 16.
  14. 17.

  15. 18.
  16. 19.
  17. 20.
  18. 23.

    Rule 1: Have a good reason to do it •

    Why are you even bothering? What are you trying to solve? • Does the state of your current application make it difficult to add more features? • Is it hard for you to recruit because the job market for the tech you use is shrinking? • Make sure you have a good reason for tackling this large tech debt problem before you begin.
  19. 24.

  20. 26.

    Rule 2: Don't stop and rewrite everything • This is

    a stop the world solution and one that is rarely a good idea. • It takes a lot of time to get to parity with your existing application. • Hard to rediscover all the edge case bugs that were fixed over years. • Stops work on new functionality. Which can be hugely damaging to a young company. • There are times when it's the right call… • …but those are the exceptions, not the rule.
  21. 28.

    Rule 3: Prepare to be in a state of constant

    migration • Having an Evergreen Legacy Application means your old code and new code will exist alongside each. Possibly forever. • You have to be ok with living in this hybrid world. • Prepared to take a small cost when switching context between the old and the new. • It's ok to not have an end path to removing legacy code, but you have to be ok with living in a world of flux
  22. 30.

    Rule 4: What is new today is legacy tomorrow •

    Be careful with how many new things you adopt. • Each new thing increases your overall maintenance burden. • Eventually everything becomes legacy.
  23. 31.

    Harry’s 4 Rules • Rule 1: Have a good reason

    to do it • Rule 2: Don't stop and rewrite everything • Rule 3: Prepare to be in a state of constant migration • Rule 4: What is new today is legacy tomorrow
  24. 32.

    Harry’s 4 Rules • Rule 1: Have a good reason

    to do it • Rule 2: Don't stop and rewrite everything • Rule 3: Prepare to be in a state of constant migration • Rule 4: What is new today is legacy tomorrow
  25. 33.
  26. 34.
  27. 36.
  28. 38.
  29. 40.
  30. 42.
  31. 43.
  32. 46.
  33. 48.
  34. 50.

    const FooterView = mixInto(Marionette.View)( onInitialRenderPromise, removeViewOnDestroyMixin, viewWithReact ).extend({ className: 'app-footer',

    template, initialize() { this.onInitialRender.then(() => this.render()); this.registerReactComponent( <BackboneProvider models={{ settings: this.model }}> <SiteFooterBackbone /> </BackboneProvider>, '.js-react-site-footer' ); },
  35. 51.

    registerReactComponent(reactElement, selector) { this._registeredReactMetadata[selector] = { mounted: false, reactElement, selector,

    }; }, onRender() { Object.keys(this._registeredReactMetadata).forEach(selector => { const reactComponent = this._registeredReactMetadata[selector]; const domElement = this._getElForSelector(reactComponent.selector); ReactDOM.render(reactComponent.reactElement, domElement); }); },
  36. 53.
  37. 54.

    const person = { name: 'harry', location: 'spain', }; const

    model = new Backbone.Model(person); model.get('name'); // 'harry' model.set('name');
  38. 55.
  39. 56.

    class BackboneWrapper extends React.Component { componentDidMount() { this.props.model.on('change', this.handleChange); }

    componentWillUnmount() { this.props.model.off('change', this.handleChange); } render() { return <li>{this.props.model.get('text')}</li>; } } <BackboneWrapper model={model} />
  40. 57.
  41. 59.

    const userBackboneModel = new Backbone.Model({ name: 'harry', location: 'spain', });

    const mapModelsToProps = (models) => { const { user } = models; return { name: user.get('name'), location: user.get('location), }; }; const MyComponentConnected = connectBackboneToReact(mapModelsToProps)(MyComponent); function MyComponent({ name, location }) { // All it has to worry about is plain javascript values. } <MyComponentConnected model={{user: userBackboneModel }} />
  42. 60.
  43. 62.
  44. 63.
  45. 65.
  46. 66.
  47. 67.
  48. 68.
  49. 69.