wzorce projektowe - architektura dużych aplikacji w pythonie

80
Wzorce projektowe Architektura dużych aplikacji w Pythonie

Upload: konrad-halas

Post on 25-Apr-2015

826 views

Category:

Documents


0 download

DESCRIPTION

Autor: Marek Stępniowskihttp://stepniowski.com/

TRANSCRIPT

Page 1: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektoweArchitektura dużych aplikacji w Pythonie

Page 2: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Marek Stępniowskihttp://stepniowski.com

@mstepniowski

Page 3: Wzorce projektowe - architektura dużych aplikacji w Pythonie
Page 4: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Gamma, et al.Design Patterns

Time

Hunt, ThomasThe PragmaticProgrammer Martin Fowler

Patterns of Enterprise Application Architecture

Cormen, et al.Introduction to

Algorithms

Kent BeckTest-Driven

Development

Python

Abelson, SussmanStructure and

Interpretation of Computer Programs

Chris OkasakiPurely Functional Data Structures

My first language

Stages of a programmer

Level

9000

0

Page 5: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Gamma, et al.Design Patterns

Time

Hunt, ThomasThe PragmaticProgrammer Martin Fowler

Patterns of Enterprise Application Architecture

Cormen, et al.Introduction to

Algorithms

Kent BeckTest-Driven

Development

Python

Abelson, SussmanStructure and

Interpretation of Computer Programs

Chris OkasakiPurely Functional Data Structures

My first language

Stages of a programmer

Level

9000

0

Page 6: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorzec projektowy

def. Uniwersalne, sprawdzone w praktyce rozwiązanie często pojawiających się, powtarzalnych problemów projektowych. Pokazuje powiązania i zależoności pomiędzy klasami oraz obiektami i ułatwia tworzenie, modyfikację oraz pielęgnację kodu źródłowego.

Page 7: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Singleton

Page 8: Wzorce projektowe - architektura dużych aplikacji w Pythonie

django.conf.settings

Page 9: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class Singleton { private static Singleton instance; private Singleton() {};

public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; }}

Page 10: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = ( super(Singleton, cls) .__new__(cls, *args, **kw)) return cls._instance

Page 11: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Alan ShalloweyJames R. Trott

Page 12: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Design patterns are higher-order abstractions for program organization.

Peter Norvig

Kod wynikowy

Kod źródłowy

Koncepcja procedury

Page 13: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Marek Stępniowski

Page 14: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Abstract Factory

Factory Method

Builder

Prototype

Singleton

Adapter

Bridge

Composite

Decorator

Facade

Flyweight

Proxy

Chain of Reponsibility

Command

Interpreter

Iterator

Mediator

Memento

Observer

State

Strategy

Template Method

Visitor

23

DP

Page 15: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Abstract Factory

Factory Method

Builder

Prototype

Singleton

Adapter

Bridge

Composite

Decorator

Facade

Flyweight

Proxy

Chain of Reponsibility

Command

Interpreter

Iterator

Mediator

Memento

Observer

State

Strategy

Template Method

Visitor

32

Multiton

Object Pool

RAII

Front Controller

Null Object

Publish/Subscribe

Blackboard

Servant

Specification

CC

Page 16: Wzorce projektowe - architektura dużych aplikacji w Pythonie

80

Transaction Script

Domain Model

Table Module

Service Layer

Table Data Gateway

Row Data Gateway

Active Record

Data Mapper

Unit of Work

Identity Map

Lazy Load

Identity Field

Foreign Key Mapping

Association Table

Mapping

Dependent Mapping

Embedded Value

Serialized LOB

Single Table Inheritance

Class Table Inheritance

Concrete Table

Inheritance

Inheritance Mappers

Metadata Mapping

Query Object Repository

Model View Controller

Page Controller

Front Controller

Template View

Transform View

Two-Step View

Application Controller

Remote Facade

Data Transfer Object

Client Session State

Server Session State

Database Session State

Gateway

Mapper

Layer Subtype

Separated Interface

Registry

Value Object

Money

Special Case

Plugin

Service Stub

Record Set PoEAA

Page 17: Wzorce projektowe - architektura dużych aplikacji w Pythonie

86

Transaction Script

Domain Model

Table Module

Service Layer

Table Data Gateway

Row Data Gateway

Active Record

Data Mapper

Unit of Work

Identity Map

Lazy Load

