37
Anton Shemerey @shemerey Single Responsibility Principle в Руби чему instance/class variables это ОЧЕН

Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

  • Upload
    -

  • View
    298

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Anton Shemerey@shemerey

Single Responsibility Principle в Руби или почему instance/class variables это ОЧЕНЬ плохо

Page 2: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

each object should have one and

only one responsibility

Page 3: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear Anton Shemerey.

Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.

Shipping books at the book rate generally slows delivery. As you know, paymentin full ($20.75) is due by the end of the month.

Thank you for doing business with Doe. We look forward to serving you again.If you have questions regarding the new pricing please contact support.

--

Sincerely yours, John PeterDoe Books

720 S Michigan AveChicago, IL, United States+1 312-922-4400

Order Confirmation Page

Page 4: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. Anton Shemerey

Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.

Shipping books at the book rate generally slows delivery. As you know, paymentin full ($20.75) is due by the end of the month.

Thank you for doing business with Doe Books. We look forward to serving you again.If you have questions regarding the new pricing please contact support.

--

Sincerely yours, John PeterDoe Books

720 S Michigan AveChicago, IL, United States+1 312-922-4400

Order Confirmation Page variables

Page 5: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. {%user_full_name%}

Thank you for your patronage. This letter is to confirm that your order from{%company_name%} has been filled and should arrive within {%delivery_time%}.

Shipping books at the book rate generally slows delivery. As you know, paymentin full ({%order_total%}) is due by the end of the month.

Thank you for doing business with {%company_name%}. We look forward to serving you again. If you have questions regarding the {%price_url%} please contact {%support_email%}.

--

Sincerely yours, {%owner_name%}{%company_name%}

{%company_address%}

Order Confirmation Template

Page 6: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Data we have :(

• current_user.full_name #=> ‘Anton Shemerey’

• @order.estimated_delivery #=> ’15 days’

• @order.total #=> ‘<Money: @cents = 2075 ….’

• COMPANY_NAME #=> ‘Doe Books’

• $owner.full_name #=> ‘John Peter’

• @pricing_link #=> ‘http://example.com/price'

• $support_email = ‘[email protected]

• @@company_address #=> ‘720 S Michigan Ave Chicago….’

Page 7: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Facepalm

Page 8: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. <%= current_user.full_name %>

Thank you for your patronage. This letter is to confirm that your order from<%= COMPANY_NAME %> has been filled and should arrive within <%= @order.estimated_delivery%>.

Shipping books at the book rate generally slows delivery. As you know, paymentin full (<%= number_to_currency(@order.total) %>) is due by the end of the month.

Thank you for doing business with <%= COMPANY_NAME %>. We look forward to serving you again. If you have questions regarding the <%= @pricing_link %> please contact <%= email_to(“Support”, $support_email) %>.

--

Sincerely yours, <%= $owner.full_name %><%= COMPANY_NAME %>

<%= @@company_address %>

Order Confirmation Template

Page 9: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

THE Controller :)

class OrdersController < ApplicationController .... def confirmation @order = Order.find(params[:id]) end ....end

Page 10: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»
Page 11: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. <%= current_user.full_name %>

Thank you for your patronage. This letter is to confirm that your order from<%= COMPANY_NAME %> has been filled and should arrive within <%= @order.estimated_delivery%>.

Shipping books at the book rate generally slows delivery. As you know, paymentin full (<%= number_to_currency(@order.total) %>) is due by the end of the month.

Thank you for doing business with <%= COMPANY_NAME %>. We look forward to serving you again. If you have questions regarding the <%= @pricing_link %> please contact <%= email_to(“Support”, $support_email) %>.

--

Sincerely yours, <%= $owner.full_name %><%= COMPANY_NAME %>

<%= @@company_address %>

Order Confirmation Template

Page 12: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. <%= @current_user_full_name %>

Thank you for your patronage. This letter is to confirm that your order from<%= @company_name %> has been filled and should arrive within <%= @estimated_delivery_time %>.

Shipping books at the book rate generally slows delivery. As you know, paymentin full (<%= number_to_currency(@order_total) %>) is due by the end of the month.

Thank you for doing business with <%= @company_name %>. We look forward to serving you again. If you have questions regarding the <%= link_to(‘price’, @pricing_link) %> please contact <%= email_to(“Support”, @support_email) %>.

--

Sincerely yours, <%= @owner_full_name %><%= @company_name %>

<%= @company_address %>

Order Confirmation Template Second Attempt

Page 13: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

THE Controller :)class OrdersController < ApplicationController .... def confirmation @order = Order.find(params[:id]) @current_user_full_name = current_user.full_name @company_name = COMPANY_NAME @estimated_delivery_time = @order.estimated_delivery @order_total = @order.total @pricing_link = 'http://example.com/price' @support_email = '[email protected]' @owner_full_name = $owner.full_name @company_address = @@company_address end ....end

Second Attempt

Page 14: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»
Page 15: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. Anton Shemerey

