Presentation is loading. Please wait.

Presentation is loading. Please wait.

Refactoring Legacy AngularJS

Similar presentations


Presentation on theme: "Refactoring Legacy AngularJS"— Presentation transcript:

1 Refactoring Legacy AngularJS
I’m Corinna Cohn I’ve been writing web applications since 2000 and single page applications since 2012. I work for Fusion Alliance, a consulting company in Indianapolis, Indiana I am an application architect at an insurance company helping multiple teams design and maintain enterprise AngularJS applications Corinna Fusion Alliance March 8, 2016

2 “Ability to write complex code.”
From recruiting I don’t want to write complex code. Complex code is what you get when you solve a problem without elegance. Complex code is hard to understand. Complex code is hard to debug. Our goal in refactoring is avoiding complexity and seeking simplicity. “Ability to write complex code.”

3 Reduce reliance on Controllers
Complex Simple Our Goal Our goal today is to talk about moving your code from being more complex to more simple. Angular 2 is getting rid of controllers. Reduce reliance on Controllers

4 Principles of refactoring AngularJS Analyzing the SlamOff application
Overview What is “refactoring” Principles of refactoring AngularJS Analyzing the SlamOff application Live refactoring of SlamOff Review the refactoring Further reading I’ll define “refactoring” “legacy code” and other terms discussed We’ll cover some of the principles of refactoring AngularJS applications We’ll look at an application prior to any refactoring We’ll start to refactoring our application to demonstrate some of the principles We’ll review the changes after our refactoring Finally I’ll point you to some other resources to learn more about refactoring

5 Refactoring Martin Fowler is the author of “Refactoring” and has these definitions of refactoring. “Without changing its observable behavior” Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

6 Refactoring is not bug fixes. Refactoring is not adding new features.
Refactoring makes code easier to understand and support. Refactoring is not a separate task (technical debt). “Beat the clock” pressure to deliver results in technical debt and extra code complexity. At the end of a delivery I’ve seen refactoring tasks added to help clear technical debt. I don’t think this is the best approach to refactoring.

7 The Role of Unit Testing in Refactoring
Clearly document the expected usage of code. Allows code to be written and considered in isolation. Encourage good separation of concerns. Establish a measure of stability in the code base. Adding features into a system directly can be confusing. It’s not always clear when or if you’ve broken some other feature as you’re modifying code. Unit tests allow code to be written without worrying about side effects from other application code. Unit tests should be small and limited in scope. Accordingly, the code being tested should also be small, limited, and simple. Complex code is hard to test; unit testing encourages simpler code. Unit tests document how the developer intends the code to be used. Good unit tests are the most trust worthy pieces of documentation. Unit tests establish some stability in the code base. Unit tests should be able be run quickly, and you should be able to run them after every change so you can see if you’ve accidentally broken some other part of the system.

8 Source code that is not covered with unit tests.
Legacy Code Michael Feathers defines legacy code as code that is not covered with unit tests. Without unit tests it’s hard to know whether the changes we’re making are affecting the functionality of the system. Michael Feathers recommends putting tests in place *before* making any changes. In my experience this is tough to do with web applications because we usually need to use Selenium-based integration tests, which in web applications are notoriously fragile. Source code that is not covered with unit tests.

9 Refactoring AngularJS
These are not the only techniques, but these are techniques I use as part of my typical work in analyzing and refactoring production Angular applications. Refactoring AngularJS

10 Avoid Better Project Organization
Organize by feature, not functionality. Organize by feature, not functionality. Don’t put create a folder for views, for controllers, for services, etc. Instead, organize by the feature in your application. You want to be able to locate your code quickly and easily. If you have your code separated by functionality it will be harder to find, especially as the number of views, controllers, services, etc increases. Avoid Better

11 Services and Specialized Objects
One feature per file, one file per feature. File names should reflect the name and type of the feature. Specialized objects are controllers, directives, components, filters, etc. search.component.js

12 angular.module('myApp', [ // first-party
modules angular.module('myApp', [ // first-party 'myTrackPlayer', 'myTournamentManager', // third-party 'ui-router', 'ui-bootstrap', 'moment' ]); The angular.module is a global place for creating, registering and retrieving Angular modules One of the easiest ways of controlling app sprawl is to divide your application into multiple modules. When you load an angular module, the .config and .run blocks will execute. This often produces unwelcome side effects during unit testing. You can sometimes move initialization and setup code into a separate angular module so that you can more easily test your code.

13 Wrap third-party globals in modules
Third-party modules Wrap third-party globals in modules Promotes re-use Makes it easier to unit test Opportunity to add proxies to make libraries easier to use Many third-party modules already have public modules that wrap the library as Angular modules. When you use a third-party library, create an Angular wrapper for that library and manage it as a separate module. angular.module('soundcloud', []); angular.constant('soundcloud', window.SC);

14 Avoid the tendency to put all the HTML into one file.
Maintainable Views Avoid the tendency to put all the HTML into one file. Use directives/components to create reusable components. Use <ng-include> to break large HTML files into smaller templates. Use an “Application Shell”, avoid monolithic, one-view applications.

15 Keep business logic in components
Business logic can’t be reused from within a controller. Complicated display logic is not easily written or reasoned about in the DOM (ngIf, ngShow, ngHide). Prefer logic in directives or components over services. By “business logic” I’m talking about code that interacts with the server, localStorage, cookies, creates objects, game logic, or complex display rules. “The controller is where reusable code goes to die.” Complicated display logic is hard to organize with ngIf, ngShow, ngSwitch. If you are having a hard time writing the display logic in HTML it’s also going to be hard to maintain. Use a service to write the rules and expose the service to your view via a controller.

16 Plain JSON has no behavior, so how can we do work with JSON objects?
Let models do some work Plain JSON has no behavior, so how can we do work with JSON objects? Use the factory pattern to add behavior or computed properties to plain objects. Sometimes working with plain JSON works out fine, but other times we want our objects to have behaviors or competed properties. The

17 Factory pattern $http.get(‘/my/track/123') .then(function (item) { return TrackFactory.create(item); });

18 Call behaviors directly on objects
<button ng-click=“track.play()"> Play </button>

19 SlamOff

20 Analysis of SlamOff All of the logic for the application is in just one controller. The view is doing a lot of work. It’s hard to read. The controller uses global libraries. There is no reusability.

21 Changes to SlamOff Divided the giant single template into smaller templates. Created a feature-based folder structure. Wrapped SoundCloud in its own module. Created a facade with SoundCloud functions. Moved logic from Controller into Components.

22 Changes to SlamOff ctd. Used a Factory to create our track objects. Moved complicated display logic into testable service. Created unit tests (documentation!) for our new work.

23 Resources AngularJS Style Guide by John Papa AngularJS Patterns: Clean Code by John Papa Clean Code by Robert Martin Refactoring by Martin Fowler Refactoring to Patterns by Joshua Kerievsky Working with Legacy Code by Michael Feathers


Download ppt "Refactoring Legacy AngularJS"

Similar presentations


Ads by Google