Identity Field

Foreign Key Mapping

Association Table

Mapping

Dependent Mapping

Embedded Value

Serialized LOB

Single Table Inheritance

Class Table Inheritance

Concrete Table

Inheritance

Inheritance Mappers

Metadata Mapping

Query Object Repository

Model View Controller

Page Controller

Front Controller

Template View

Transform View

Two-Step View

Application Controller

Remote Facade

Data Transfer Object

Client Session State

Server Session State

Database Session State

Gateway

Mapper

Layer Subtype

Separated Interface

Registry

Value Object

Money

Special Case

Plugin

Service Stub

Record Set

Model Template View

Model View Presenter

Model View ViewModel

Layers

KVO

KVC inne

Page 18: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

Behavioral

Structural

Creational Architectural

Concurrency

Page 19: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Money

Model View Controller

Prototype

Smart Pointers? Procedures? Classes? Value Objects? Reference Counting? Closures? Asynchronous communication? Layers?

Page 20: Wzorce projektowe - architektura dużych aplikacji w Pythonie

The first rule of Singletons is: you do not use Singletons

The second rule of Singletons is: you do not use Singletons

Page 21: Wzorce projektowe - architektura dużych aplikacji w Pythonie

django.conf.settings

Page 22: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class Borg: __shared_state = {} def __init__(self): self.__dict__ = self.__shared_state

Page 23: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class Singleton(type): def __init__(cls, name, bases, d): super(Singleton, cls).__init__( name, bases, d) cls._instance = None

def __call__(cls, *args, **kw): if cls._instance is None: cls._instance = ( super(Singleton, cls) .__call__(*args, **kw)) return cls._instance

class Settings(object): __metaclass__ = Singleton

Page 24: Wzorce projektowe - architektura dużych aplikacji w Pythonie

# settings.py

IM_A_CHARGIN_MAH_LAZER = TrueIM_A_FIRIN_MAH_LAZER = False

tagline = ''

# main.pyimport settings

settings.tagline = 'Shoop da Whoop'

Page 25: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Multiton

Page 26: Wzorce projektowe - architektura dużych aplikacji w Pythonie

import logging

log = logging.getLogger( 'setjam.classification.movie')

log.warning( 'New ep of Bold & Beautiful!')

logging

Page 27: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

Formal

Informal

Invisible

Peter Norvig

Page 28: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Singleton

Invisible

Informal

Formal

Page 29: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Multiton

Invisible

Informal

Formal

Page 30: Wzorce projektowe - architektura dużych aplikacji w Pythonie

oryginalnych wzorców projektowychniewidzialne lub uproszczone15/23

Page 31: Wzorce projektowe - architektura dużych aplikacji w Pythonie

First-class types: Abstract Factory, Factory Method, Flyweight, State, Proxy, Chain of Responsibility

First-class functions: Command, Strategy, Template Method, Visitor

Decorators: Mediator, Observer

Modules: Singleton, Facade +Iterator

Page 32: Wzorce projektowe - architektura dużych aplikacji w Pythonie
Page 33: Wzorce projektowe - architektura dużych aplikacji w Pythonie

))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

Page 34: Wzorce projektowe - architektura dużych aplikacji w Pythonie

AdapterAbstract FactoryMethod FactoryTemplate MethodNull ObjectPluginStrategyObserverState

9

Page 35: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Hipotetyczna firma

Page 36: Wzorce projektowe - architektura dużych aplikacji w Pythonie

SeriesMatcher().match(data)

ManualSeriesMatcher().match(data, pattern, trusted_keys)

MovieMatcher().match(subscription, data)

Page 37: Wzorce projektowe - architektura dużych aplikacji w Pythonie

+match(4)ClassificationEngine

+match(4)SeriesEngine

+match(4)ManualSeriesEngine

+match(4)MovieEngine

+match(1)SeriesMatcher

+match(4)ManualSeriesMatcher

+match(2)MovieMatcher

Adapter

Page 38: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): pass

class SeriesEngine(ClassificationEngine): def match(self, subscription, data, pattern, trusted_keys): return SeriesMatcher().match(data)

class ManualSeriesEngine(ClassificationEngine): def match(self, subscription, data, pattern, trusted_keys): return ManualSeriesMatcher().match(data, pattern, trusted_keys)

