SlideShare ist ein Scribd-Unternehmen logo
1 von 125
Downloaden Sie, um offline zu lesen
從 Classes 到 Objects:
那些 OOP 教我的事
http://ihower.tw
2013/10/26@ RubyConf China
我是誰
• 張⽂文鈿 a.k.a. ihower
• http://ihower.tw
• 來⾃自台灣
Ruby Taiwan
http://ruby.tw
RubyConf Taiwan
2013/4/25-26
Agenda
•
•
•

•

OOP
class-oriented
object-oriented

•
•
•

Role-oriented
Context-oriented
DCI

Conclusion
Object = Identity
+ Behavior
+ State
Identity
a = "foo"
b = "foo"
a.object_id # 70178176631620
b.object_id # 70178176659140
a == b # true
a.equal?(b) # false
Behavior
"foo".methods =>
[:<=>, :==, :===, :eql?, :hash,
:casecmp, :+, :*, :%, :[], :
[]=, :insert, :length, :size,
:bytesize, :empty?, :=~, :match, :succ,
:succ!, :next, :next!, :upto, :index,
:rindex, :replace, :clear, :chr,
:getbyte, :setbyte, :byteslice, :to_i,
:to_f, :to_s, :to_str, :inspect, :dump,
:upcase, :downcase, :capitalize,
:swapcase, :upcase!, :downcase!,
:capitalize!, :swapcase!, :hex, :oct,
State
class Person
def name
@name
end
def name=(name)
@name = name
end
end
State (cont.)
a = Person.new
b = Person.new
a.name = "Foo"
b.name = "Bar"
class Person
attr_accessor :name
end
封裝 Encapsulation
• 物件的 State 狀態被封裝起來
• 必須透過外在的 Behavior,也就是
Method ⽅方法來存取操作
多型 Polymorphism
• Duck-typing in Ruby
• 不管物件的類型,只要有相同的介⾯面,
就可以呼叫使⽤用
class Org
attr_accessor :name
end
[Person.new, Org.new].each do |p|
puts p.name
end
OOP = objects
+ messages
Sending Message
就是呼叫物件的⽅方法

person
呼叫 name ⽅方法

內部狀態
@name
runtime picture
obj
obj

obj

obj
obj
obj

obj
obj
class-oriented design?
class-based OOP
class-based OOP
• 物件需要⼀一種⽅方式可以⽅方便⽣生成
class-based OOP
• 物件需要⼀一種⽅方式可以⽅方便⽣生成
• 絕⼤大部分的 OO 程式語⾔言都⽀支援 class-based
class-based OOP
• 物件需要⼀一種⽅方式可以⽅方便⽣生成
• 絕⼤大部分的 OO 程式語⾔言都⽀支援 class-based
• 是 Object 的 template 樣板
class-based OOP
• 物件需要⼀一種⽅方式可以⽅方便⽣生成
• 絕⼤大部分的 OO 程式語⾔言都⽀支援 class-based
• 是 Object 的 template 樣板
• 是 Object 的 factory ⼯工廠
class-oriented?
class-oriented?
• 使⽤用 class 概念來設計整個系統
class-oriented?
• 使⽤用 class 概念來設計整個系統
• 找出系統的 nouns,以資料為中⼼心,將物
件⽤用類別進⾏行分類 (Data-centric)
class-oriented?
• 使⽤用 class 概念來設計整個系統
• 找出系統的 nouns,以資料為中⼼心,將物
件⽤用類別進⾏行分類 (Data-centric)

• 愛⽤用繼承架構
class-oriented?
• 使⽤用 class 概念來設計整個系統
• 找出系統的 nouns,以資料為中⼼心,將物
件⽤用類別進⾏行分類 (Data-centric)

• 愛⽤用繼承架構
• 最後得到系統的 static representation
A static class diagram
Data-centric
• 例如,⼀一個 e-commerce 系統:
• Product
• Invoice
• User
• 將需要的⽅方法定義在每個類別上
A Product model
class Product
validates_presence_of :name
end
不斷加⽅方法進來
class Product
validates_presence_of :name
def add_to_billing(billing)
billing.items << self
end
end
A fat Product model
class Product
validates_presence_of :name, :price
def add_to_billing(order)
order.items << self
end
def tag(name)
#...
end
def self.export
#...
end
def sales_report
#...
end
你以為很多物件在互動
obj
obj

obj

obj
obj
obj

obj
obj
其實只有少數幾種物件
User

Product

Invoice
三種類型的物件
class Product
def A
def B
def C
...
...
...
...
...
end

class Invoice
def X
def Y
def Z
...
...
...
...
...
end

class User
def Q
def W
def E
...
...
...
...
...
end
最後變成
萬能的 God Object!
What’s more
Object-oriented?
如何能更善⽤用 Object?
是什麼 v.s. 做什麼
是什麼 v.s. 做什麼
• ⼀一個物件”是什麼” (Being) 跟作什麼
(Doing) 是分開的概念
是什麼 v.s. 做什麼
• ⼀一個物件”是什麼” (Being) 跟作什麼
(Doing) 是分開的概念

• ⼀一個物件需要有什麼⽅方法,跟當時的⾓角
⾊色和情境有關係
是什麼 v.s. 做什麼
• ⼀一個物件”是什麼” (Being) 跟作什麼
(Doing) 是分開的概念

• ⼀一個物件需要有什麼⽅方法,跟當時的⾓角
⾊色和情境有關係

• Responsibility-centric 以職責為中⼼心,將
物件進⾏行分類
1. 根據 Roles 來區分
物件可以做什麼
def work
end
def rest
end
def approve
end
def review
end
person
Roles:
Employee

def work
end
def rest
end
def approve
end
def review
end
def work
end
def rest
end

person
Roles:
Manager

def approve
end
def review
end
Role-oriented
• 不同⾓角⾊色有不同責任,需要的⽅方法也就
不同

• ⽤用單⼀一繼承⾏行不通的,⼀一個物件可能同
時有好幾個⾓角⾊色
def buy
end
def complain
end
def approve
end
def review
end

Role:
Customer

Role:
Manager
def buy
end

person
Roles:
Customer
Manager

def complain
end
def approve
end
def review
end

Role:
Customer

Role:
Manager
怎麼實作?
We represent roles as identifiers ... they [roles] may
just be pointers to role-bound object, or macros, or
function or something else.
- Lean Architecture p.240
⽅方法⼀一:
Composition
Object Composition
Object Composition
• ⼀一個物件裡包其他物件
Object Composition
• ⼀一個物件裡包其他物件
• 靜態程式語⾔言的唯⼀一選擇
Object Composition
• ⼀一個物件裡包其他物件
• 靜態程式語⾔言的唯⼀一選擇
• 眾多 Design Pattern
class Person
def initialize(role)
@role_behavior = role
end
def say
@role_behavior.say
end
end
class EmployeeRole
def say
puts "done!"
end
end
class ManagerRole
def say
puts "solid!"
end
end
Strategy Pattern!
p1 = Person.new(ManagerRole.new)
p2 = Person.new(EmployeeRole.new)
person

person

employee
role

manager
role
或是換個
組合⽅方向?
require 'delegate'
class Person
end
class EmployeeRole < SimpleDelegator
def say
puts "done!"
end
end
class ManagerRole < SimpleDelegator
def fly
puts "solid!"
end
end
require 'delegate'
class Person
end
class EmployeeRole < SimpleDelegator
def say
puts "done!"
end
end
class ManagerRole < SimpleDelegator
def fly
puts "solid!"
end
end
Decorator Pattern
p1 = EmployeeRole.new(Person.new)
p2 = ManagerRole.new(Person.new)
employee

manager

person

person
Strategy v.s. Decorator
Strategy v.s. Decorator
• Strategy Pattern
• 相同⽅方法,但是不同⾓角⾊色有不同演算
法時
Strategy v.s. Decorator
• Strategy Pattern
• 相同⽅方法,但是不同⾓角⾊色有不同演算
法時

• Decorator Pattern
• 當你想新增物件的⾓角⾊色⾏行為時
Object Composition
• Composition 很強⼤大
• 但是也可以搞的很複雜,特別是參數和
狀態如何在物件之間流通....
⽅方法⼆二:
Mixin
A Product model
class Product
validates_presence_of :name
def add_to_billing(billing)
billing.items << self
end
end
Orderable Role
module Billingable
def add_to_billing(billing)
billing.items << self
end
end
class Product
validates_presence_of :name
include Billingable
end
class Product
validates_presence_of :name
include
include
include
include
end

Billingable
Taggable
Exporter
Reporter
Rails4
• app/models/concerns
• app/controllers/concerns
批評
• 只是 copy-paste ⽽而已
• module 本質上還是繼承 inheritance,不
若 composition 容易替換
Poor man’s
role-oriented design
Simple, Quick and Dirty
是什麼 v.s. 做什麼
• ⼀一個物件”是什麼” (Being) 跟作什麼
(Doing) 是分開的概念

• ⼀一個物件需要有什麼⽅方法,跟當時的⾓角
⾊色和情境有關係

• Responsibility-centric 以職責為中⼼心,將
物件進⾏行分類
2. 根據情境來區分
物件可以做什麼
def buy
end
def complain
end
def approve
end
def review
end
def buy
end
def complain
end
def approve
end
def review
end

購物情境
才需要
def buy
end
def complain
end
def approve
end
def review
end

客服情境
才需要
Use case
• 不同的 User case 特定情境,物件需要的
⽅方法不⼀一樣

• 例如註冊流程、購物流程
怎麼實作?
還是 Composition
⽽而且有很多種 Patterns
• Service object
• Query object
• Form object
• View object
• Policy object
• ....根據情境分類....
Service Object
a.k.a. Command Pattern
包裝跨 Data Model 的操作

class BillingControllers < ApplicationController
before_filter :find_current_billing
def add_product
@product = Product.find(params[:product_id])
BillingService.new(@billing, @product).perform!
end
end
Service Object
class BillingService
def initialize(billling, product)
@billling = billling
@product = product
end
def perform!
add_product_to_billling(@billling, @product)
end
private
def add_product_to_billling(billling, product)
billling.items << product
end
end
Query Object
包裝複雜的 SQL 查詢

class ProductQuery
def initialize(relation = Product.scoped)
@relation = relation
end
def by_regions(region_ids = nil)
if region_ids.present?
countrys = RegionCountry.where(:region_id =>
region_ids).pluck(:country_alpha2)
@relation = @relation.where(:country => countrys)
end
self
end
end
@products = ProductQuery.new.by_regions(region_ids)
View Object
包裹給 Rails View 使⽤用

class DashboardView
def initialize(company)
@company = company
end
def arr
#...
end
def mrr
#...
end
def cac
#...
end
end
Form Object
搭配 Rails 的表單

class Signup
include Virtus
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
attr_reader :user
attr_reader :company
attribute :name, String
attribute :company_name, String
attribute :email, String
validates :email, presence: true
# … more validations …
# Forms are never themselves persisted
def persisted?
false
end
def save
if valid?
persist!
true
else
false
end
end
class SignupsController < ApplicationController
def create
@signup = Signup.new(params[:signup])
if @signup.save
redirect_to dashboard_path
else
render "new"
end
end
end
增加物件的多樣性
避免肥⼤大的類別
obj
obj

obj

obj
obj
obj

obj
obj
DCI
⾓角⾊色+情境
將 Behavior 跟 Data model 分開的更徹底
DCI
DCI
• Data: 資料
DCI
• Data: 資料
• 例如 Product
DCI
• Data: 資料
• 例如 Product
• Context: 情境
DCI
• Data: 資料
• 例如 Product
• Context: 情境
• 例如加⼊入購物⾞車這個 Use case
DCI
• Data: 資料
• 例如 Product
• Context: 情境
• 例如加⼊入購物⾞車這個 Use case
• Interaction: ⾏行為
DCI
• Data: 資料
• 例如 Product
• Context: 情境
• 例如加⼊入購物⾞車這個 Use case
• Interaction: ⾏行為
• 例如加⼊入購物⾞車這個⽅方法
呼叫⽅方式
class BillingControllers < ApplicationController
before_filter :find_current_billing
def add_product
@product = Product.find(params[:product_id])
BillingContext.new(@billing, @product).perform!
end
end
情境
class BillingContext
def initialize(billling, product)
@billling = billling
end
def perform!
@product.add_to_billling(@billling)
end
end
class Product < ActiveRecord::Base
# 注意,這裡不放 Behavior 了
end
Billingable Role
class BillingContext
module Billlingable
def add_to_billling(billling)
billling.items << self
end
end
end
class BillingContext
def initialize(billling, product)
@billling = billling
@product.extend(Billingable)
end
def perform!
@product.add_to_billling(@billling)
end
module Billlingable
def add_to_billling(billling)
billling.items << self
end
end
data model 的 behavior,
是 run-time 的時候,根據當時的需要
動態 extend 進去物件
compile-time
Product
class
沒有⾏行為

run-time
extend ⾏行為模組

Product
object
加上⾏行為
批評
⽤用 Wrapper ?
require 'delegate'
class BillingContext
def initialize(billling, product)
@billling = billling
@product = BillingableProduct.new(product)
end
def perform!
@product.add_to_billling(@billling)
end
class BilllingableProduct < SimpleDelegator
def add_to_billling(billling)
billling.items << __getobj__
end
end
end
self 精神分裂
http://en.wikipedia.org/wiki/Schizophrenia_(object-oriented_programming)

• __getobj__
• 多包⼀一層,物件的 identify 和 class 是不⼀一
樣的,需要處理資料傳遞和分享的問題

• 就算⾃自⼰己寫 Wrapper,也很⿇麻煩
• 更別提如果有兩個以上的 Roles
Benchmark
並沒有數量級的差距
0.4
0.3
0.2
0.1
0

inherited

mixin

wrapper

simple delegator

extend(DCI)

https://gist.github.com/ihower/7160400
結論
Conclusion
結論
結論
• 從 Data-Centric 到 Responsibility-centric
結論
• 從 Data-Centric 到 Responsibility-centric
• 物件的 Behavior 會因為⾓角⾊色和情境⽽而需求不

同,可以分開。⽽而不需要通通塞在 data model
上
結論 (cont.)
結論 (cont.)
•

在靜態語⾔言中,Composition 是唯⼀一解
結論 (cont.)
•
•

在靜態語⾔言中,Composition 是唯⼀一解
但是在 Ruby 中,善⽤用⼀一些技巧可以事半功倍

•
•

Mixins
DCI
結論 (cont.)
•
•
•

在靜態語⾔言中,Composition 是唯⼀一解
但是在 Ruby 中,善⽤用⼀一些技巧可以事半功倍

•
•

Mixins
DCI

因為 Ruby 把 class 當作 behavior 的容器,⽽而
不是死的 template,所以可以動態地修改⾏行
為
Reference:
•
•
•

Object-Oriented Programming: Objects over Classes (The ThoughtWorks Anthology 2)

•
•
•
•
•

http://mikepackdev.com/blog_posts/24-the-right-way-to-code-dci-in-ruby

•

http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecordmodels/

•

https://speakerdeck.com/stefanoverna/fat-models-must-die

Clean Ruby, Jim Gay
Rails Developers Should Take DCI Seriously http://gilesbowkett.blogspot.tw/2012/12/
rails-developers-should-take-dci.html
http://dci-in-ruby.info/
https://practicingruby.com/articles/responsibility-centric-vs-data-centric-design
http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns
http://blog.gemnasium.com/post/60091511603/casting-adding-behavior-to-objectswithout-using
謝謝!
歡迎參加明晚 Faria Systems 的
After Party

Weitere ähnliche Inhalte

Was ist angesagt?

Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型Justin Lin
 
Java SE 7 技術手冊投影片第 04 章 - 認識物件
Java SE 7 技術手冊投影片第 04 章 - 認識物件Java SE 7 技術手冊投影片第 04 章 - 認識物件
Java SE 7 技術手冊投影片第 04 章 - 認識物件Justin Lin
 
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出Java SE 7 技術手冊投影片第 10 章 - 輸入輸出
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出Justin Lin
 
Java SE 7 技術手冊投影片第 12 章 - 通用API
Java SE 7 技術手冊投影片第 12 章  - 通用APIJava SE 7 技術手冊投影片第 12 章  - 通用API
Java SE 7 技術手冊投影片第 12 章 - 通用APIJustin Lin
 
JS and NG - ntut iLab 2015/07/14
JS and NG - ntut iLab 2015/07/14JS and NG - ntut iLab 2015/07/14
JS and NG - ntut iLab 2015/07/14BO Hong LI
 
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註Justin Lin
 
Java SE 8 技術手冊第 5 章 - 物件封裝
Java SE 8 技術手冊第 5 章 - 物件封裝Java SE 8 技術手冊第 5 章 - 物件封裝
Java SE 8 技術手冊第 5 章 - 物件封裝Justin Lin
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascriptjay li
 
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试lydiafly
 
Java SE 8 技術手冊第 4 章 - 認識物件
Java SE 8 技術手冊第 4 章 - 認識物件Java SE 8 技術手冊第 4 章 - 認識物件
Java SE 8 技術手冊第 4 章 - 認識物件Justin Lin
 
Migrations 與 Schema 操作
Migrations 與 Schema 操作Migrations 與 Schema 操作
Migrations 與 Schema 操作Shengyou Fan
 
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Kris Mok
 
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJava SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJustin Lin
 
如何用JDK8實作一個小型的關聯式資料庫系統
如何用JDK8實作一個小型的關聯式資料庫系統如何用JDK8實作一個小型的關聯式資料庫系統
如何用JDK8實作一個小型的關聯式資料庫系統なおき きしだ
 
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDE
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDEJava SE 7 技術手冊投影片第 02 章 - 從JDK到IDE
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDEJustin Lin
 
建造与理解-用Python实现深度学习框架
建造与理解-用Python实现深度学习框架建造与理解-用Python实现深度学习框架
建造与理解-用Python实现深度学习框架ZhenChen57
 

Was ist angesagt? (20)

Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
 
Java SE 7 技術手冊投影片第 04 章 - 認識物件
Java SE 7 技術手冊投影片第 04 章 - 認識物件Java SE 7 技術手冊投影片第 04 章 - 認識物件
Java SE 7 技術手冊投影片第 04 章 - 認識物件
 
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出Java SE 7 技術手冊投影片第 10 章 - 輸入輸出
Java SE 7 技術手冊投影片第 10 章 - 輸入輸出
 
Java SE 7 技術手冊投影片第 12 章 - 通用API
Java SE 7 技術手冊投影片第 12 章  - 通用APIJava SE 7 技術手冊投影片第 12 章  - 通用API
Java SE 7 技術手冊投影片第 12 章 - 通用API
 
Ruby basic
Ruby basicRuby basic
Ruby basic
 
JS and NG - ntut iLab 2015/07/14
JS and NG - ntut iLab 2015/07/14JS and NG - ntut iLab 2015/07/14
JS and NG - ntut iLab 2015/07/14
 
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註
Java SE 7 技術手冊投影片第 16 章 - 自訂泛型、列舉與標註
 
Java SE 8 技術手冊第 5 章 - 物件封裝
Java SE 8 技術手冊第 5 章 - 物件封裝Java SE 8 技術手冊第 5 章 - 物件封裝
Java SE 8 技術手冊第 5 章 - 物件封裝
 
潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
 
Ecma script edition5-小试
Ecma script edition5-小试Ecma script edition5-小试
Ecma script edition5-小试
 
Java SE 8 技術手冊第 4 章 - 認識物件
Java SE 8 技術手冊第 4 章 - 認識物件Java SE 8 技術手冊第 4 章 - 認識物件
Java SE 8 技術手冊第 4 章 - 認識物件
 
Migrations 與 Schema 操作
Migrations 與 Schema 操作Migrations 與 Schema 操作
Migrations 與 Schema 操作
 
Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)Nashorn on JDK 8 (ADC2013)
Nashorn on JDK 8 (ADC2013)
 
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDEJava SE 8 技術手冊第 2 章 - 從JDK到IDE
Java SE 8 技術手冊第 2 章 - 從JDK到IDE
 
