Part of an introductory series given to new hires and interns, this talk is a crash course in design patterns and engineering best practices for new-grads with mostly academic computer science experience. Focuses on the things they don't teach you: naming things, working on a team, optimizing for maintainability.
7. • Has one well defined job. Doesn’t ask
questions.
• Has limited knowledge of the rest of the
operation. Others don’t know or care how
he gets the job done.
• Has no secret dealings with others, clean
cut actor.
• Can be replaced—others could do this
specific job if he was “removed.”
8. • Single Responsibility Principle
(Robert C. Martin)
• Separation of Concerns
(Dijkstra)
• Avoid Side Effects
• “Program to an interface, not an
implementation.” (Erich Gamma)
12. Design Patterns
Command
Encapsulate a request as an object, thereby letting users
parameterize clients with different requests, queue or log
requests, and support undoable operations.
(Tasks in N1 are an implementation of the Command pattern.)
13. Anti-Patterns (“Code Smells”)
- Copying code into more than three places
- Calling private methods on other classes
- Inspecting state which was not designed to be observed
- Waiting for something to happen using the wall clock
setTimeout I’m looking at you. 😒
14. Anti-Patterns (“Code Smells”)
Ex: Adding optional parameters that change the behavior of
existing code slightly. “Don’t do this, this one time.”
thread.save({tellUser: true}) thread.save().then(() => {
this.tellUser();
});
Take a break, think about refactoring,
explain the problem to someone else.
16. • Functions that return a value should indicate how costly that
value is to retrieve:
thread() // easy
getThread() // hmm, probably not O(1)
fetchThread() // better cache the result of this!
Naming Conventions
17. • Names should reflect intended use and give you an idea what
is returned:
onClicked() // called in response to an event
newWindow() // always returns a new object
isSending() // always returns a boolean
ensureReady() // may or may not do anything
• Long names are almost always worth it:
finalizeAndPersistNewMessage() // shit is going down
Naming Conventions
18. • Functions with many parameters should use named hashes:
_onComposeReply: ({thread, message, popout, behavior}) =>
• Leading (or trailing) underscores denote private members:
_doInternalFileWrite myInstanceVar_
this._onComposeReply({
thread: A,
behavior: reply-all,
popout: true
})
Naming Conventions
19. Exceptions aren’t Evil
Throw exceptions aggressively to protect the
code you write from things it wasn’t intended for.
• If your code makes assumptions, make
assertions.
• If you ever have the option of crashing now, or /
probably/ crashing later downstream, crash
now.
22. Code Review
Code Level:
• Clarity
• Function / variable naming
• Test coverage
Architectural Level:
• Does this fit performance requirements?
• Does this follow conventions and patterns used elsewhere?
• Are we comfortable with the limitations of this approach?
• Are changes well contained?
23. Further Reading
- Design Patterns: Elements of Reusable Object-Oriented
Software (Gang of Four)
- Clean Code: A Handbook of Agile Software Craftmanship (Bob
Martin)
- https://sourcemaking.com/design_patterns
- http://en.clouddesignpattern.org