Thank you for your patronage. This letter is to confirm that your order fromDoe Books has been filled and should arrive within 15 days.

Shipping books at the book rate generally slows delivery. As you know, paymentin full ($0) is due by the end of the month.

Thank you for doing business with Doe Books. We look forward to serving you again. If you have questions regarding the new pricing please contact support.

--

Sincerely yours, John PeterDoe Books

720 S Michigan AveChicago, IL, United States+1 312-922-4400

Free Order !!!!

Page 16: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Five sec to fix ;-)

Page 17: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

class OrdersController < ApplicationController # .... def confirmation @order = Order.find(params[:id]) @current_user_full_name = current_user.full_name @company_name = COMPANY_NAME @estimated_delivery_time = @order.estimated_delivery @order_total = @order.total

@pricing_link = 'http://example.com/price' @support_email = '[email protected]' @owner_full_name = $owner.full_name @company_address = @@company_address end # ....end

binding.pry

require 'pry'; binding.pry

Page 18: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

2.0.0-p353 :006 > @order_total => #<Money:0x007fc7afb23530 @cents=83991, @currency="USD", @bank=#<Money::VariableExchangeBank:0x007fc7a36415c8 @rates={}, @mutex=#<Mutex:0x007fc7a3641528>>>

WTF ?!?!?!?!

Page 19: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»
Page 20: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

Dear. <%= @current_user_full_name %>

Thank you for your patronage. This letter is to confirm that your order from<%= @company_name %> has been filled and should arrive within <%= @estimated_delivery_time %>.

Shipping books at the book rate generally slows delivery. As you know, paymentin full (<%= number_to_currency(@order_total) %>) is due by the end of the month.

Thank you for doing business with <%= @company_name %>. We look forward to serving you again. If you have questions regarding the <%= link_to(‘price’, @pricing_link) %> please contact <%= email_to(“Support”, @support_email) %>.

--

Sincerely yours, <%= @owner_full_name %><%= @company_name %>

<%= @company_address %>

Order Confirmation Template binding.pry

<%- require 'pry'; binding.pry %>

Page 21: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

2.0.0-p353 :0016 > @order_total => #<Money:0x007fc7afb23530 @cents=0, @currency="USD", @bank=#<Money::VariableExchangeBank:0x007fc7a36415c8 @rates={}, @mutex=#<Mutex:0x007fc7a3641528>>>

WTF ?!?!?!?!

Page 22: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

GREP!!!

$ grep -iRn @order_total app | wc

#=> 151 1017 17348

Page 23: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

How are rails instance variables passed to

views?????

Page 24: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

AbstractController::Rendering#view_assigns

module AbstractController module Rendering # .... # This method should return a hash with assigns. # You can overwrite this configuration per controller. # :api: public def view_assigns protected_vars = _protected_ivars variables = instance_variables

variables.reject! { |s| protected_vars.include? s } variables.each_with_object({}) { |name, hash| hash[name.slice(1, name.length)] = instance_variable_get(name) } end # .... endend

Page 25: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

module AbstractController def view_context view_context_class.new(

view_renderer, view_assigns, self) endend

AbstractController#view_context

Page 26: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»
Page 27: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

GREP!!!$ grep -iRn @order_total app/helpers | wc

#=> 2 8 143

Second Attempt

module ApplicationHelper .... def current_cart_total if current_user if order = current_user.current_order @order_total = order.total end else @order_total = Money.new(0) end end ....end

Page 28: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

$ git blame | grep current_cart_total

Problem Fixed!

Page 29: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

class OrdersController < ApplicationController before_action :load_order, only: [:show, :update, :destroy]

def update if @order.update_attributes(params[:order]) redirect_to :show else render 'edit' end end

private

def load_order @order = Order.find(params[:id]) endend

Controller.before_action

Page 30: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

class OrdersController < ApplicationController .... def order @order ||= Order.find(params[:id]) end ....end

Memoization

Page 31: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

class OrdersController < ApplicationController helper_method :order

def update if order.update_attributes(params[:order]) redirect_to :show else render 'edit' end end

private

def order @_order ||= Order.find(params[:id]) endend

Controller.helper_method

Page 32: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

• memoization / lazy loading

• encapsulating (getter, setter)

• barewords (method, local variable, helper_method, ….)

Page 33: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

#source_location, caller

def total_order stack = caller require 'pry'; binding.pry ...end

<% self.method(:total_order).source_location %>

Page 34: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

one action one @

• PRESENTER

• SERVICE OBJECT

• PROXY OBJECT

• VALUE OBJECT

• LOCALS

• HELPER_METHOD

You can always use following

Page 35: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»
Page 36: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

#destroy_all_view_assigns

group :development, :test do gem 'destroy_all_view_assigns'end

Page 37: Антон Шемерей «Single responsibility principle в руби или почему instanceclass variables это очень плохо»

https://github.com/shemerey/destroy_all_view_assigns

https://github.com/shemerey

https://www.facebook.com/shemerey

https://twitter.com/shemerey

https://www.linkedin.com/in/shemerey

Questions ???