CRUD 綜合運用
CRUD 綜合運用CRUD 綜合運用
CRUD 綜合運用
 
Eloquent ORM
Eloquent ORMEloquent ORM
Eloquent ORM
 
如何用JDK8實作一個小型的關聯式資料庫系統
如何用JDK8實作一個小型的關聯式資料庫系統如何用JDK8實作一個小型的關聯式資料庫系統
如何用JDK8實作一個小型的關聯式資料庫系統
 
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDE
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDEJava SE 7 技術手冊投影片第 02 章 - 從JDK到IDE
Java SE 7 技術手冊投影片第 02 章 - 從JDK到IDE
 
整合 Open ID
整合 Open ID整合 Open ID
整合 Open ID
 
建造与理解-用Python实现深度学习框架
建造与理解-用Python实现深度学习框架建造与理解-用Python实现深度学习框架
建造与理解-用Python实现深度学习框架
 

Andere mochten auch

那些 Functional Programming 教我的事
那些 Functional Programming 教我的事那些 Functional Programming 教我的事
那些 Functional Programming 教我的事Wen-Tien Chang
 
空手、緊握、到放手 – 敏捷路上學到的5件事
空手、緊握、到放手 – 敏捷路上學到的5件事 空手、緊握、到放手 – 敏捷路上學到的5件事
空手、緊握、到放手 – 敏捷路上學到的5件事 Yves Lin
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2Wen-Tien Chang
 
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with Facilitation
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with FacilitationScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with Facilitation
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with FacilitationYves Lin
 
Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材teddysoft
 
Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)Bruce Li
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Wen-Tien Chang
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upWen-Tien Chang
 
