2014年1月20日 星期一

Scala 前言2 - is Scalable by OOP & Functional Programming

前言
Functional programming是一個比OOP還要舊的語言, 重點不是What is Functional Programming, 而是當Scala 同時有Functional programming & OOP特性的時候, 這兩者該如何完美的互相結合, 並且幫助你建置出有用且可擴展性的Software

Scala名稱來自於Scalable, 它的使命亦即就是讓你可建置出可擴展性的Software, OOP本身也是一個可擴充性語言, 當你需要新的東西時候, 創造新的物件 or 透過繼承來實做是一個常見的方式, 可是OOP的Encapsulation(封裝) 把Program架構模組化成物件, 卻又產生了一些矛盾, 因為在一個以物件為基本元素的語言, 當你只需要該物件的一個method的特性時,你卻得繼承整個物件, 是非常不方便的, 如果硬幹, 你要幫既有的系統增加新的功能時, 你會遇到得重新Compile整個系統, 是會有問題的.

Functional Programming是一個比OOP還要舊的語言, 在FP中是把Instruction封裝成一個Function, 而OOP可以視為這種模組的進化, 當Software更加複雜的時候, 把Method + Field 封裝成一個物件. 但也限制住了Functional的很多特性, 為了建置出可擴展性的Software, Scala結合了OOP與Functional的特點, 這兩者看似相近又有矛盾的架構, 該怎麼結合?


FUNCTIONS AS OBJECTS


既然物件就是Function的進化, 那麼就直接把Function視為物件來運作即可, 這是一種向下相容的設計模組, 這種概念可以把Function視為簡化版的物件, 沒有Field 只有一個Method (就是Function自己), 如此一來Function可以視為一個Value(就是用Return value代表)去做更多物件上面的應用, 比如當作其他Function call的parameter

 List(1, 2, 3).map((x: Int) => x + 1)  

上面Scala的Example, 是對List物件的map method傳入一個Function當作Parameter:
(x: Int) => x + 1
這是一個Anonymous function無名(匿名)函式, =>符號左邊代表接受參數,右邊代表函式運算本體
這裡左邊是接收一個 Int 參數 x, 右邊執行運算 x+1並回傳 Result,
這時候Scala Compiler會再包裝一次變成以下的code:

 List(1, 2, 3).map(new Function1[Int, Int]{ def apply(x:Int): Int = x + 1})  

原本傳入的Function 會被包入在scala.Function1 的 Class中, 這時候就會是物件, 然後把原本的Anonymous function (x: Int) => x + 1 包裹在apply method裡面, 就完成了把Function轉換成物件的過程

當Function是物件的時候, 也就會有Type, Function的Type是由該Function 的Parameter type加上Return type所組合而成
所以當上例的Function  (x: Int) => x + 1 被包裝成 Function1[Int, Int] Class裡面, 後面的[Int, Int]中第一個Int表示該Function object接受一個 Int parameter, 是由 (x: Int)所判斷得知, 第二個 Int表示該Function object 的Return Type是Int, 是透過Return value x + 1 判斷出Type是Int.
因此Function  object (x: Int) => x + 1 的類型是 Int => Int

Functional還有很多更進階的特性, 藉由結合Functional & OOP可以讓整個軟體開發上更有彈性且容易擴充

繼續閱讀  Scala Basic1, 變數

沒有留言:

張貼留言