顯示具有 程式 標籤的文章。 顯示所有文章
顯示具有 程式 標籤的文章。 顯示所有文章

2015/11/12

物件導向原理

繼承和介面是一種包裝
繼承和介面的目的:用相同的包裝裝不同的東西

委派是一種插座
委派的目的:可抽換插座上的包裝

舉例說明:
1.
電腦上的USB插座是委派,插在上面的東西全都得實作USB介面,你隨時可以插拔USB插座上的東西,來改變電腦功能。

2.
不管你在PCHOME買啥,他都會找到一個更大的箱子去包裝你買的東西,而那個箱子是他們運送的標準規格,送貨員只需要學會接受標準規格即可上班。

最簡單的兩個設計模式:

所以延長線可以接延長線是天經地義的事情。

2015/11/10

swift 物件導向觀念

import UIKit

//程式碼複製

class A11{
    func doo(){
        print("A")
        print("A")
        print("A")
        
        print("B")
        print("B")
        print("B")
    }
}

class A12{
    func doo(){
        print("A")
        print("A")
        print("A")
        
        print("C")
        print("C")
        print("C")
    }
}



// 包裝重複
class StaticOrSingleton{
    class func AAA(){
        print("A")
        print("A")
        print("A")
    }
}

class A21{
    func doo(){
        StaticOrSingleton.AAA()
        print("B")
        print("B")
        print("B")
    }
}

class A22{
    func doo(){
        StaticOrSingleton.AAA()
        print("C")
        print("C")
        print("C")
    }
}


// 包裝不同 by 繼承

class A31{
    func doo(){
        StaticOrSingleton.AAA()
        bbb()
    }
    func bbb(){
        print("B")
        print("B")
        print("B")
    }
}

class A32:A31{
    override func bbb(){
        print("C")
        print("C")
        print("C")
    }
}


// 包裝不同 by 繼承2
class A40{
    func doo(){
        StaticOrSingleton.AAA()
        bbb()
    }
    func bbb(){}
}

class A41:A40{
    override func bbb(){
        print("B")
        print("B")
        print("B")
    }
}

class A42:A40{
    override func bbb(){
        print("C")
        print("C")
        print("C")
    }
}



// 包裝不同 by 委派
protocol B{
    func bbb()
}

class B1:B{
    func bbb(){
        print("B")
        print("B")
        print("B")
    }
}

class B2:B{
    func bbb(){
        print("C")
        print("C")
        print("C")
    }
}

class A6{
    var b:B
    init(b:B){
        self.b = b
    }
    func doo(){
        StaticOrSingleton.AAA()
        b.bbb()
    }
}

A6(b: B1()).doo()
A6(b: B2()).doo()


// 包裝不同 by 函數變數
class A7{
    var b:()->()
    init(b:()->()){
        self.b = b
    }
    func doo(){
        StaticOrSingleton.AAA()
        b()
    }
}

A7(b: {
    print("B")
    print("B")
    print("B")
}).doo()
A7(b: {
    print("C")
    print("C")
    print("C")
}).doo()





2015/11/6

如何寫出好程式

想要寫出好程式,你需要具備兩個能力:

價值觀:你能比較實作一個功能,兩個不同寫法之間的優缺點。
實作能力:你能夠實作一個功能,用多個不同的寫法。


case A:
當你還是一個新手,你剛學會寫程式。你不會考慮效能、可讀性、可擴充性等等的問題。你好不容易找到一個寫法可以讓編譯器通過編譯,並且顯示出正確結果。此時的你,沒有價值觀也沒有實作能力。


case B:
你開始看一些如何寫出好程式的原則,知道效能、可讀性、可擴充性等等的問題是重要的。此時的你,有價值觀但是沒有實作能力,你說得一口好程式

當你面臨一個選擇題,但你只有一個選項,即使你有再好的價值觀也沒用。


case C:
你開始看一些設計模式、繼承、委派、泛型、學會使用套件,學會各種寫法。此時的你,沒有價值觀但是有實作能力,你的程式充滿設計模式,你喜歡過度設計

當你面臨一個選擇題,而你有上百個選項,但是你不知道哪個選項比較好,你沒辦法選出最佳解。


case D:
於是你學會了應該要實作各種寫法,並認真思考各種寫法之間的優缺點,跟人討論的同時逐漸建立出自己的價值觀,你終於能寫出好程式。

2015/3/21

程式設計師界的文人相輕是怎麼一回事?

這是一個文人相輕的故事。