好設計如何好 @ C.C. Agile #14
好設計如何好 @ C.C. Agile #14好設計如何好 @ C.C. Agile #14
好設計如何好 @ C.C. Agile #14teddysoft
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateWen-Tien Chang
 
那一夜我們說Pattern design patterns 20周年-published
那一夜我們說Pattern design patterns 20周年-published那一夜我們說Pattern design patterns 20周年-published
那一夜我們說Pattern design patterns 20周年-publishedteddysoft
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩Wen-Tien Chang
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Wen-Tien Chang
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0Wen-Tien Chang
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向Shengyou Fan
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean StartupWen-Tien Chang
 
[演講] Scrum導入經驗分享
[演講] Scrum導入經驗分享[演講] Scrum導入經驗分享
[演講] Scrum導入經驗分享teddysoft
 
敏捷軟體開發方法與 Scrum 簡介
敏捷軟體開發方法與 Scrum 簡介敏捷軟體開發方法與 Scrum 簡介
敏捷軟體開發方法與 Scrum 簡介曦 徐
 
TensorFlow 深度學習講座
TensorFlow 深度學習講座TensorFlow 深度學習講座
TensorFlow 深度學習講座Mark Chang
 

Andere mochten auch (19)

那些 Functional Programming 教我的事
那些 Functional Programming 教我的事那些 Functional Programming 教我的事
那些 Functional Programming 教我的事
 
