Anti Object-Oriented Design Patterns

24
DEVCON 2013 Anti- Object Oriented Design Patterns Alvaro Polo

description

This talk shows an analysis of some object oriented design patterns that are there to fight against the object oriented design and the rules and constraints of some of the most popular OOP languages. Some of these patterns will be discussed in detail, analyzing their nature from the PLT (Programming Language Theory). For each one, an alternative using non-OOP design will be discussed. The final purpose of the talk is to provide some insights about OOP and what would be the benefits of mixing such a paradigm with others like functional programming.

Transcript of Anti Object-Oriented Design Patterns

Page 1: Anti Object-Oriented Design Patterns

DEVCON  2013  

Anti- Object Oriented Design Patterns

Alvaro Polo

Page 2: Anti Object-Oriented Design Patterns

DEVCON  2013  

Design Patterns

What’s a design pattern?

“A   general   reusable   solu-on   to   a   commonly  occurring   problem   within   a   given   context   in  so8ware  design”,  Wikipedia  

Page 3: Anti Object-Oriented Design Patterns

DEVCON  2013  

Design Patterns

But, what kind of commonly ocurring problem are we talking about?

Page 4: Anti Object-Oriented Design Patterns

DEVCON  2013  

Design Patterns

No, this is all about software design

Page 5: Anti Object-Oriented Design Patterns

DEVCON  2013  

Problems unsolved by the language

_uppercase: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp movq %rdi, -8(%rbp) movl %esi, -12(%rbp) movl $0, -16(%rbp)

LBB0_1: movl -16(%rbp), %eax cmpl -12(%rbp), %eax jge LBB0_3 movslq -16(%rbp), %rax movq -8(%rbp), %rcx movb (%rcx,%rax), %dl movb %dl, -17(%rbp) movsbl -17(%rbp), %esi cmpl $97, %esi jl LBB0_2

movsbl -17(%rbp), %eax cmpl $122, %eax jg LBB0_2 movsbl -17(%rbp), %eax addl $65, %eax subl $97, %eax movb %al, %cl movslq -16(%rbp), %rdx movq -8(%rbp), %rsi movb %cl, (%rsi,%rdx)

LBB0_2: movl -16(%rbp), %eax addl $1, %eax movl %eax, -16(%rbp) jmp LBB0_1

LBB0_3: popq %rbp ret

Page 6: Anti Object-Oriented Design Patterns

DEVCON  2013  

Problems unsolved by the language

_uppercase: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp movq %rdi, -8(%rbp) movl %esi, -12(%rbp) movl $0, -16(%rbp)

begin_for: movl -16(%rbp), %eax cmpl -12(%rbp), %eax jge end_for movslq -16(%rbp), %rax movq -8(%rbp), %rcx movb (%rcx,%rax), %dl movb %dl, -17(%rbp) movsbl -17(%rbp), %esi cmpl $97, %esi jl end_if

movsbl -17(%rbp), %eax cmpl $122, %eax jg end_if movsbl -17(%rbp), %eax addl $65, %eax subl $97, %eax movb %al, %cl movslq -16(%rbp), %rdx movq -8(%rbp), %rsi movb %cl, (%rsi,%rdx)

end_if: movl -16(%rbp), %eax addl $1, %eax movl %eax, -16(%rbp) jmp begin_for

end_for: popq %rbp ret

void uppercase(char *str, int strl) { for (int i = 0; i < strl; i++) { char c = str[i]; if (c >= 'a' && c <= 'z') str[i] = 'A' + c - 'a'; } }

Page 7: Anti Object-Oriented Design Patterns

DEVCON  2013  

Problems caused by the language

We want to represent IPv4 addresses in our Java program. Suggestions? class IpV4Address {

private uint bits = 0; public static IpV4Address fromCidr(String cidr) { ... } public bool isInSameNetwork(IpV4Address addr, Netmask netmask) { ... } ... };

Page 8: Anti Object-Oriented Design Patterns

DEVCON  2013  

Problems caused by the language

We want to represent IPv4 addresses in our program. Suggestions? class IpV4Address {

private uint bits = 0; public static IpV4Address fromCidr(String cidr) { ... } public bool isInSameNetwork(IpV4Address addr, Netmask netmask) { ... } ... };

Page 9: Anti Object-Oriented Design Patterns

DEVCON  2013  

Problems caused by the language

Let  me  introduce  the  An@-­‐  Object  Oriented  Design  PaGerns  

Page 10: Anti Object-Oriented Design Patterns

DEVCON  2013  

Singleton Pattern

