Top Banner
An Introduction of Interator Pattern with Ruby @ ConFoo Montreal 2018-03-07 by Jian Weihang An Introduction of Interator Pattern in Ruby 1
69

An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Oct 13, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction ofInterator Pattern with

Ruby@ ConFoo Montreal 2018-03-07

by Jian Weihang

An Introduction of Interator Pattern in Ruby 1

Page 2: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Bonjour!An Introduction of Interator Pattern in Ruby 2

Page 3: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

墋簏膠Jian Weihang

An Introduction of Interator Pattern in Ruby 3

Page 4: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

@tonytonyjan

An Introduction of Interator Pattern in Ruby 4

Page 5: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Taiwan

An Introduction of Interator Pattern in Ruby 5

Page 6: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in Ruby 6

Page 7: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in Ruby 7

Page 8: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in Ruby 8

Page 9: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

$ gem install taiwan

An Introduction of Interator Pattern in Ruby 9

Page 10: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Tech Leader

An Introduction of Interator Pattern in Ruby 10

Page 11: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Ruby Developersince 2010

An Introduction of Interator Pattern in Ruby 11

Page 12: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Maintainerof exif and jaro_winkler

An Introduction of Interator Pattern in Ruby 12

Page 13: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Published a bookin 2015

An Introduction of Interator Pattern in Ruby 13

Page 14: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in

Ruby

An Introduction of Interator Pattern in Ruby 14

Page 15: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Outline

An Introduction of Interator Pattern in Ruby 15

Page 16: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in Ruby 16

Page 17: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

!̴̴

An Introduction of Interator Pattern in Ruby 17

Page 18: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

An Introduction of Interator Pattern in Ruby 18

Page 19: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

How to Help Controllers Lose

Weight?

An Introduction of Interator Pattern in Ruby 19

Page 20: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

The Controller Is a Translator

An Introduction of Interator Pattern in Ruby 20

Page 21: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Good Practiceclass PostsController < ApplicationController def create @post = Post.create(post_params) redirect_to @post rescue render :new endend

An Introduction of Interator Pattern in Ruby 21

Page 22: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Bad Practiceclass PostsController < ApplicationController def create @post = Post.create(post_params) @post.send_notification redirect_to @post rescue render :new endend

An Introduction of Interator Pattern in Ruby 22

Page 23: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

!̴̴

An Introduction of Interator Pattern in Ruby 23

Page 24: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Fat Models andSkinny Controllers

An Introduction of Interator Pattern in Ruby 24

Page 25: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Single Responsibility Principle

An Introduction of Interator Pattern in Ruby 25

Page 26: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

# Rails 5.1.5class Post < ActiveRecord::Baseend

Post.new.public_methods.size # => 404

An Introduction of Interator Pattern in Ruby 26

Page 27: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

class AlmightyGod < ActiveRecord::Base # hundreds of methodsend

An Introduction of Interator Pattern in Ruby 27

Page 28: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

class Cart < ApplicationModel def add_product(product) endend

vs.class Product < ApplicationModel def add_to_cart(cart) endend

An Introduction of Interator Pattern in Ruby 28

Page 29: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

class Course def add_student(student) endend

vs.class Student def join_course(course) endend

An Introduction of Interator Pattern in Ruby 29

Page 30: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

!̴̴

An Introduction of Interator Pattern in Ruby 30

Page 31: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model is neither a class nor object.

An Introduction of Interator Pattern in Ruby 31

Page 32: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model is a layer.

An Introduction of Interator Pattern in Ruby 32

Page 33: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Separation of Concerns• Presentation Layer

• views

• controllers

• Model Layer

• models

An Introduction of Interator Pattern in Ruby 33

Page 34: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model Layer

• Domain Objects

• Storage Abstractions

• Services

An Introduction of Interator Pattern in Ruby 34

Page 35: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model Layer

• Domain Objects

• Storage Abstractions

• Services

An Introduction of Interator Pattern in Ruby 35

Page 36: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model Layer

• Domain Objects

• Storage Abstractions

• Services

An Introduction of Interator Pattern in Ruby 36

Page 37: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model Layer

• Domain Objects

• Storage Abstractions

• Services

An Introduction of Interator Pattern in Ruby 37

Page 38: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Model Layer• ActiveRecord::Base

• Domain Objects

• Storage Abstractions

• Services

• ???

An Introduction of Interator Pattern in Ruby 38

Page 39: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

What about the Implementation

!

An Introduction of Interator Pattern in Ruby 39

Page 40: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Service Object• a.k.a.

• Interactor

• Use Case

An Introduction of Interator Pattern in Ruby 40

Page 41: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Clean Architecture

https://goo.gl/ihgHGBAn Introduction of Interator Pattern in Ruby 41

Page 42: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Minimal Implementation# app/{services|interactors|use_cases}class AddToCart attr_reader :errors

def initialize(cart, product) @cart, @product = cart, product @errors = [] end

def perform # manipulate @cart, @product and @errors ... end

def success?; @errors.empty? endend

An Introduction of Interator Pattern in Ruby 42

Page 43: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Usageclass CartController < ApplicationController def add_to_cart product = Product.find(params[:product_id]) add_to_cart = AddToCart.new(current_cart, product) add_to_cart.perform if add_to_cart.successs? # ... else # ... end endend

An Introduction of Interator Pattern in Ruby 43

Page 44: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Advantages• Skinny Controller