空手、緊握、到放手 – 敏捷路上學到的5件事
空手、緊握、到放手 – 敏捷路上學到的5件事 空手、緊握、到放手 – 敏捷路上學到的5件事
空手、緊握、到放手 – 敏捷路上學到的5件事
 
淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2淺談 Startup 公司的軟體開發流程 v2
淺談 Startup 公司的軟體開發流程 v2
 
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with Facilitation
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with FacilitationScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with Facilitation
ScrumMaster 的吃飯傢伙 – 引導出個夢幻團隊 Building a Dream Team with Facilitation
 
Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材
 
Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)Refactoring Workshop (Rails Pacific 2014)
Refactoring Workshop (Rails Pacific 2014)
 
Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介Ruby 程式語言綜覽簡介
Ruby 程式語言綜覽簡介
 
Yet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom upYet another introduction to Git - from the bottom up
Yet another introduction to Git - from the bottom up
 
好設計如何好 @ C.C. Agile #14
好設計如何好 @ C.C. Agile #14好設計如何好 @ C.C. Agile #14
好設計如何好 @ C.C. Agile #14
 
ALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborateALPHAhackathon: How to collaborate
ALPHAhackathon: How to collaborate
 
那一夜我們說Pattern design patterns 20周年-published
那一夜我們說Pattern design patterns 20周年-published那一夜我們說Pattern design patterns 20周年-published
那一夜我們說Pattern design patterns 20周年-published
 
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
A brief introduction to Vagrant – 原來 VirtualBox 可以這樣玩
 
Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀Git 版本控制系統 -- 從微觀到宏觀
Git 版本控制系統 -- 從微觀到宏觀
 