Page 11: Anti Object-Oriented Design Patterns

DEVCON  2013  

Singleton Pattern

public class Application extends Configurable { private static Application instance; private Application() { ... } public static Application getInstance() { if (instance == null) instance = new Application(); return instance; } // The functionality of the application goes here ... }

OOP establishes some constraints: ü Every object is bounded to a lifecycle ü Every class has as many instances as fit into

memory

Singleton is fighting against these rules!

Page 12: Anti Object-Oriented Design Patterns

DEVCON  2013  

Singleton Pattern

What if we bend the rules? ...

object Application extends Configurable { // The functionality of the application goes here ... }

Page 13: Anti Object-Oriented Design Patterns

DEVCON  2013  

Strategy and Co.

Page 14: Anti Object-Oriented Design Patterns

DEVCON  2013  

Strategy and Co.

interface Player { void attack(Player enemy); // Other stuff the player does ...

} interface Weapon { void attack(Player enemy); } class AbstractPlayer implements Player { private Weapon weapon;

public setWeapon(Weapon weapon) { this.weapon = weapon; } public void attack(Player enemy) { weapon.attack(enemy); }

} class Axe implements Weapon { ... } class Sword implements Weapon { ... } class Bow implements Weapon { ... }

ü  Java is a pure-OOP programming language

ü  Everything is modeled using objects

Strategy is fighting against the lack of other mechanism to represent behavior!

Page 15: Anti Object-Oriented Design Patterns

DEVCON  2013  

Strategy and Co.

What if we have a non-pure OOP language?

class player { public: typedef std::function<void(Player&)> weapon; void set_weapon(weapon& w) { _weapon = w; } void attack(player& enemy) { _weapon(enemy); } private: weapon _weapon; }; void axe(player& enemy) { ... } void sword(player& enemy) { ... } void bow(player& enemy) { ... }

Page 16: Anti Object-Oriented Design Patterns

DEVCON  2013  

Strategy and Co.

The lack of functions is not a matter exclusive for strategy pattern ü  Observer pattern ü  Factory (method) pattern ü  Adapter pattern ü  …

Page 17: Anti Object-Oriented Design Patterns

DEVCON  2013  

Visitor

Page 18: Anti Object-Oriented Design Patterns

DEVCON  2013  

Visitor

interface CarElementVisitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Body body); void visit(Car car); } interface CarElement { void accept(CarElementVisitor visitor); } class Wheel implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Engine implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Body implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } }

class Car implements CarElement { public void accept(CarElementVisitor visitor) { for(CarElement elem : elements) elem.accept(visitor); visitor.visit(this); } } class Mechanic implements CarElementVisitor { public void visit(Wheel wheel) { ... } public void visit(Engine engine) { ... } public void visit(Body body) { ... } public void visit(Car car) { ... } }

Page 19: Anti Object-Oriented Design Patterns

DEVCON  2013  

Visitor

interface CarElementVisitor { void visit(Wheel wheel); void visit(Engine engine); void visit(Body body); void visit(Car car); } class Car implements CarElement { public void accept(CarElementVisitor visitor) { for(CarElement elem : elements) visitor.visit(elem); visitor.visit(this); } }

Why not simply…?

elem is a CarElement, and

visit(CarElement) is not defined in

visitor!

Page 20: Anti Object-Oriented Design Patterns

DEVCON  2013  

Visitor

That’s why we need to redefine accept() again and again

interface CarElement { void accept(CarElementVisitor visitor); } class Wheel implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Engine implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Body implements CarElement { public void accept(CarElementVisitor visitor) { visitor.visit(this); } }

Call visit(Wheel w)

Call visit(Engine e)

Call visit(Body b)

Page 21: Anti Object-Oriented Design Patterns

DEVCON  2013  

Visitor

What if we dispatch the message based on… ü The receiver of the message, and… ü The arguments of the message?

Let me introduce the double dispatch! Visitor pattern is there to provide double dispatch semantics not supported by the language

Page 22: Anti Object-Oriented Design Patterns

DEVCON  2013  

Conclusions

Page 23: Anti Object-Oriented Design Patterns

DEVCON  2013  

Conclusions

ü  Design patterns are bad ü  NOOOOOOOOOOO!!!!!!! ü  Design patterns are useful, even when they fight against the

language ü We must learn from our errors and languages must evolve to

avoid them And some opinions ü  OOP as implemented by Java is almost over ü  Learn Scala

Page 24: Anti Object-Oriented Design Patterns

DEVCON  2013  

Q&A