Scaling API-first – The story of a global engineering organization
PRDCW-advanced-design-patterns
1. AMIR BARYLKO
ADVANCED
DESIGN PATTERNS
Amir Barylko Advanced Design Patterns
2. WHO AM I?
• Software quality expert
• Architect
• Developer
• Mentor
• Great cook
• The one who’s entertaining you for the next hour!
Amir Barylko Advanced Design Patterns
4. PATTERNS
What are they?
What are anti-patterns?
Which patterns do you use?
Amir Barylko Advanced Design Patterns
5. WHAT ARE PATTERNS?
•Software design Recipe
•or Solution
•Should be reusable
•Should be general
•No particular language
Amir Barylko Advanced Design Patterns
6. ANTI-PATTERNS
• More patterns != better design
• No cookie cutter
• Anti Patterns : Patterns to identify failure
• God Classes
• High Coupling
• Breaking SOLID principles....
• (name some)
Amir Barylko Advanced Design Patterns
7. WHICH PATTERNS
DO YOU USE?
• Fill here with your patterns:
Amir Barylko Advanced Design Patterns
10. CHAIN OF RESPONSIBILITY
• More than one object may handle a request, and the handler
isn't known a priori.
• The handler should be ascertained automatically.
• You want to issue request to one of several objects without
specifying The receiver explicitly.
• The set of objects that can handle a request should be
specified dynamically
Amir Barylko Advanced Design Patterns
14. PROXY
• Avoid creating the object until needed
• Provides a placeholder for additional functionality
• Very useful for mocking
• Many implementations exist (IoC, Dynamic proxies, etc)
Amir Barylko Advanced Design Patterns
17. ACTIVERECORD
• Isa Domain Model where classes match very closely the
database structure
• Each table is mapped to class with methods for finding,
update, delete, etc.
• Each attribute is mapped to a column
• Associations are deduced from the classes
Amir Barylko Advanced Design Patterns
18. create_table "movies", :force => true do |t|
t.string "title"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "reviews", :force => true do |t|
t.string "name"
t.integer "stars"
t.text "comment"
t.integer "movie_id"
t.datetime "created_at"
t.datetime "updated_at"
end
class Movie < ActiveRecord::Base
validates_presence_of :title, :description
has_many :reviews
end
class Review < ActiveRecord::Base
belongs_to :movie
end
Amir Barylko Advanced Design Patterns
19. movie = Movie.new
movie.all # all records
# filter by title
movie.where(title: 'Spaceballs')
# finds by attribute
movie.find_by_title('Blazing Saddles')
# order, skip some and limit the result
movie.order('title DESC').skip(2).limit(5)
# associations CRUD
movie.reviews.create(name: 'Jay Sherman',
stars: 1,
comment: 'It stinks!')
Amir Barylko Advanced Design Patterns
20. REPOSITORY
• Mediator between domain and storage
• Acts like a collection of items
• Supports queries
• Abstraction of the storage
Amir Barylko Advanced Design Patterns
23. ANTIPATTERN
CHEAPER BY THE DOZEN
Amir Barylko Advanced Design Patterns
24. WHAT TO DO?
• Use a criteria or better a queryable result (LINQ)
• Use a factory to return repositories
• Use a UnitOfWork with a factory
Amir Barylko Advanced Design Patterns
25. EVENT AGGREGATOR
• Manage events using a subscribe / publish mechanism
• Isolates subscribers from publishers
• Decouple events from actual models
• Events can be distributed
• Centralize event registration logic
• No need to track multiple objects
Amir Barylko Advanced Design Patterns
26. Channel events
from multiple
objects into a
single object to
s i m p l i f y
registration for
clients
Amir Barylko Advanced Design Patterns
30. EVENT SOURCING
• Register all changes in the application using events
• Event should be persisted
• Complete Rebuild
• Temporal Query
• Event Replay
Amir Barylko Advanced Design Patterns
33. LIST COMPREHENSION
• Syntax Construct in languages
• Describe properties for the list (sequence)
• Filter
• Mapping
• Same idea for Set or Dictionary comprehension
Amir Barylko Advanced Design Patterns
34. LANGUAGE COMPARISON
• Scala
for (x <- Stream.from(0); if x*x > 3) yield 2*x
• LINQ
var range = Enumerable.Range(0..20);
from num in range where num * num > 3 select num * 2;
• Clojure
(take 20 (for [x (iterate inc 0) :when (> (* x x) 3)] (* 2 x)))
• Ruby
(1..20).select { |x| x * x > 3 }.map { |x| x * 2 }
Amir Barylko Advanced Design Patterns
35. OBJECT MOTHER / BUILDER
• Creates an object for testing (or other) purposes
• Assumes defaults
• Easy to configure
• Fluent interface
• Usually has methods to to easily manipulate the domain
Amir Barylko Advanced Design Patterns
36. public class When_adding_a_an_invalid_extra_frame
{
[Test]
public void Should_throw_an_exception()
{
// arrange
10.Times(() => this.GameBuilder.AddFrame(5, 4));
var game = this.GameBuilder.Build();
// act & assert
new Action(() => game.Roll(8)).Should().Throw();
}
}
http://orthocoders.com/2011/09/05/the-bowling-game-kata-first-attempt/
Amir Barylko Advanced Design Patterns
38. VISITOR
• Ability to traverse (visit) a object structure
• Different visitors may produce different results
• Avoid littering the classes with particular operations
Amir Barylko Advanced Design Patterns
42. NULL OBJECT
• Represent “null” with an actual instance
• Provides default functionality
• Clear semantics of “null” for that domain
Amir Barylko Advanced Design Patterns
43. class animal {
public:
virtual void make_sound() = 0;
};
class dog : public animal {
void make_sound() { cout << "woof!" << endl; }
};
class null_animal : public animal {
void make_sound() { }
};
http://en.wikipedia.org/wiki/Null_Object_pattern
Amir Barylko Advanced Design Patterns
44. FACTORY
• Creates instances by request
• More flexible than Singleton
• Can be configured to create different families of objects
• IoC containers are closely related
• Can be implemented dynamic based on interfaces
• Can be used also to release “resource” when not needed
Amir Barylko Advanced Design Patterns
45. interface GUIFactory {
public Button createButton();
}
class WinFactory implements GUIFactory {
public Button createButton() {
return new WinButton();
}
}
class OSXFactory implements GUIFactory {
public Button createButton() {
return new OSXButton();
}
}
interface Button {
public void paint();
}
http://en.wikipedia.org/wiki/Abstract_factory_pattern
Amir Barylko Advanced Design Patterns
46. STRATEGY
• Abstracts the algorithm to solve a particular problem
• Can be configured dynamically
• Are interchangeable
Amir Barylko Advanced Design Patterns
48. DATA TRANSFER OBJECT
• Simplifies information transfer across services
• Can be optimized
• Easy to understand
Amir Barylko Advanced Design Patterns
50. PAGE OBJECT
• Abstract web pages functionality to be used usually in testing
• Each page can be reused
• Changes in the page impact only the implementation, not the
clients
Amir Barylko Advanced Design Patterns
51. class ProjectListPage
include PageObject
def navigate
visit('/projects')
self
end
def edit(project)
row = find(:xpath, "//td[.='#{project.name}']")
row.parent.click_link('Edit')
ProjectEditPage.new
end
def projects
all(:css, "#projects tr")......
end
end
Amir Barylko Advanced Design Patterns
52. When /^I go to the projects page$/ do
project_list_page.navigate
end
When /^I activate the project$/ do
project_list_page.
navigate.
edit(current_project).
activate.
save
end
Amir Barylko Advanced Design Patterns
54. RESOURCES
• Email: amir@barylko.com, @abarylko
• Slides: http://www.orthocoders.com/presentations
• Patterns: Each pattern example has a link
Amir Barylko Advanced Design Patterns
57. QUALITY SOFTWARE
TRAINING
• Topics: Kanban, BDD & TDD.
• When: May 4, 10-11 & 16-17
• More info: http://www.maventhought.com
• Goal: Learn techniques, methodologies and tools to improve
the quality in your job.
Amir Barylko Advanced Design Patterns