我過去在當地的咖啡廳跟一個敏捷教練(Agile Coach)談過Scrum及敏捷方法(Agile),他在澳洲最大的銀行工作。我們談到的其中一個主題是敏捷方法及Scrum在亞洲的採用情形。他一直想了解是否有任何亞洲的銀行採取敏捷方法,從高階管理階層到員工階層。他想要比較這些亞洲銀行跟自己工作的銀行採取Scrum成熟度上的差異。他目前工作的銀行在東南亞的國家開了許多分公司,因此,管理部門要求他飛到東南亞在當地導入Scrum及敏捷方法。然而,他受到了來自當地管理者的阻礙。當地管理者要求他找其他採用Scrum典範的亞洲銀行。很多亞洲領導者相信無論它在西方世界運作得多好,不代表在東方世界一定可以運作。
在他的研究中,他發現多數亞洲銀行並不會全力衝刺敏捷方法。他對他自己的發現感到驚訝,因為大多數在澳洲的大型銀行視敏捷方法為必須,而不是其中的一個選項。他也驚訝於在亞洲多數採行Scrum的只限於軟體開發,然而管理上並不採用敏捷管理方法。多數(可能並非所有)亞洲公司非常保守也不敢全面採用敏捷方法。多數聲稱採行敏捷方法的亞洲公司也只在軟體開發的管理上採用了Scrum方法而已,管理者仍然使用傳統的方法。
我在過去的5年內在香港、杜拜、印尼、日本、南韓、菲律賓、馬來西亞、新加坡、泰國、越南公司有執行過的Scrum訓練跟Scrum教練課程。我看到這個部份世界的人們對於Scrum及敏捷方法有許多誤解。亞洲公司的管理者認知的Scrum以及敏捷方法就如同軟體開發一樣,他們還不理解熱烈的參與以及對Scrum及敏捷方法有良好的認識是必須的,如此,公司才能充份利用敏捷方法。這些年來,我也做了許多小型研究以及關於當地文化的訪談。研究當然不是非常嚴謹,因為我想用更親近、更個人的形式跟這些人談當地文化。這些當地文化阻礙了在亞洲大規模採用Scrum及敏捷方法,這就是為什麼管理部門仍然抗拒採用敏捷方法的原因。
只有少數亞洲公司會盡全力衝刺敏捷方法,這些公司通常是由年輕的一代領軍的網路公司,他們曾經在歐洲、澳洲或是北美工作或是學習過。這些領導者是Scrum及敏捷方法的信徒,因為他們曾經在他們以前的工作地點見識過他有用。不只是當地亞洲公司他們努力掙扎去了解敏捷的真諦,研發中心在亞洲的跨國公司也無法充份利用Scrum及敏捷方法,因為當地管理者仍然採用傳統方法來管理公司及Scrum團隊。
Ken Schwaber寫了一篇部落格文章,當中寫道文化上習慣預測的人將會確切地看到糟糕的軟體、錯過的時程、浪費的金錢、士氣低落的員工。 以下是由我增加的理由,解釋為什麼Scrum以及敏捷方法在亞洲不管用。我在這些理由上做了不少廣義化。事情當然都有例外,不過例外不會太多。
1: 生命中的每件事都有階層關係
亞洲人相信我們存在的宇宙正系統性地運作著,每件事都應該有他的階層關係。有陰陽,有種姓制度。年輕的一代應該尊重較老的一代。下屬應該聽從老闆的話,因為多數人認為老闆有所有的答案。在一些亞洲國家國王代表絕對的統治者,國王應該有所有最終的答案。採行一黨制的國家也有相同的現象。
當西方人相信平等主義,多數亞洲人甘願處於階層當中,他們知道他們的位置跟在這個位置上的慣例或是行為準則。沒有既定結構,每個人相互合作地工作,以及跨職能團隊的自我組織的方式被認為是不合邏輯的,他看起來就是失序的系統。人們期待被告知要做什麼,也想要告訴別人該做什麼,因為這才是一個有秩序的系統的運作方式。
在多數的亞洲文化,在公司的位置也決定了社會地位。亞洲人寧願擔任專案經理(PM),因為這個腳色非常明確,也因為PM擁有很多事情的決定權,相較之下,敏捷教練(Agile coach)或是Scrum Master並沒有任何的權力告訴別人該做什麼。對大多數亞洲人來說,作為一個敏捷教練或是Scrum Master看起來較低等。這就是為什麼當你瀏覽LinkedIn,你會常常看人們聲稱他是他們公司的Scrum Master,同時也把專案經理放在底下,因為他們想受到朋友的敬重。為什麼很多亞洲人他們聲稱自己是敏捷教練或是Scrum Master,仍然把專案經理的頭銜放在他們的LinkedIn個人頁面的理由,是因為他們公司不承認敏捷教練或是Scrum Master這個角色,或是因為他們想看起來掌握公司的權力且同時跟上敏捷的潮流。即使一個敏捷教練,他沒有專案經理的頭銜,仍然不能抗拒告訴人們該做什麼。亞洲人還沒有了解到Scrum Master是真正的管理者,是不同種類的管理者。
除了Scrum Master在很多亞洲公司仍然維持著像傳統上對下的管理者外,也沒有像授權的"產品負責人"這樣的東西,我稱之為迷你CEO,對他的產品負責。任何產品負責人做的決策可以被(也極有可能會被)任何公司中有最高政治權力的人推翻。在亞洲公司,多數的產品負責人就像裝飾品,他(她)對他所管理的產品並沒有任何的控制權。但最有趣的是,這些擁有更高政治權力的人並不想要變成產品負責人,因為他們太『忙』以至於無法在開發團隊中協力開發。授權這個字在多數亞洲公司的意思就是,把權力從較低位者抽走。
儘管這些社會階層在西方文化看似也沒那麼重要,在亞洲文化卻十分重要。在大多數亞洲公司,程式設計師位於整個階層的最底層。在階層中的地位大多數時候也決定了薪水。這也是為什麼主流亞洲程式設計師不會夢想後半輩子還是一個程式設計師,因為程式設計師是位於整個公司的最底層。如果他們後半輩子還是個程式設計師,社會會認為他們的生涯是停滯沒有前進的。你將會常常在Scrum或是敏捷社群論壇看到問題,問題圍繞在如何在一個實作99% Scrum的組織成為一個Scrum Master或是開發者。
據我先前的觀察,生命中的每件事都有階層關係這個信念是最主要的理由為什麼Scrum無法完全在亞洲發揮作用。
2: 以和為貴(Let’s keep things in harmony)
亞洲人非常會以和為貴。亞洲人為了要保持同儕間的合諧傾向去避免衝突。這沒有什麼不對,但是這跟西方人十分的不同,他們不害怕面對衝突、直接而勇敢面對、不吝批評指教、討論有爭議的主題、堅持個人認為是對的主張。一個敏捷團隊會鼓勵要有面對衝突的勇氣,但這極少在亞洲公司中看到,特別是跟老闆衝突。跟老闆衝突會被視為是叛亂的一件事。
這樣不面對衝突的習慣影響了亞洲整個敏捷團隊執行Sprint Planning、Sprint Review、Sprint Retrospectives和Daily Scrum。更不用說Pair Programming了。人們傾向保留他們的意見因為他們不習慣於安份的環境製造太多錯誤。回顧就變得乏味而令人生厭,因為大家就只會在Sprint上說沒有問題,而現實則是大家害怕見到問題被別人暴露出來,過一陣子之後大家認為他們的回顧一點用也沒有,應該盡早停止。Sprint Planning變得單調,大多數人只會跟隨講話最大聲的那個人。Sprint Review只變成一個單向的demo,以及向主管報告專案進度的場合。Sprint Planning只是變成一個約定,沒有資訊交換,沒有協商,跟瀑布開發流程沒有差別。Daily Scrum變成定期舉辦的進度更新會議,而不是一個每天的計劃協力調整。
一整天下來,很難從這樣的團隊中看到透明性,Scrum的三大支柱之一,因為人們會設法講你想聽的話。人們懼怕面對衝突和陷入麻煩。這也很常見,人們會拉長時間工作來掩蓋目前正在發生的問題而不讓老闆知道。人們不知道為什麼Scrum變成一個微管理工具,因為人們喜歡以和為貴,也因為人們想保住他們的飯碗,管理階層認為他們是可取代的。
3: 不同教育體系,不同款思維
亞洲的教育體系跟西方的教育體系非常的不同。就如同老闆看起來總是會有個答案,同樣的情況也適用於教室,老師或是講者也看起來要是教室中最聰明的人。多數西方學校傾向使用案例讓所有人熱烈參與討論,亞洲學校仍然強調機械性的反覆背誦。如此的作法會養成很會考試的人,但也在學生身上放了巨大的壓力,而且不鼓勵獨立思考。亞洲的教育體系只有成績跟排名,沒有實驗、自我探索以及犯錯,這些都是敏捷方法所訴求的。
曾經在學校以及大學教書,那裡的人不被鼓勵犯大量錯誤和去見老師或是講者整整十六年,自然地亞洲人對於在工作場合犯錯感到不安全。
亞洲的教育體系影響了人們在職場的思考及行為。自我組織,Scrum的重要教義,很難在亞洲公司達成,因為自我組織是學校或大學不會教的事情。亞洲人已經被教育成要要遵守規則、遵循整個系統,打破他會被視為造反。亞洲人希望被教練或顧問告知如何變得敏捷以及如何適當地執行Scrum,而不是由他們自己找到答案。要教會亞洲人自我組織及自我探索等於消滅了在學校或大學整整十六年所教的東西。
4: 外包 —每件事最後都會走到cost down(正確說法:reducing costs)
為什麼Scrum跟敏捷方法在亞洲公司這麼難推行的最後一個理由,就是因為亞洲是個外包天堂。你可能會疑惑:為什麼外包是個問題?
在歐洲、北美和澳洲的公司會外包到亞洲的其他國家來降低成本。不幸的是,這也帶來成本。就是因為這些公司已經看到Scrum和敏捷方法在世界的一部份成功,這不代表可以簡單地移植敏捷的文化到亞洲。甚至,有了敏捷方法你可以節省開發成本,這不代表建構敏捷文化也同樣便宜。事實上,敏捷方法期待好的團隊成員,而且最好的軟體開發人員大多數都不便宜。
因為這樣的便宜心態,我已經看多非常多次人們採取最便宜的方法來做到敏捷:受最便宜的訓練,他會把Scrum教得像公式解、線上教學、拿到最便宜的敏捷證照,甚至找槍手去考Scrum Master的認証考試等等。很多亞洲人仍然認為Scrum是一個專案管理的方法學,他可以直接安裝而不用任何苦功,然後日後的每件事就這樣固定下來。這樣便宜的見解也會從一些(善於騙人的)訓練人員以及顧問來,他們會教公式化Scrum跟『敏捷專案管理』。
接受Scrum訓練並得到Scrum認証並不代表自動讓任何組織變得敏捷。變得敏捷需要努力、耐心、breaking the silos、放下自傲、管理階層的參與、信任、勇氣、很多組織上的變革、很多的實驗及很多失敗(也包含有經驗的敏捷教練)執行多年。以上所有都十分的昂貴。如果打造一個敏捷的組織是這麼地昂貴,打造亞洲的敏捷組織必定更為昂貴,理由我在前面已經有提過。
只要人們持續認為轉換到敏捷方法就跟薯片一樣便宜簡單(cheap as chips),Scrum在亞洲就不管用。
這就是全部了嗎?他怎麼能這麼難?
確實有非常多其他為什麼Scrum和敏捷方法在亞洲不奏效的原因,以及為什麼很多亞洲公司無法充份利用Scrum和敏捷方法,但我的一些朋友給我一些忠告,叫我不要在公眾空間寫出來,一旦被很多人找到會是敏感而冒犯的。甚至是我在寫這篇文章的時候,我需要一些勇氣,當我想到一些人可能會覺得被冒犯。
Scrum未來有沒有可能在亞洲運作?這些事情能不能被改變?
在大多數的亞洲公司敏捷方法仍然像是附屬品,人們並不是為了他背後的價值而去實踐他,只是為了在這世界上保持在潮流的前端。亞洲公司不想要被敏捷的浪潮拋下,但不是全力擁抱敏捷且在組織中做出改變,他們包裝任何他們目前在做的事情並且把它稱為敏捷。
我個人認為,要發起一場革命,讓亞洲公司大量採用Scrum和敏捷方法,也讓亞洲領導者完全了解到有非常多文化本質上的障礙要先克服,才能讓Scrum像西方公司那樣完整運作,特別是階層式的上對下管理方法,仍然是大多數亞洲公司一個厚重的包袱。但事情仍舊有希望,很多新一代想要改變二十一世紀亞洲組織運作的方式。我希望我可以活到看見Scrum和敏捷方法在亞洲變成規範而不再是選項的那一天。我邊這麼想著,邊啜飲我最後一口咖啡。
Julia 的物件導向
今天特別要來談談Julia這個語言的物件導向模型。
我已經聽到有些人跟我說「Julia才沒有物件導向」或是「我不承認這是物件導向」等等這類的話。
不過我得要跟大家說,物件導向不是只有大家看到的C++或是Java那個樣子的物件導向模型。
介紹 Julia 的物件導向模型
如果你的背景是C++, Java, Python, Ruby等等語言的話,那你應該非常熟悉物件導向的幾個要素:
- 封裝
- 繼承
- 多型
談到封裝,Julia幾乎沒有封裝的概念。
是的,Julia不封裝!
Julia宣告的是型別,不是類別;型別他只宣告了有哪些欄位,他也不會把方法宣告在型別裡頭。
所以Julia的型別感覺上會比較像是C的struct
,只存資料或狀態,不帶任何的方法。
那方法怎麼辦?
方法會由 Julia 的多重分派(multiple dispatch)引入。
也就是說,我只要去設計任何函式,這個函式他所用到的參數型別,那這個函式就是這些參數的方法。
Julia會視函式呼叫的參數型別組合,來決定到底要執行哪一種方法。
看完之後應該會很傻眼,既然沒有封裝,然後又不帶方法,那這樣要怎麼實現物件導向呢?
Julia 的型別系統
概念上來說,Julia會藉由兩種型別來建立型別階層(type hierarchy):抽象型別跟複合型別
1 | abstract type Number end |
以上宣告了 3 個抽象型別以及一個複合型別。
抽象型別只有一行宣告,也就是說明這代表什麼樣的概念,他不具有欄位。
<:
代表的是 is subtype of,abstract type Complex <: Number end
代表的是Complex
是Number
的子型別。
複合型別就像Integer
,他有一個field x
,他是Real
的子型別。
子型別可以是抽象型別或是複合型別,但相反的是,父型別只能是抽象型別。
以上我們描繪了一個型別階層,位於最頂端的是Number
,所有人都是Number
的子型別。
而複合型別只能位於這棵型別階層的末端的位置。
在Julia中,所有的型別都是Any
的子型別,相反,所有型別的子型別則是Union{}
。
這樣的階層完全不俱備傳統物件導向的繼承概念,雖然觀念上也滿足is-a的關係,但是他並沒有從父型別上繼承任何東西,也沒有東西可以被繼承。
你可能會問:那這樣的型別階層有什麼用呢?
這就要配合多重分派來用拉~~
Julia 的多重分派
大家比較熟悉的應該是single dispatch,也就是區別foo.method()
與bar.method()
的不同。
傳統的物件導向當他呼叫foo.method()
與bar.method()
這兩者時,同樣都是呼叫method()
這個函式,可是到底要呼叫誰的實作呢?
Single dispatch會告訴你:去找擁有這個函式的人,也就是.
前面的那個傢伙。
但是Julia的設計理念是:函式並不屬於任何人,也就是不會有人擁有函式。
所以Julia裡的函式會是method(foo)
跟method(bar)
這樣的形式。
Julia設計上很聰明,他會告訴函式去執行擁有跟參數型別相同排列組合的那個實作。
這也就是多重分派了,他不依賴單一的型別去判斷,而是所有的參數型別的組合!
所以當你宣告了一個像這樣的函式:
1 | function foo(a, b, c) |
他會接受任意的3個參數,當沒宣告參數型別時就自動是Any
。
那以下這個狀況:
1 | function foo(a::Int64, b) |
就只接受第一個參數型別是Int64
,而輸入兩個參數的情況了。
OOP in Julia
以這樣的type system以及多重分派作為建構物件導向的核心機制。
我們不能在以傳統的思維去想物件導向。
我們需要思考的是物件導向的核心是什麼?
物件導向的引入主要幫助我們去塑造一個物件概念,並且幫助我們減少重複的程式碼,提高程式碼的再利用(reuse)。
我們訴求的是高內聚,低耦合的程式碼。
在Julia中,複合型別提供了一個類似物件、結構的角色,由於沒有繼承關係,也不會有過高的內聚。
繼承所需要的元素可以由合成(composition)來達成,但相對犧牲了部份的欄位再利用的可能性。
方法的部份還原成了最初始的函式的樣貌,而函式本身是更加自由的。
藉由多重分派可以更加細緻地定義函式的行為,可以在不同的參數型別上提供多樣的語意。
例如,*(Int64, Int64)
的含意是數字的乘法,*(String, String)
則是字串的串接,同樣的運算子或是函數名稱,可以提供不同context下,不同的語意,這不是很像人類的語言習慣嗎?
在Julia的精神中,我們關注的是context跟行為,去定義不同context下的函式以及語意(行為)是重要的。
這方面Julia提供了絕佳的多型(polymorphism),但完全不支援繼承與封裝,對資訊的存取權更是無法控制。
但他更強調的是readability!如果設計者考慮到context,那讀程式碼的人就更能進入這個context去思考。
在函式的使用上更是毋庸置疑的靈活而鬆耦合,所以在程式碼的撰寫上,可以自然的達成高內聚,低耦合,更可以提升readability,最後的再利用就端看設計者最佳化的功力拉!
Julia是一個達成物件導向精神的語言!
State-centered and behavior-centered OOP
The state-centered OOP
傳統大家認知的物件導向,大多都由一個概念或是實體所構成。
大家在做程式設計的時候,大家所關注的大多是一個變數的值是如何變化或是一個物件的狀態如何變化。
所以很自然的會從一個實體或是概念著手,進而去設計他應該有怎樣的properties或是做什麼事情。
會慢慢凝聚出一個概念,並且把這個概念化成一個個的class,並把這個class描繪清楚。
class描繪仔細了以後,就去關注class跟class之間的互動關係,進而完成整個演算法或是架構。
The behavior-centered OOP
在Julia的物件導向則是敘述關係或是行為。
Julia會以函式的角度出發,Julia中的物件導向指的是design a set of methods這回事。
Julia會使你關注在參數之間的關係,他們應該如何一起完成工作?參數如何被dispatch?函式跟函式之間會不會衝突?
型別應該會有什麼樣的行為?*
用在數字上跟用在字串上的語意有沒有一樣?
方法其實是在圈定一群型別,他們會一起作用,就是這麼簡單。
所以Julia的物件導向觀點都會圍繞在設計方法上面,而這樣的觀點又可以讓Julia很自然的融入functional programming當中。
這讓Julia可以花比較少力氣在斤斤計較欄位的設計上,也花比較少力氣在思考繼承關係上。
相對花比較多力氣在這個方法被宣告、進入整個語言系統當中的運作情形,也就是對整個系統的影響上。
如果家人親友遭逢重大變故
知道事情的真相比較好還是不知道比較好?
知道事實怕自己無法改變既定事實又怕受傷害
不知道事實又懸著一顆心,忐忑不安
最近朋友的親人遭逢重大變故
該不該讓其他家人知道,讓他傷透腦筋
是不是知道世界上所有的事實就能變得無敵、變得快樂?
但知道了以後,又怕看到這個世界是極其的噁心汙濁,自己又無能為力
是不是當個傻瓜比較好?
傻瓜連自己怎麼死的都不知道,可能跌進水溝就死了
我認為最重要的不是成為全知的人或是成為愚笨的人
擁有勇氣跟足夠的心智能力才是重點
成為了全知的人,如果擁有極其強大的勇氣跟能夠處理這些事實的心智能力
自然不必為這些事實悲傷
勇氣會帶你克服這些情緒,心智能力能良好的處理這些資訊
如果沒有了勇氣跟心智,知道太多的事實必然掉入悲觀的深淵中
你不知道如何運用這些事實,你不知道如何解釋你的人生,你沒有勇氣面對他們
相反,有勇氣的傻瓜就是個有勇無謀的匹夫
只會戰死在第一線上,可能有貢獻、可能沒有
如果傻瓜連勇氣都沒有,也沒有足夠的心智能力
快樂的活著會是你人生的唯一目標
但是!!!
你不知道快樂何時會消失?你不知道怎麼留住他?
但你仍然過你的生活
某天,他消失了,你如同一隻無助的小動物一樣,手足無措
想掙扎,但又不知如何找回以往的快樂…
勇氣跟心智能力或許比聰明來的重要
擁有勇氣跟心智能力可以活的不錯
但是變得聰明、知道更多事實,才能突破限制、抓住幸福的尾巴
聰明、勇氣跟心智能力是需要一起成長的
為什麼美女一定要皮膚白、長的瘦、高顏值,不同體態的人有不同姿態的美
為什麼不接受同性戀,同性戀跟異性戀一樣愛人跟被愛
為什麼看動漫被視為宅,看卡通被認為幼稚
為什麼害怕精神病患,雖然行為舉止怪異,他仍舊是人,仍然有感覺
台灣社會極度推崇單一的主流價值觀
對於不同文化或是價值觀的族群接受度不高
這次鄭捷的事件提醒了我們這件事
我們無法以更開放、接受的態度,科學性的精神去探討議題
就憑藉著直覺、單一的,去裁決這件事
他的死並沒有帶給這個社會任何美好,只代表這個社會又忽視了當中的議題,等待下次事件發生
這就像當事件發生了,你卻把眼睛遮起來當作沒看到一樣的愚蠢
沒看到事件發生就代表沒發生事件嗎
這個社會極度的被框架所綁架
胖並不等於醜,瘦也不等於美
動漫是興趣不等於宅
殺人不等於死刑
我們從不開放自己的心態去看一件事
在《行為的藝術》一書中,簡單的邏輯提到:
5台機器生產5件衣服需5分鐘,那麼100台機器生產100件衣服需要多久?
如果你的答案是100分鐘的話,請多想想
正確答案是5分鐘,如果你達出錯誤的答案是因為你的直覺跳出來主導一切
這類的題目被稱為認知反射測試(Cognitive Reflection Test, CRT)
心理學家Shane Frederick測試了很多人,當中麻省理工學院學生表現最優異
CRT值低的人傾向依直覺行事,CRT高的人較擅長以意志力駕馭,以理性思考
研究發現,美國人當中,CRT較高的多為無神論者,CRT較低則傾向信仰上帝
相對容易聽信直覺的人,愈無法以理智挑戰其宗教觀念
很多人念了生物,甚至是分子生物學
但是都不知道DNA,RNA跟protien之間到底是什麼關係
這篇就是用簡單的比喻來說明他們的關係
先來引用一下維基百科的圖
常常我們說DNA是生命的藍圖,DNA其實是"這種分子"的名字
不如我們把細胞想成是一台車子,DNA就是這台車子的設計總藍圖
他很大很大一張,裏面寫滿了各式各樣車子零件的設計圖還有要怎麼組裝起來
RNA就是從設計總藍圖 (DNA)上複製下來的某個零件的藍圖
protien就是根據零件的藍圖 (RNA)製作出來的零件本身
那我們開始囉~~
DNA要轉錄 (transcription)成RNA,也就是把零件的藍圖從總藍圖裡抄寫出來
RNA polymerase佔了很重要的角色,因為他就是那個抄寫員
他會一字不漏的把DNA上的訊息都抄寫成RNA
接著呢在他開始抄寫的時候,會在零件藍圖的開頭加個註記 (capping)
在他超寫完畢的時候呢,會在零件藍圖的結尾加個註記 (polyA tail)
加上這些註記之後,就可以避免這張藍圖被回收人員 (RNase)當成垃圾清掉
大家以為到這邊這張零件藍圖就算完整了嗎
其實不是,這張藍圖還需要做客製化修改 (splicing),修改的過程有點複雜
但是簡單的講,就是依據細胞目前的需求跟狀態,把RNA稍稍修改成他的設計
如此一來,零件藍圖 (messenger RNA)就算是完成了
那從零件藍圖 (messenger RNA)做成零件 (protien)呢
這位工匠就是ribosome (核醣體)大大拉~~~
這位工匠會依據RNA上的設計打造 (translation)一個新的零件
他把amino acid (胺基酸)抓來串起來成為peptide (胜肽鍊)
peptide只是零件的雛型而已,需要加以修飾才會變成真正的零件
這些零件的雛型會被送到細胞核外進行修飾 (post-translational modification)、折疊 (folding)
在DNA上纏繞著一些組蛋白 (histone)
他就像總藍圖的捲軸一樣,會把藍圖捲起來
如此一來,RNA polymerase這個抄寫員就無法抄寫 (transcription)某部份的藍圖 (DNA)
這樣細胞就可以依據環境的改變或是需求改變,去調整該製造出哪些零件
這個領域的學問被稱為epigenetics (表觀遺傳學)
我們都知道gene (基因)在DNA上,然而gene跟gene之間是會互動的!
這個我們稱為基因之間的互相調控,也就是當某些protien變得比較多的時候,他就會告訴gene不要製造這麼多出來,以達到一個平衡
我們再回到汽車零件的比喻,當我生產過多的螺絲零件 (protien)的時候,當然會覺得我用不到這麼多螺絲,所以會跟上游的
製造商溝通,要他們不要製造這麼多
所以細胞當中無時不刻都在進行這種溝通 (調控;gene regulation)
現在發現不只是protien會去調控基因,RNA也會調控基因
所以細胞就處於一種互相調控的網路當中,維持著平衡
如果我們可以了解細胞當中,各種分子是怎麼溝通的話,我們就有辦法去告訴細胞一些事情
例如避免細胞轉變成癌細胞等等事情
很多初學java的人都會有這樣的疑問:
我該用類別, 抽象類別還是介面?
尤其在學 java 之前沒有碰過物件導向概念的人。
在多種選擇的情況下,我該用哪一個比較好呢?
我們可以分幾個觀點來看這個問題
概念解釋觀點
在物件導向的語言裏面,物件跟類別是被抽象化的概念。
也得力於這樣的抽象化,我們可以把某些東西廣義化應用到不同的層面。
這樣的抽象化有賴於封裝、繼承、多型的落實。
封裝可以將概念相同的程式碼放在一起,這些程式碼做同一件事,所以他們代表同一個概念。
同時也比較好維護。
繼承可以提高 reusabiity 的機會,同時也展現了概念上的相似性。
多型就是一種同中求異的概念。
位於同一個繼承體系之下,可以有不同的行為。
承續我先前寫過的文章
繼承是is-a的概念,而實作介面是has-a的概念。
這些概念是不相違背的,所以我們可以簡單的把類別、抽象類別、介面分開。
類別跟抽象類別應該位於繼承體系之下,因為抽象類別也有is-a關係。
但是相對於(具體)類別,抽象類別是不允許被實體化(instantiate)的。
為什麼?
舉個例,Cat 跟 Dog 都繼承於 Animal,因為 Cat is an Animal and Dog is an Animal.
這時我們會把 Animal 寫成抽象類別,因為 Animal 被實體化之後不具任何意義。
他只是我們在繼承體系上或是概念上的類別,他並不是一個具體的物件,不具屬性跟行為。
所以 Animal 不應該被寫成(具體)類別。
那不能被實體化的類別我還需要去定義他的屬性跟方法嗎?
當然要!
回到我們的例子,通常只要是 Animal 就會 eat()
、move()
,或是我想給 Animal id
或是 name
。
這時我們不會把這些東西寫在 Cat 或是 Dog 裏面。
我們會把他通通寫到 Animal 裏面,如此一來下面的子類別就可以簡單的具有這些屬性跟方法了。
這時我們來講講介面,就如同我前面提到的。
介面的實作是has-a的關係。
所以他提供了在一個繼承體系之外的功能性。
他可以讓繼承於 Animal 的 Bird 擁有 fly()
的行為。
他可以讓繼承於 Animal 的 Turtle 擁有 swim()
的行為。
這些都是無法從 Animal 繼承過來的東西。
那無法繼承過來的話,自己寫就好阿,大驚小怪!
錯!
這時我們就會看到
會 fly()
(飛)的 Bird(鳥)。
會 transport()
(運輸)的 Airplane(飛機)。
會 swing()
(拍翅膀)的 Swan(天鵝)。
但是他們想表達的都是在天上飛的概念。
所以介面可以達到統一格式的效果。
大家都實作同樣的方法來表達同樣的行為。
或許行為的實際內容不一樣,但是在概念上是相同的。
軟體工程觀點
在前一個觀點當中提到抽象化。
抽象化使得同樣的一段程式碼可以提高他使用的頻率。
也達到**reusability (重複利用性)**的效果。
我們有了繼承體系來提高 reusability。
在程式碼上,子類別不用重寫同樣的程式碼,只要從父類別繼承來就好。
相對於同樣的程式碼散落在各個子類別,當要維護的時候就要一個一個修改。
這樣父類別就控制了子類別的行為。
如果父類別的方法被修改的話,也會影響到子類別。
如果你不希望父類別的改變影響到子類別的話,這時請確認兩者是否真的要使用繼承關係。
如果是繼承關係但又不希望受影響,那就用多型吧!
我們使用介面來提高系統的flexibility (靈活性)。
當你需要有相同概念的方法時只要實作同樣的介面就可以達到。
同時規定同樣的介面便於管理維護。
只要實作同樣的介面就可以簡單地擴充模組。
這是一個靈活的系統該有的特徵。
相對於多重繼承 (ex. C++)
相對於C++的多重繼承,java 只允許單一繼承。
在多重繼承當中,可以讓一個類別擁有很多身份。
一個類別可以是很多種東西。
這樣的概念其實可以讓人容易了解這個類別在做些什麼。
像是Computer is a Machine and Computer is a Calculator.
這樣我們可以理解電腦是一種會計算的機器。
但是相對應的他也帶來一些不必要的副作用。
繼承於多樣的父類別,也同時繼承到了父類別的屬性跟方法,但是並不是所有的屬性跟方法都是有用的,甚至有些屬性或方法根本用不到。
當你沒有要使用到的時候卻又繼承了太多的東西,這就造成了另一種的設計不良的狀況。
這會讓別人誤解子類別有擁有父類別的某些方法,但卻不知道那是不應該出現的。
造成誤用問題就更大了。
這樣的問題小至程式錯誤,大至系統崩潰,這就成了系統的弱點之一了。