2016-06-10 aftership - how to code better and faster

43
How to code better and faster By Vimukthi

Upload: aftership

Post on 20-Feb-2017

150 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: 2016-06-10 AfterShip - How to code better and faster

How to code better and fasterBy Vimukthi

Page 2: 2016-06-10 AfterShip - How to code better and faster

Overview

● Lets define ‘better’● Key principles in software architecture

Foreach (principle in key_principles) { ❏ The principle❏ How to follow the principle.❏ Code demonstration/workshop

}● Design patterns summary● References● Q&A

Page 3: 2016-06-10 AfterShip - How to code better and faster

Question :What is better

?

Page 4: 2016-06-10 AfterShip - How to code better and faster

● Quality● Fast time to market● Readability● Easy to Change/Adapt● Etc.

Page 5: 2016-06-10 AfterShip - How to code better and faster

Key principles in software architecture

● Separation of concerns● Single responsibility Principle● Principle of least knowledge● Don’t repeat yourself(DRY)● Minimize up front design(YAGNI)

Maintainability=Better

Time to market=Faster

How to Balance Maintainability vs Time to market?

Page 6: 2016-06-10 AfterShip - How to code better and faster

Answer:

Follow this Presentation without falling asleep :D

Page 7: 2016-06-10 AfterShip - How to code better and faster

Key principles in software engineering

Separation of concerns● Divide app into layers of non overlapping concerns● Minimize interaction points between the layers● High cohesion + Low Coupling

Page 8: 2016-06-10 AfterShip - How to code better and faster

Question : Identify mixed up architectural concerns in following code?

source: http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/

Page 9: 2016-06-10 AfterShip - How to code better and faster

Specific Answer - separate the data handling code

Any other problems you see?

Page 10: 2016-06-10 AfterShip - How to code better and faster

General Answer - Follow a layered architecture pattern such as MVC, DAO, DDD upfront

Page 11: 2016-06-10 AfterShip - How to code better and faster

MVCDDD

DAO

Page 12: 2016-06-10 AfterShip - How to code better and faster

Aftership Notice Board

● Aftership needed an online notice board and some guy at Aftership built this app

● Now he has left. We need to add a few new features

● But no one but him understands the code :(● So we need your help in making it more

maintainable

Page 13: 2016-06-10 AfterShip - How to code better and faster

1) Time For Some Exercise :)● Clone the repository https://github.com/vimukthi-git/howtcodebetterfaster/● This is using Koa framework http://koajs.com/ ● ‘npm install ’● Run the app with ‘npm start ’ and open ‘http://localhost:3000 ’● For a start checkout the branch ‘1_separate_concerns_bad ’● Open the app in your IDE● Check the ‘app.js’, Seems the entire app is in one file now.● Let’s separate the concerns by following MVC. ● Extract the handlers and their dependencies into a ‘controllers.js ’.

Fully MVC version is in the branch ‘2_separate_concerns_good’

Page 14: 2016-06-10 AfterShip - How to code better and faster

Key principles .. cntd,

Single responsibility Principle

● A responsibility is “a reason to change”● Divide components so that each one will only “change” for a

single reason only● Write side-effectless code

Page 15: 2016-06-10 AfterShip - How to code better and faster

Question : Separate the responsibilities of following class?

Page 16: 2016-06-10 AfterShip - How to code better and faster

Specific Answer - Divide Auth, Detail, Orders, Request into separate modules

Page 17: 2016-06-10 AfterShip - How to code better and faster

General Answer - Follow Module or a composition pattern depending on the situation

● Divide to class and files like we did in the example - Module Pattern● Microservices pattern derives from this● Follow a composition pattern such as chain of control or strategy,

Page 18: 2016-06-10 AfterShip - How to code better and faster

2) Let’s refactor our app so that controllers have single responsibility

● After we converted the app to MVC it was easier for us to add our user login feature.

● Checkout the branch ‘3_single_responsibility_bad ’, Run the app● Login user: ‘vimukthi ’ pass: ‘123’● But seems our controller violates single responsibility● Let’s create a directory ‘controllers ’ and add two new files

‘auth_controller.js ’ and ‘notice_controller.js ’● Move login related handlers and their dependencies to ‘auth_controller.

js’

Fully single responsibility version is in the branch ‘4_single_responsibility_good’

Page 19: 2016-06-10 AfterShip - How to code better and faster

Chain of control pattern

Where have you seen chain of control pattern?

Page 20: 2016-06-10 AfterShip - How to code better and faster

3) Let’s practice chain of control

● Add the config.json with an auth parameter for local, dev prod envs● Load the config in app.js● Provide the config to controllers in a koa middleware (Note this is

just an example, There is a better way to do configs in Koa)● Use the config in auth controller to remove authentication for local

env● As you can see koa middleware is a great example of chain of

control pattern

Answer is in the branch ‘5_chain_of_control’

Page 21: 2016-06-10 AfterShip - How to code better and faster

Strategy pattern

Page 22: 2016-06-10 AfterShip - How to code better and faster

4) Let’s practice strategy pattern

● Right now the notice board sorts by chronological order only● Let’s make it sort by alphabetical order while also making good use of strategy

pattern.● Let’s extract query parameter ‘sort’ in the

`controllers/notice_controller`● Then add a `sort` parameter to ‘list’ function in

`models/notice_model.js ` ● Then add the two strategy classes for sorting in ‘utils.js ’● Refactor `list` function to take the sort parameter and use the strategy

classes to sort.

Answer is in the branch ‘6_strategy’