• Easier to Trace Code

• Easier to Write Test

An Introduction of Interator Pattern in Ruby 44

Page 45: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Advantages• Skinny Controller

• Easier to Trace Code

• Easier to Write Test

An Introduction of Interator Pattern in Ruby 45

Page 46: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Advantages• Skinny Controller

• Easier to Trace Code

• Easier to Write Test

An Introduction of Interator Pattern in Ruby 46

Page 47: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Advantages• Skinny Controller

• Easier to Trace Code

• Easier to Write Test

An Introduction of Interator Pattern in Ruby 47

Page 48: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

class AddToCart def initialize(cart, product) @cart, @product = cart, product end

def perform @cart.line_items.push(@product) endend

An Introduction of Interator Pattern in Ruby 48

Page 49: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

gem 'rspec-mocks'

describe AddToCart it 'works' do line_items = double('line_items') cart = double('cart', line_items: line_items) product = double('product')

expect(line_items).to receive(:push).once { product } # expect cart.line_items.push(product)

add_to_cart = AddToCart.new(cart, product) add_to_cart.perform endend

An Introduction of Interator Pattern in Ruby 49

Page 50: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Abstractionclass Interactor attr_reader :errors

def self.perform(*args) new(*args).tap { |interactor| interactor.perform } end

def perform raise NotImplementedError end

def success? @errors.empty? endend

An Introduction of Interator Pattern in Ruby 50

Page 51: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Usageclass AddToCart < Interactor def initialize(cart, product) @cart = cart @product = product end

def perform # logic here. endend

An Introduction of Interator Pattern in Ruby 51

Page 52: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Usageclass CartController < ApplicationController def add_to_cart product = Product.find(params[:product_id]) add_to_cart = AddToCart.perform(current_cart, product) if add_to_cart.successs? # ... else # ... end endend

An Introduction of Interator Pattern in Ruby 52

Page 53: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

!̴̴

An Introduction of Interator Pattern in Ruby 53

Page 54: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Third-party Gems

An Introduction of Interator Pattern in Ruby 54

Page 55: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

gem "mutations"class UserSignup < Mutations::Command required do string :email, matches: EMAIL_REGEX string :name end

optional do boolean :newsletter_subscribe end

def execute # logic endend

UserSignup.run(params[:user])

An Introduction of Interator Pattern in Ruby 55

Page 56: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

gem "interactor"class AuthenticateUser include Interactor

def call if user = User.authenticate(context.email, context.password) context.user = user context.token = user.secret_token else context.fail!(message: "authenticate_user.failure") end endend

AuthenticateUser.call(params)

An Introduction of Interator Pattern in Ruby 56

Page 57: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

FYI

name stars forks issues closed

mutation 1,127 69 54 79%

interactor 1,919 110 76 87%

An Introduction of Interator Pattern in Ruby 57

Page 58: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

gem "interactor2"class AddToCart < Interactor2 attr_reader :line_item, :cart # should be any attribute you want to expose

def initialize(product, cart) @cart = cart @line_item = cart.line_items.new(product: product) end

def perform unless @line_item.save fail! 'oops' end endend

An Introduction of Interator Pattern in Ruby 58

Page 59: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

gem "interactor2"class AddToCart < Interactor2 include ActiveModel::Validations attr_reader :line_item, :cart # should be any attribute you want to expose

validates :product, :cart, presence: true

def initialize(product, cart) @cart = cart @line_item = cart.line_items.new(product: product) end

def perform unless @line_item.save fail! 'oops' end endend

An Introduction of Interator Pattern in Ruby 59

Page 60: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

https://github.com/tonytonyjan/interactor2/

An Introduction of Interator Pattern in Ruby 60

Page 61: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Conclusion• Consistent Interface

• Self-explaining

• Context Encapsulation

• Decoupling your domain from your framework

An Introduction of Interator Pattern in Ruby 61

Page 62: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Conclusion• Consistent Interface

• Self-explaining

• Context Encapsulation

• Decoupling your domain from your framework

An Introduction of Interator Pattern in Ruby 62

Page 63: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Conclusion• Consistent Interface

• Self-explaining

• Context Encapsulation

• Decoupling your domain from your framework

An Introduction of Interator Pattern in Ruby 63

Page 64: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Conclusion• Consistent Interface

• Self-explaining

• Context Encapsulation

• Decoupling your domain from your framework

An Introduction of Interator Pattern in Ruby 64

Page 65: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Conclusion• Consistent Interface

• Self-explaining

• Context Encapsulation

• Decoupling your domain from your framework

An Introduction of Interator Pattern in Ruby 65

Page 66: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Thanks for Your Listening@tonytonyjan

An Introduction of Interator Pattern in Ruby 66

Page 67: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

References• https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-

architecture.html

• https://www.wikiwand.com/en/Domain-driven_design

• https://github.com/cypriss/mutations

• https://github.com/collectiveidea/interactor

• https://github.com/tonytonyjan/interactor2

An Introduction of Interator Pattern in Ruby 67

Page 68: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Q&A

An Introduction of Interator Pattern in Ruby 68

Page 69: An Introduction of Interator Pattern with Ruby...An Introduction of Interator Pattern in Ruby 22 4 4! An Introduction of Interator Pattern in Ruby 23. Fat Models and ... An Introduction

Entity-Boundary-Interactor

An Introduction of Interator Pattern in Ruby 69