A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0A brief introduction to SPDY - 邁向 HTTP/2.0
A brief introduction to SPDY - 邁向 HTTP/2.0
 
PHP 語法基礎與物件導向
PHP 語法基礎與物件導向PHP 語法基礎與物件導向
PHP 語法基礎與物件導向
 
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
從 Scrum 到 Kanban: 為什麼 Scrum 不適合 Lean Startup
 
[演講] Scrum導入經驗分享
[演講] Scrum導入經驗分享[演講] Scrum導入經驗分享
[演講] Scrum導入經驗分享
 
敏捷軟體開發方法與 Scrum 簡介
敏捷軟體開發方法與 Scrum 簡介敏捷軟體開發方法與 Scrum 簡介
敏捷軟體開發方法與 Scrum 簡介
 
TensorFlow 深度學習講座
TensorFlow 深度學習講座TensorFlow 深度學習講座
TensorFlow 深度學習講座
 

Ähnlich wie 從 Classes 到 Objects: 那些 OOP 教我的事

Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Wen-Tien Chang
 
Open source的devops工具箱 公開版@coscup2016
Open source的devops工具箱 公開版@coscup2016Open source的devops工具箱 公開版@coscup2016
Open source的devops工具箱 公開版@coscup2016Kirk Chen
 
Javascript OOP
Javascript OOPJavascript OOP
Javascript OOP凯 高
 