class MovieEngine(ClassificationEngine): def match(self, subscription, data, pattern, trusted_keys): return MovieMatcher().match(subscription, data)

Page 39: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class SeriesEngine(ClassificationEngine): def __init__(self): self.matcher = SeriesMatcher() def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data)

class ManualSeriesEngine(ClassificationEngine): def __init__(self): self.matcher = ManualSeriesMatcher() def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data, pattern, trusted_keys)

class MovieEngine(ClassificationEngine): def __init__(self): self.matcher = MovieMatcher() def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(subscription, data)

Page 40: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Factory

Page 41: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): matcher_class = None def __init__(self, matcher=None): self.matcher = (matcher if matcher else self.matcher_class())

class SeriesEngine(ClassificationEngine): matcher_class = SeriesMatcher def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data)

class ManualSeriesEngine(ClassificationEngine): matcher_class = ManualSeriesMatcher def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data, pattern, trusted_keys)

class MovieEngine(object): matcher_class = MovieMatcher def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(subscription, data)

Page 42: Wzorce projektowe - architektura dużych aplikacji w Pythonie

MatcherFactorySeries FactoryNicer Factory

Page 43: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): def __init__(self, matcher=None): self.matcher = self.get_matcher()

class SeriesEngine(ClassificationEngine): def get_matcher(self): return SeriesMatcher() def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data)

class ManualSeriesEngine(ClassificationEngine): def get_matcher(self): return SeriesMatcher(defaults=settings.TRUSTED_KEYS) def match(self, subscription, data, pattern, trusted_keys): return self.matcher.match(data, pattern, trusted_keys)

class MovieEngine(object): def get_matcher(self): return MovieMatcher() def match(self, subscription, data): return self.matcher.match(subscription, data)

Page 44: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Template Method

Page 45: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): # ... def classify(self, subscription, subscription_data, data): preprocessed_data = self.preprocess(subscription, data) filtered_data = self.filter(subscription, preprocessed_data) matched_data = self.match(subscription, subscription_data, filtered_data)) classified_data = self.merge(subscription, matched_data) postprocessed_data = self.postprocess(subscription, classified_data) return postprocessed_data

Page 46: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): # ... def classify(self, subscription, subscription_data, data, timer): with timer.label('preprocess'): preprocessed_data = self.preprocess(subscription, data) with timer.label('filter'): filtered_data = self.filter(subscription, preprocessed_data) with timer.label('match'): matched_data = self.match(subscription, subscription_data, filtered_data)) with timer.label('merge'): classified_data = self.merge(subscription, matched_data, extra_priorities) with timer.label('postprocess'): postprocessed_data = self.postprocess(subscription, classified_data) return postprocessed_data

Page 47: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Class-based generic views

Page 48: Wzorce projektowe - architektura dużych aplikacji w Pythonie

+label(1)+dump(0)

AbstractTimer

+label(1)+dump(0)

Timer+label(1)+dump(0)

DummyTimer

Client

Do nothing

Null Object

Page 49: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class Timer(object): def __init__(self, identifier=None): self.identifier, register = identifier, {}

@contextmanager def label(self, label): t0 = time.time() yield t1 = time.time() self.register[label] = t1 - t0

def dump(self): r = dict(self.register) if self.identifier: r['_identifier'] = self.identifier return r

class DummyTimer(Timer): def label(self, label): yield def dump(self): return {'_identifier': '<DummyTimer>'}

Page 50: Wzorce projektowe - architektura dużych aplikacji w Pythonie

class ClassificationEngine(object): # ... def classify(self, subscription, subscription_data, data, timer=None): if timer is None: timer = DummyTimer()

with timer.label('preprocess'): preprocessed_data = self.preprocess(subscription, data) with timer.label('filter'): filtered_data = self.filter(subscription, preprocessed_data) with timer.label('match'): matched_data = self.match(subscription, subscription_data, filtered_data)) with timer.label('merge'): classified_data = self.merge(subscription, matched_data, extra_priorities) with timer.label('postprocess'): postprocessed_data = self.postprocess(subscription, classified_data) return postprocessed_data

Page 51: Wzorce projektowe - architektura dużych aplikacji w Pythonie

+run(1)+runAll(0)

HarvesterCommand

DisneyHarvester

AmazonHarvester

CrackleHarvester

NetflixHarvester

ITunesHarvester

Page 52: Wzorce projektowe - architektura dużych aplikacji w Pythonie