使用設計模式的人有兩種。第一種人他們知道各種模式的優缺點而能夠在適當的時機去使用正確的模式。第二種人是剛學會設計模式,覺得在程式裡面有用設計模式真屌,通常我們會稱呼這叫作過度設計。

不使用設計模式的人也有兩種。第一種是學會之後知道他的缺點所以盡量不使用,第二種人是沒學過。

當一個使用設計模式的人,遇到一個不使用設計模式的人時,就會出現文人相輕的局面:雙方都認為對方是第二種人。

我說明一下什麼是設計模式:就是一群人覺得自己寫的程式架構很好然後把架構命個名丟出來,出了一本書叫設計模式,簡單說就是給你作文範本。所以你在程式裡面去使用設計模式,就好像你寫作文有用成語一樣,可是你知道剛學會成語的人很喜歡整篇作文都是成語,因為覺得很屌...




附上一篇整篇都是成語的作文:http://kids.yam.com/joke/article.php?cid=campus&id=53013

== 以下轉載 ==

今天是國慶日,因為英明偉大的政府建設國家、愛護百姓的功績罄竹難書,所以放假一天,爸爸媽媽特地帶我們到動物園玩。

按照慣例,我們早餐喜歡吃地瓜粥。今天因為地瓜賣完了,媽媽只好黔驢技窮地削些芋頭來濫竽充數。沒想到那些種在陽台的芋頭很好吃,全家都貪得無厭地自食其果。

出門前,我那徐娘半老的媽媽打扮的花枝招展,鬼斧神工到一點也看不出是個糟糠之妻。頭頂羽毛未豐的爸爸也趕緊洗心革面沐猴而冠,換上雙管齊下的西裝後英俊得慘絕人寰,雞飛狗跳到讓人退避三舍。東施效顰愛漂亮的妹妹更是穿上調整型內衣愚公移山,畫虎類犬地打扮的豔光四射,趾高氣昂地穿上新買的高跟鞋。

我們一丘之貉坐著素車白馬,很快地到了動物園,不料參觀的人多到豺狼當道草木皆兵,害我們一家骨肉分離。妻離子散的爸爸鞠躬盡瘁地到處廣播,終於找到到差點認賊作父的我和遇人不淑的妹妹,困獸之鬥中,我們螳臂當車力排眾議推己及人地擠到猴子柵欄前,魚目混珠拍了張強顏歡笑的全家福。

接著到雞鳴狗盜的鳥園欣賞風聲鶴唳哀鴻遍野的大自然美妙音樂。後來爸爸口沫橫飛地為我們指鹿為馬時,吹來一陣涼風,唾面自乾的滋味,讓人毛骨悚然不寒而慄,媽媽連忙為爸爸黃袍加身,也叮囑我們要克紹其裘。

到了傍晚,因為假日的關係,餐廳家家鵲佔鳩巢六畜興旺,所以媽媽帶著我們孟母三遷,最後終於決定吃火鍋。有家餐廳剛換壁紙,家徒四壁很是美麗,燈火闌珊配上四面楚歌,非常有氣氛。十面埋伏的女服務生們四處招蜂引蝶,忙著為客人圍魏救趙,口蜜腹劍到讓人誤認到了西方極樂世界。

飢不擇食的我們點了綜合火鍋,作懷不亂的爸爸當頭棒喝先發制人,要求為虎作倀拿著刀子班門弄斧的女服務生,快點將狡兔死走狗烹,因為尸位素餐的我們一家子早就添油加醋完畢,就等著火鍋趕快沈魚落雁好問鼎中原,可惜鍋蓋太小,有點欲蓋彌彰。

湯料沸騰後,熱得樂不思蜀的我們趕緊解衣推食好大義滅親上下其手,一網打盡撈個水落石出。

火鍋在我們呼天嗆地面紅耳赤地蠶食鯨吞後,很快就只剩滄海一粟,和少數的漏網之魚。母範猶存的媽媽想要丟三落四放冬粉時,發現火苗已經危在旦夕,只好投鼠忌器。幸好狐假虎威的爸爸呼盧喝雉叫來店員抱薪救火,終於死灰復燃,也讓如坐針毯的我們中飽私囊。鳥盡弓藏後,我們一家子酒囊飯袋,沆瀣一氣,我和妹妹更是小人得志,沾沾自喜。

不料結帳的時候,老闆露出廬山真面目,居然要一飯千金,爸爸氣得吳牛喘月,媽媽也委屈地牛衣對泣。

啊!這三生有幸的國慶日,就在爸爸對著錢包自慚形穢大義滅親後,我們全家江郎才盡,一敗塗地! ~ the end ~


2015/2/6

新手該學什麼語言作入門:javascript

