0% found this document useful (0 votes)
15 views53 pages

Refactoring To Patterns

The document discusses the evolution of the Mephisto software from a simple structure to a more complex, multi-engine system through the application of refactoring and design patterns. It emphasizes the importance of refactoring for improving code structure without altering its external behavior and introduces various design patterns, particularly the Strategy Pattern, to manage multiple algorithms for spam detection. The document also outlines specific code examples demonstrating the refactoring process and the implementation of design patterns in Mephisto.

Uploaded by

alok singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views53 pages

Refactoring To Patterns

The document discusses the evolution of the Mephisto software from a simple structure to a more complex, multi-engine system through the application of refactoring and design patterns. It emphasizes the importance of refactoring for improving code structure without altering its external behavior and introduces various design patterns, particularly the Strategy Pattern, to manage multiple algorithms for spam detection. The document also outlines specific code examples demonstrating the refactoring process and the implementation of design patterns in Mephisto.

Uploaded by

alok singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

Refactoring to Patterns

How Mephisto went from a single engine Lada


to a multi-engine jet figher
The Story

Behind a multi-engine
Mephisto
The Story
The Story

237 spams
The Story

Over a weekend
The Story
The Story

Long
The Story

Long

Arduous
The Story

Long

Arduous
Ooops! 
Hazardous
The Story ­ Solution
The Story ­ Solution
The Story ­ Solution

Carl kindly asked for a
Defensio plugin on
Mephisto
The Story ­ Solution

I wanted to try Git
The Story ­ Solution

Mephisto arrived on
GitHub
The Story ­ Solution

Time to Refactor
to Design Patterns
Refactoring

What is refactoring ?
Refactoring
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.
Martin Fowler, Refactoring: Improving the Design of Existing Code, page 53
Refactoring

Refactoring:
Improving the Design
of Existing Code
Refactoring

Without changing its external behavior


Refactoring ­ Example

class Comment
def check_approval
# ...
end
end
Refactoring ­ Example

class Comment
def ham?
# ...
end
end
Design Patterns
Each pattern describes a problem which occurs
over and over again in our environment, and
then describes the core of the solution to that
problem, in such a way that you can use this
solution a million times over, without ever doing
it the same way twice
Christopher Alexander, A Pattern Language, page x
Design Patterns

Design Patterns:
Elements of Reusable
Object­Oriented
Software
Design Patterns ­ Example

Strategy: Define a
family of algorithms,
encapsulate each one,
and make them
interchangeable.
Refactoring to Patterns

Refactoring, with the intention


of instantiating a design pattern
Mephisto 0.8 Drax

class Comment
def check_approval(site, request)
self.approved = site.approve_comments?
if valid_comment_system?(site)
akismet = Akismet.new(site.akismet_key, site.akismet_url)
self.approved = !akismet.comment_check(
comment_spam_options(site, request))
end
end
end
Mephisto 0.8 Drax + Defensio
class Comment
def check_approval(site, request)
self.approved = site.approve_comments?
if valid_akismet_comment_system?(site)
akismet = Akismet.new(site.akismet_key, site.akismet_url)
self.approved = !akismet.comment_check(
akismet_comment_spam_options(site, request))
elsif valid_defensio_comment_system?(site)
defensio = Defensio.new(site.defensio_key,
site.defensio_url)
self.approved = !defensio.comment_check(
defensio_comment_spam_options(site, request))
end
end
end
Mephisto 0.8 Drax + Defensio + Chummy

class Comment
def check_approval(site, request)
self.approved = site.approve_comments?
case
when valid_akismet_comment_system?(site)
akismet_validation(site, request)
when valid_defensio_comment_system?(site)
defensio_validation(site, request)
when valid_chummy_comment_system?(site)
chummy_validation(site, request)
# and so on...
end
end
end
Core of the problem ?

Be able to support multiple


algorithms to detect comment spam
How ?

Strategy Design Pattern


Refactoring to Strategy Pattern
Refactoring to Strategy Pattern
Introduce Class

class Mephisto::SpamDetectionEngines::AkismetEngine
end
Refactoring to Strategy Pattern
Move Method
class Comment
def check_approval(site, request)
self.approved = site.approve_comments?
if valid_comment_system?(site)
akismet = Akismet.new(
site.akismet_key, site.akismet_url)
self.approved = !akismet.comment_check(
comment_spam_options(site, request))
end
end
end

class Mephisto::SpamDetectionEngines::AkismetEngine
end
Refactoring to Strategy Pattern
Move Method
class Comment
def check_approval(site, request)
Mephisto::SpamDetectionEngines::AkismetEngine.new(
site.akismet_key, site.akismet_url).check_approval(
self, site, request)
end
end

class Mephisto::SpamDetectionEngines::AkismetEngine
def check_approval(comment, site, request)
comment.approved = !akismet.comment_check(
comment_spam_options(comment, site, request))
end
end
Refactoring to Strategy Pattern
Structural Changes
Refactoring to Strategy Pattern
Introduce Subclass
class Mephisto::SpamDetectionEngines::DefensioEngine <
Mephisto::SpamDetectionEngines::AkismetEngine
end
Refactoring to Strategy Pattern
Add Behavior
class Mephisto::SpamDetectionEngines::DefensioEngine <
Mephisto::SpamDetectionEngines::AkismetEngine
def check_approval(comment, site, request)
!defensio.check_comment(
comment_spam_options(comment, site, request))
end

def comment_spam_options(comment, site, request)


# Defensio-specific spam options
end
end
Refactoring to Strategy Pattern
Structural Changes
Refactoring to Strategy Pattern
Extract Superclass
module Mephisto::SpamDetectionEngines
class Base
end

class DefensioEngine < Base


end

class AkismetEngine < Base


end
end
Refactoring to Strategy Pattern
Structural Changes
Creational Patterns

Abstract Factory Pattern


Creational Patterns

class Site
def spam_engine
klass_name = read_attribute(:spam_detection_engine)
if klass_name.blank?
Mephisto::SpamDetectionEngines::
NullEngine.new(self)
else
klass_name.constantize.new(self)
end
end
end
Refactoring to Strategy Pattern
Interaction Diagram
Adapter Pattern

Convert the interface of a class


into another interface clients expect.
Adapter Pattern

def check_approval
# implementation
end
Adapter Pattern

def ham?
# implementation
end
Refactoring to Adapter Pattern
Before
class CommentsController
def create
if @comments.check_approval(site, request) then
# thanks
else
# thanks, but moderated
end
end
end

class Comment
def check_approval(site, request, options={})
# implementation
end
end
Refactoring to Adapter Pattern
Rename Method
class CommentsController
def create
if @comments.ham?(site, request) then
# thanks
else
# thanks, but moderated
end
end
end

class Comment
def check_approval(site, request, options={})
# implementation
end
end
Refactoring to Adapter Pattern
Interaction Diagram
Who am I ?

François Beausoleil
Who am I ?

François Beausoleil

A Single Programmer's
Blog
Who am I ?

François Beausoleil

A Single Programmer's
Blog

XLsuite
Creative Commons Attributions

dave_7
http://flickr.com/photos/daveseven/204585649/

DanieVDM
http://flickr.com/photos/dvdmerwe/251163984/

You might also like