def get_class(path): module_path, class_name = path.rsplit('.', 1) package_path = ([module_path.rsplit('.', 1)[0]] if '.' in module_path else None) module = __import__(module_path, fromlist=package_path) return getattr(module, class_name)

# settings.pyHARVESTERS = ( 'harvesters.disney_harvester.harvester.DisneyHarvester', 'harvesters.amazon_harvester.harvester.AmazonHarvester', 'harvesters.crackle_harvester.harvester.CrackleHarvester', 'harvesters.netflix_harvester.harvester.NetflixHarvester', 'harvesters.itunes_harvester.harvester.ITunesHarvester')

Plugin

Page 53: Wzorce projektowe - architektura dużych aplikacji w Pythonie

admin.site.register(MyModel, MyModelAdmin)

Page 54: Wzorce projektowe - architektura dużych aplikacji w Pythonie

def check_and_fixup_data(new_data, old_data, fixup_func=fixup_data, flagging_func=flag_data): is_worse, report = flagging_func(old_data, new_data)

if is_worse: new_data = fixup_func(new_data, old_data) is_worse, report = flagging_func(old_data, new_data)

return (is_worse, new_data, report)

Page 55: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Strategy

Page 56: Wzorce projektowe - architektura dużych aplikacji w Pythonie

sorted(iterable)

Page 57: Wzorce projektowe - architektura dużych aplikacji w Pythonie

sorted(iterable, cmp=None, key=None, reverse=False)

Page 58: Wzorce projektowe - architektura dużych aplikacji w Pythonie

+notify(*)Observer

+notify(*)ObserverA

+notify(*)ObserverB

notifyObservers(*) for observer in observerCollection: observer.notify(*)

+registerObserver(1)+unregisterObserver(1)+notifyObservers(*)

observerCollectionObservable

Observer

Page 60: Wzorce projektowe - architektura dużych aplikacji w Pythonie

State

Page 61: Wzorce projektowe - architektura dużych aplikacji w Pythonie

var Post = function (text, state) { this.initialize(text, state);};

_.extend(Post.prototype, { initialize: function (text, state) { this.text = text; this.state = state; }, getMaxCharacterCount: function () { this.state.getMaxCharacterCount(); }, getCharacterCount: function (text) { this.state.getCharacterCount(text); }});

Page 62: Wzorce projektowe - architektura dużych aplikacji w Pythonie

var FacebookBehavior = function () {};_.extend(FacebookBehavior.prototype, { getMaxCharacterCount: function () { return 450; }, getCharacterCount: function (text) { return text.length; }});

CH20 = 'xxxxxxxxxxxxxxxxxxxx';var TwitterBehavior = function () {};_.extend(TwitterBehavior.prototype, { getMaxCharacterCount: function () { return 140; }, getCharacterCount: function (text) { return text.replace(URL_REGEXP, CH20).length; }});

Page 63: Wzorce projektowe - architektura dużych aplikacji w Pythonie

My God! It’s full of patterns!

Page 64: Wzorce projektowe - architektura dużych aplikacji w Pythonie

A B

Page 65: Wzorce projektowe - architektura dużych aplikacji w Pythonie

A B

Page 66: Wzorce projektowe - architektura dużych aplikacji w Pythonie

A BC

Page 67: Wzorce projektowe - architektura dużych aplikacji w Pythonie

A BC

Page 68: Wzorce projektowe - architektura dużych aplikacji w Pythonie

A BC

Page 69: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Patternitis

Page 70: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Architektura aplikacji

Page 71: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

Page 72: Wzorce projektowe - architektura dużych aplikacji w Pythonie

No silver bullet!

Page 73: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

Page 74: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

+ TDD

Page 75: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

+ TDD

+ Seams Michael Feathers,

Working Effectively with Legacy Code

Page 76: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe

+ TDD

+ Seams Michael Feathers,

Working Effectively with Legacy Code

+ druga para oczu

Page 77: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Wzorce projektowe+ TDD

+ Seams Michael Feathers,

Working Effectively with Legacy Code

+ druga para oczu + trzecia para oczu

Page 78: Wzorce projektowe - architektura dużych aplikacji w Pythonie

I jakoś to idzie!

Page 79: Wzorce projektowe - architektura dużych aplikacji w Pythonie

Marek Stępniowskihttp://stepniowski.com

@mstepniowski