01 A Simple iOS Application
01 A Simple iOS Application01 A Simple iOS Application
01 A Simple iOS ApplicationTom Fan
 
CSS 培训
CSS 培训CSS 培训
CSS 培训S S
 
那些年,我們一起Open的data
那些年,我們一起Open的data那些年,我們一起Open的data
那些年,我們一起Open的dataKevingo Tsai
 
领域驱动设计实践
领域驱动设计实践领域驱动设计实践
领域驱动设计实践Jacky Chi
 
Javascript 培训第二节 基础上
Javascript 培训第二节 基础上Javascript 培训第二节 基础上
Javascript 培训第二节 基础上liziqi7
 
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5   app - oss - 3rd party api(ver 1.0) 開放原始碼 Ch2.5   app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0) My own sweet home!
 
2016.8.1 Design Pattern Eric
2016.8.1 Design Pattern Eric2016.8.1 Design Pattern Eric
2016.8.1 Design Pattern Eric柏亨 盧
 
咩星征服計劃 用 Js 征服地球 Part II
咩星征服計劃 用 Js 征服地球 Part II咩星征服計劃 用 Js 征服地球 Part II
咩星征服計劃 用 Js 征服地球 Part II羊 小咩 (lamb-mei)
 
Jira live demo 2017
Jira live demo 2017Jira live demo 2017
Jira live demo 2017Linktech
 
