things every professional programmer should know
TRANSCRIPT
Things Every Professional Programmer
Should KnowOP Student Conference 2015
@DanielSawano
The IT Revolution
[The Delorian]
The IT Revolution
creating the future[The Delorian]
The IT Revolution
revolutionizing
[The Delorian]
The Landscape is changing
[Change Machine]
The Landscape is changing
• Competitors everywhere
[Change Machine]
The Landscape is changing
• Competitors everywhere
• Time to market essential
[Change Machine]
The Landscape is changing
• How to keep up?
• What to learn?
[Question Mark]
Know Your Language
• Low level characteristics• How common data structures and
constructs affect• CPU usage• Memory usage
Liskov Substitution Principle
“… If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of Pis unchanged when o1 is substituted for o2 then S is a subtype of T.”
- Barbara Liskov, 1988
Liskov Substitution Principle
class Rectangle { private int width; private int height; public int width() {return width;} public void setWidth(final int width) { this.width = width; } public int height() {return height;} public void setHeight(final int height) { this.height = height; } }
Liskov Substitution Principle
void setAndVerifyArea(final Rectangle rectangle) { rectangle.setHeight(5); rectangle.setWidth(4); int area = rectangle.height() * rectangle.width(); assertEquals(20, area); }
Liskov Substitution Principle
void setAndVerifyArea(final Rectangle rectangle) { rectangle.setHeight(5); rectangle.setWidth(4); int area = rectangle.height() * rectangle.width(); assertEquals(20, area); }
@Test void should_verify_area() { setAndVerifyArea(new Rectangle()); }
Liskov Substitution Principle
class Square extends Rectangle { @Override public void setWidth(final int width) { super.setWidth(width); super.setHeight(width); } @Override public void setHeight(final int height) { super.setHeight(height); super.setWidth(height); }}
Liskov Substitution Principle
@Test void should_verify_area() { setAndVerifyArea(new Rectangle()); setAndVerifyArea(new Square()); }
Liskov Substitution Principle
@Test void should_verify_area() { setAndVerifyArea(new Rectangle()); setAndVerifyArea(new Square()); }
void setAndVerifyArea(final Rectangle rectangle) { rectangle.setHeight(5); rectangle.setWidth(4); int area = rectangle.height() * rectangle.width(); assertEquals(20, area); }
Liskov Substitution Principle
Liskov Substitution Principle
• Use as guidance for inheritance
Liskov Substitution Principle
• Use as guidance for inheritance
• Common problems with inheritance:
• overused as means to achieve polymorphism
• “broken” inheritance caused by bad domain knowledge
• used as a bad way for code reuse (DRY)
Liskov Substitution Principle
• Use as guidance for inheritance
• Common problems with inheritance:
• overused as means to achieve polymorphism
• “broken” inheritance caused by bad domain knowledge
• used as a bad way for code reuse (DRY)
• if we brake LSP we brake substitution
Dependency Inversion Principle
A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
- Robert C. Martin, 1995
Dependency Inversion Principle
Foo
Bar
interface
Dependency Inversion Principle
Foo
Bar
SimpleBar
interface
implementation
Dependency Inversion Principle
Foo
Bar
SimpleBar
Dependency Inversion Principle
Foo
Bar
SimpleBarInverting
dependencies
Dependency Inversion Principle
• Decouples software modules• Essential for separation of concerns,
modularization, testability• Dependency Injection is a design pattern
typically used for realizing DIP• Violation of LSP will typically cause
problems
Composition Over Inheritance
A technique to achieve polymorphic behavior and code reuse without inheritance
Composition Over Inheritance
interface Shape { int area(); }
Composition Over Inheritance
interface Shape { int area(); }
class Rectangle implements Shape { private final int width, height; Rectangle(final int width, final int height) { this.width = width; this.height = height; } @Override public int area() { return width * height; } }
Composition Over Inheritance
class Square implements Shape { private final Rectangle rectangle; public Square(final int width) { rectangle = new Rectangle(width, width); } @Override public int area() { return rectangle.area(); }}
Composition Over Inheritance
• Helps you avoid accidentally violating LSP
• Makes your design more stable in the long term
• Makes your code more flexible
• Solves situations where you otherwise would need multiple inheritance
Encapsulation
Generally used to refer to one or both of:• information hiding
(e.g. hide the implementation)• bundling data with the methods that
operates on the data (e.g. angle.sin() vs Math.sin(x))
Encapsulation
Helps make your code:• modularized• adaptive to change
Encapsulation
Adaptive to change• Internals can be changed without
affecting others• One implementation can be substituted
for another
Encapsulation
“Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation’”
- Design Patterns, “Gang of Four”, 1995
Immutability
“An immutable object is one whose state cannot be changed after construction”
- Java Concurrency in Practice, B. Göetz et.al, 2006
Immutability
• Mutability itself is not bad• Problem is when mutable state
becomes shared
Immutabilityclass Rectangle implements Shape { private int width, height; Rectangle(final int width, final int height) { this.width = width; this.height = height; } public int width() { return width; }
public void setWidth(final int width) { this.width = width; } public int height() { return height; }
public void setHeight(final int height) { this.height = height; } }
Immutability
class Rectangle implements Shape { private final int width, height; Rectangle(final int width, final int height) { this.width = width; this.height = height; } public Rectangle withWidth(final int width) { return new Rectangle(width, height); } public Rectangle withHeight(final int height) { return new Rectangle(width, height); } }
How it all fits together
How it all fits together
Know your languageLiskov Substitution Principle
Dependency InversionPrinciple
Composition Over Inheritance
Encapsulation
Immutability
Continuous Integration
Continuous Integration
• Testable
Continuous Integration
• Testable=> DIP
Continuous Integration
• Testable=> DIP
• Test different parts separately
Continuous Integration
• Testable=> DIP
• Test different parts separately=> modularized code base
Continuous Integration
• Testable=> DIP
• Test different parts separately=> modularized code base => separation of concerns/DIP
Continuous Integration
• Testable=> DIP
• Test different parts separately=> modularized code base => separation of concerns/DIP
• Support small, incremental changes
Continuous Integration
• Testable=> DIP
• Test different parts separately=> modularized code base => separation of concerns/DIP
• Support small, incremental changes=> encapsulation, composition, DIP
Continuous Delivery
Code should always be deliverable
Continuous Delivery
Code should always be deliverable
• Deployable in different environments
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
• Deliver small pieces separately
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
• Deliver small pieces separately=> modularized code
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
• Deliver small pieces separately=> modularized code
=> LSP, DIP, encapsulation, low coupling
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
• Deliver small pieces separately=> modularized code
=> LSP, DIP, encapsulation, low coupling
• Keep business logic separated from infrastructure
Continuous Delivery
Code should always be deliverable
• Deployable in different environments=> IoC/DIP
• Deliver small pieces separately=> modularized code
=> LSP, DIP, encapsulation, low coupling
• Keep business logic separated from infrastructure=> encapsulation, IoC, design patterns
Deployable Anywhere
Your app should run:• containerless• in the cloud on a PaaS• on a company server
The Twelve-Factor App: http://12factor.net
Deployable Anywhere
Your app should run:• containerless• in the cloud on a PaaS• on a company server
=> enabled by DIP
The Twelve-Factor App: http://12factor.net
Awesome Images
1. [The Delorian - https://flic.kr/p/fFXKMu] by William Warby under license https://creativecommons.org/licenses/by/2.0/
2. [Change Machine - https://flic.kr/p/6BH6Kq] by Tracy Shaun under license https://creativecommons.org/licenses/by-sa/2.0/
3. [Cray CPU - https://flic.kr/p/dcy51L] by Brad Montgomery under license https://creativecommons.org/licenses/by/2.0/
4. [Question Mark - https://flic.kr/p/6okjAW] by Marco Belluci under license https://creativecommons.org/licenses/by/2.0/
Thank you!@DanielSawano