朋友貼這個連結給我:http://blog.turn.tw/?p=1283 ,他說覺得有點有趣。

關於新手該學什麼語言作入門,其實我想過。

對於新手來說最困難的不是程式。

最困難的是建立可執行程式的環境。

所以首選絕對是 javascript!

不用安裝IDE,直接用chrome 按 F12 切到 console 就能寫。

如果你要存檔,記事本也能寫,學會後立刻可以作 chrome 外掛,瞬間變潮潮!

學會 javascript 之後再來就是學HTML ,可以在 dropbox 的 public 空間放自己做好的 HTML 檔,馬上成為朋友圈內第一個學會作網頁的人!

入門容易,又可以混口飯吃的語言不多,javascript至少還可以混個10年飯,何不學 javascript?

需要安裝的語言 / 資料庫完全不適合新手阿。

如果你說 javascript 能作的事太少,其實只要學會 jsonp,後台可以全用別人(朋友)的,基本上想做什麼還是能作得出來。

2014/12/11

【問題】 MVC的網站架構中 Model 的最佳實作

我認知中的MVC,是在看完 Stanford University 的 Developing iOS 7 Apps 這堂課之後才完整建立的。
http://youtu.be/ZqKbN_C4Yvg?t=14m20s
從14分到30分講MVC架構。


假設我有三個畫面,要顯示同一個 Table 的內容
第一個畫面需要 Table join A1 才能拿到足夠多的資訊
第二個畫面需要 Table join A2
第三個畫面需要 join A1 跟 A2

如果我要用一個 Model 層把 view 跟 DB 隔開,那我該提供哪些函數?

方法1:
只寫一個取出所有欄位的函數
Model.GetData   (WithA1 And A2)
缺點是會取到多餘的欄位

方法2:
為了解決方法1的問題,分別寫3個不同的SQL
Model.GetData
Model.GetA1
Model.GetA2
好處是我不會取到多餘的欄位
缺點是DB request 的次數會變多

方法3:
為了解決方法2的問題,分別寫3個不同的SQL
Model.GetDataWithA1
Model.GetDataWithA2
Model.GetDataWithA1AndA2
好處是我不會取到多餘的欄位,每次要取資料的時候只會產生1次DB request
缺點是,每當View 需要不同的欄位數的時候,我就要多作一個函數,會造成函數數量爆炸和管理困難,其實這樣寫的結果就等於是在View層上面寫SQL


問題是,一般情況下遇到這個問題會用什麼方法來解?為什麼選擇這個方法?

我問了幾個人答案都是採用方法1,是不是我想太多了?

2012/4/30

程式的命名規則

因為這個東西寫了很久
一邊寫程式一邊進步
一進步就改變程式風格
又沒有良好維護 code 的時候
程式碼就會有風格不統一的情形

然後程式的命名就亂了
我在想要怎樣命名才是最佳解

我採用的事件流程是CJSignal

我的signal命名規則 :

signal的命名應該是 時間+名詞+動詞 的形式
比方說
onMouseClick
beforeMouseClick
afterMouseClick
onViewChange

函數本身則是避免使用這樣的形式
函數應該使用 動詞 or 動詞+名詞 的形式
比方說
mouseClick.add(onMouseClick);  //這樣不好
onMouseClick.add(mouseClick);  //這樣不好
onMouseClick.add(handleMouseClick);  //這樣比較好

函數名稱盡量要跟函數內容有關 而不是跟函數執行的時間點有關

onMouseClick.add(goToHappyEnding);  //這樣更好




2012/4/13

actionscript 修改 package 造成 svn 差異比對失效

svn 是版本控制軟體

他能幫你做程式碼的差異備份 但是前提是檔案名稱要相同

當我修改 Class1.as 的 package 路徑時

我被迫要移動  Class1.as 到正確的資料夾路徑 (對應 package)

因為移動檔案會被分解為刪除檔案和新增檔案這兩個動作

而刪除的檔案與新增的檔案無關

結果造成 svn 無法與先前版本的 Class1.as 作差異比對了

完全不曉得要怎麼解決這個問題


上次龍哥的意見是說把修改 package 的事情記錄在 svn 的版本說明裡

至少這樣還找得到先前的位置

不曉得有沒有其他更好的解法

2011/7/1

debug技巧

Q:如果想要知道某個函數被那些人(Class)呼叫過,是在第幾行被呼叫的?

A:幫函數多加一個必填的參數,造成呼叫時會產生error
  於是編譯時就可以看到所有呼叫他的人都會Error: Incorrect number of arguments,而且會顯示第幾行