Programming python - part 1
Programming python - part 1Programming python - part 1
Programming python - part 1Che-Cheng Hsu
 

Ähnlich wie 從 Classes 到 Objects: 那些 OOP 教我的事 (16)

Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛Ruby Rails 老司機帶飛
Ruby Rails 老司機帶飛
 
Javascript
JavascriptJavascript
Javascript
 
Open source的devops工具箱 公開版@coscup2016
Open source的devops工具箱 公開版@coscup2016Open source的devops工具箱 公開版@coscup2016
Open source的devops工具箱 公開版@coscup2016
 
Javascript OOP
Javascript OOPJavascript OOP
Javascript OOP
 
hibernate
hibernatehibernate
hibernate
 
01 A Simple iOS Application
01 A Simple iOS Application01 A Simple iOS Application
01 A Simple iOS Application
 
Excel VBA
Excel VBAExcel VBA
Excel VBA
 
CSS 培训
CSS 培训CSS 培训
CSS 培训
 
那些年,我們一起Open的data
那些年,我們一起Open的data那些年,我們一起Open的data
那些年,我們一起Open的data
 
领域驱动设计实践
领域驱动设计实践领域驱动设计实践
领域驱动设计实践
 
Javascript 培训第二节 基础上
Javascript 培训第二节 基础上Javascript 培训第二节 基础上
Javascript 培训第二节 基础上
 
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5   app - oss - 3rd party api(ver 1.0) 開放原始碼 Ch2.5   app - oss - 3rd party api(ver 1.0)
開放原始碼 Ch2.5 app - oss - 3rd party api(ver 1.0)
 