Page 23: 2016-06-10 AfterShip - How to code better and faster

Key principles .. cntd,

Principle of least knowledge

● Each unit should have only limited knowledge about other units:

● Each unit should only talk to its friends; don't talk to strangers.

● Only talk to your immediate friends.

Page 24: 2016-06-10 AfterShip - How to code better and faster

Question : Why does following code violate Principle of least knowledge?

source: https://github.com/AfterShip/aftership-sdk-nodejs

Page 25: 2016-06-10 AfterShip - How to code better and faster

Specific Answer - Define proper interfaces and hide implementation

source: https://github.com/AfterShip/aftership-sdk-go

● Define proper interface methods● Hide REST specific parts in interface● Separate implementation and interface if

possible● Specify types of variables in interface if

possible● Help the lang interpreters/compilers in

helping the user● Only use Libs that hide implementation

details

Page 26: 2016-06-10 AfterShip - How to code better and faster

General Answer - Use clear interfaces● Javascript(Nodejs) has no interfaces, so better to document well, follow a

convention or implement programmatic type/interface checking.● Somehow prevent the people who use your code from depending on the

internals.

Page 27: 2016-06-10 AfterShip - How to code better and faster

5) Exercise Add a new data model

● To better understand the concept of an interface we will now add a new data model to our app

● This model will use the file system as the data store instead of the JS array our current model uses

● First copy the ‘models/notice_model.js’ to a new file in the model directory called ‘models/notice_file_model.js’ .

● Then add a ‘notices.json ’ file with array of notices to the root of project● Rewrite the `list` and `getById` functions to load from json file● Then add a function called ‘saveToFile(message, noticesJson)’● Save to json file when `create` is called

Answer is in the branch ‘7_add_new_data_model’

Page 28: 2016-06-10 AfterShip - How to code better and faster

General Answer - Private class data pattern

source: http://www.2ality.com/2016/01/private-data-classes.html

Page 29: 2016-06-10 AfterShip - How to code better and faster

6) Exercise convert user model to use Private class data pattern

● Let’s make our User object variables such as username private.● Introduce `Symbol` s for `username` and `password` variables.● Define private variables for them based on symbols● Finally add getters● Advantage is we can easily switch to using email as the user name if we

wanted

Answer is in the branch ‘8_private_class_data’

Page 30: 2016-06-10 AfterShip - How to code better and faster

General Answer - Dependency injection pattern

Who ever creates SayHelloWithStrategy instances has to wire the dependencies. SayHelloWithStrategy is oblivious to the way its strategies are created.

We already covered another good example in our app for dependency injection, can you name it?

Page 31: 2016-06-10 AfterShip - How to code better and faster

Key principles .. cntd,

Don’t repeat yourself

● Specific functionality should be implemented in only one component

● Then reused

Page 32: 2016-06-10 AfterShip - How to code better and faster

Question : How to create a MurderRobotDog with following class hierarchy?

source: https://www.youtube.com/watch?v=wfMtDGfHWpA

Page 33: 2016-06-10 AfterShip - How to code better and faster

Specific Answer : Instead of creating a hierarchy, create objects/functions that provide the needed functionality and compose the final solution

source: https://www.youtube.com/watch?v=wfMtDGfHWpA

I.e We prevent our code from violating DRY by reusing almost all code we write.

Page 34: 2016-06-10 AfterShip - How to code better and faster

General Answer : Use composition instead of inheritance

● Define all functionality using smaller single responsibility functions in a stateless and side effectless manner.

RetrieveJob

● Then you can combine them to build more complex functions easily.

● This is essentially like using Lego blocks to construct a building

ExecuteJob

ReputJob

ProcessJob

RetrieveJob ProcessJob

RetrieveJob ExecuteJob

ReputJob

Page 35: 2016-06-10 AfterShip - How to code better and faster

General Answer : Use composition instead of inheritance

Eg: Strategy Pattern

Page 36: 2016-06-10 AfterShip - How to code better and faster

7) Let’s practice basic composition to add a render util to our controllers

● No need of inheritance anywhere in our app as we reuse and model our code based on composition

● Render method is a great example of how we can demonstrate this.● In a traditional MVC app there would be a Generic/Parent controller so that

other controllers can inherit all methods● But we will make all those methods into utils in ‘utils.js ’

Answer is in the branch ‘9_basic_composition’

Page 37: 2016-06-10 AfterShip - How to code better and faster

Key principles .. cntd,

Minimize upfront design

Page 38: 2016-06-10 AfterShip - How to code better and faster

Question : How to better Balance Maintainability vs Time to market?

Page 39: 2016-06-10 AfterShip - How to code better and faster

Answer: Do not reinvent the wheel of good software design

● Follow tried and tested design patterns● Following patterns makes it easy to build frameworks/automate● Using patterns build independent functions/modules with,

○ Separated concerns and good interfaces○ Well defined responsibilities ○ And reusability in mind

● Prefer composition over Inheritance as○ It minimizes the need to think about object hierarchies upfront○ It makes your architecture as well as your product more agile

● Refactor continuously

Page 40: 2016-06-10 AfterShip - How to code better and faster

Patterns Summary

● Model-View-Controller(or Model-View-*)● Data Access Objects● Module Pattern● Chain of Responsibility Pattern● Strategy Pattern● Private Class Data Pattern● Dependency Injection Pattern

Page 42: 2016-06-10 AfterShip - How to code better and faster

Q & A

Page 43: 2016-06-10 AfterShip - How to code better and faster

Thanks..!