2016.8.1 Design Pattern Eric
2016.8.1 Design Pattern Eric2016.8.1 Design Pattern Eric
2016.8.1 Design Pattern Eric
 
咩星征服計劃 用 Js 征服地球 Part II
咩星征服計劃 用 Js 征服地球 Part II咩星征服計劃 用 Js 征服地球 Part II
咩星征服計劃 用 Js 征服地球 Part II
 
Jira live demo 2017
Jira live demo 2017Jira live demo 2017
Jira live demo 2017
 
Programming python - part 1
Programming python - part 1Programming python - part 1
Programming python - part 1
 

Mehr von Wen-Tien Chang

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨Wen-Tien Chang
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Wen-Tien Chang
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyWen-Tien Chang
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingWen-Tien Chang
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingWen-Tien Chang
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit TestingWen-Tien Chang
 
Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Wen-Tien Chang
 
Distributed Ruby and Rails
Distributed Ruby and RailsDistributed Ruby and Rails
Distributed Ruby and RailsWen-Tien Chang
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Wen-Tien Chang
 

Mehr von Wen-Tien Chang (17)

⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 
Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)Exception Handling: Designing Robust Software in Ruby (with presentation note)
Exception Handling: Designing Robust Software in Ruby (with presentation note)
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
 
RubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & ClosingRubyConf Taiwan 2012 Opening & Closing
RubyConf Taiwan 2012 Opening & Closing
 
Git Tutorial 教學
Git Tutorial 教學Git Tutorial 教學
Git Tutorial 教學
 
RubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & ClosingRubyConf Taiwan 2011 Opening & Closing
RubyConf Taiwan 2011 Opening & Closing
 
BDD style Unit Testing
BDD style Unit TestingBDD style Unit Testing
BDD style Unit Testing
 
Git and Github
Git and GithubGit and Github
Git and Github
 
Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3Service-Oriented Design and Implement with Rails3
Service-Oriented Design and Implement with Rails3
 
Rails3 changesets
Rails3 changesetsRails3 changesets
Rails3 changesets
 
遇見 Ruby on Rails
遇見 Ruby on Rails遇見 Ruby on Rails
遇見 Ruby on Rails
 
Designing Ruby APIs
Designing Ruby APIsDesigning Ruby APIs
Designing Ruby APIs
 
Rails Security
Rails SecurityRails Security
Rails Security
 
Rails Performance
Rails PerformanceRails Performance
Rails Performance
 
Distributed Ruby and Rails
Distributed Ruby and RailsDistributed Ruby and Rails
Distributed Ruby and Rails
 
Ruby 入門 第一次就上手
Ruby 入門 第一次就上手Ruby 入門 第一次就上手
Ruby 入門 第一次就上手
 

從 Classes 到 Objects: 那些 OOP 教我的事