2017年1月24日 星期二

[學習筆記] Touch 3D介紹

這篇文章是看完線上讀書會的3D Touch教學後寫下來的筆記,
原始的讀書會影片可以從Youtube上進行觀看。


Touch 3D是iOS 9以上,需要6S以上的機型才有支援的硬體新功能

主要功能有:

  • Quick Actions - 主畫面重壓app圖示彈出選單
  • Peek and Pop - 預覽及彈出新的視窗
  • Pressure Sensitivity - 壓力感應

Quick Action

Quick Action可以用 info.plist的方式建立,但是不建議,因為:

  1. 寫在info.plist不好寫 -> 要一個一個key
  2. 不能用code動態更新內容

用Code的方式要在app裡加入Quick Action很簡單,只要在appDelegate裡的程式進入點中,替UIApplication.shared.shortcutItems這個array加入新的shortcut選項功能:

UIApplication.shared.shortcutItems = 
[
    UIApplicationShortcutItem(
        type:”mic”,
        localizedTitle:”麥克風”,
        localizedSubtitle:”這是測試”,
        icon:UIApplicationShortcutIcon(type:.audio),
        userInfo:[“swift讀書會”:20161201]
    ),
    UIApplicationShortcutItem(
        type:”love”,
        localizedTitle:”平等對待”,
        localizedSubtitle:”改變歧視現實”,
        icon:UIApplicationShortcutIcon(type:.love),
        userInfo:[“世界人權日”:20161210]
    )
]

上面的範例會在app用力點擊時,生成一筆Title為麥克風平等對待二筆資料清單,變數type可以供開發者進行使用者點擊的判斷,icon用來顯示的icon名稱,iOS 9.1 以後內建的icon比較多(Icon樣式可以參考這裡),userInfo則是可以加入額外的參數。Quick Action有一些功能上的限制就是只能顯示四組,但可以建立無限多組。
從選單點選時程式的進入點會在:

func application(_ application:UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler:@escaping (Bool)->Void)

如果app沒有開啟,可以在didfinihsLaunching裡從

launchOptions?[UIAppliationLaunchOptionKey.shortcutItem] as? UIAppliationLaunchOptionKey

抓取key值判判是從那一個地方進來的

Peek and Pop

Peek可以讓使用者進行預覽的動作,Pop是使用者在peek預覽時再用力按下就會讓畫面直接跳到預覽的頁面,使用方式要先在所在頁面裡加入UIViewControllerPreviewingDelegate的protocol,同時實作二個func:

//peek
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location:CGPoint) -> UIViewController?{
    let index = previewingContext.sourceView.tag - 1000
    let vc = webVC()   
    return vc
}

//pop
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController){
    nav.pushViewController(viewControllerToCommit, animated: true)

}

想在Peek往上滑動時加入選單,可以在Viewcontroller裡加入previewActionItems,這部分我沒有特別去實作,因為目前還沒有需要去實作這樣的功能。

結論

Touch 3D的實作上還滿容易的,我看完整個讀書會的影片後就可以把Touch 3D基本的Quick Action及Peek、POP的功能加入到現有在開發的app中,這個預覽的功能其實還滿方便的,Touch 3D好像也可以運用在推播的功能上,不過影片好像沒有特別介紹,未來可以再花點時間研究看看。

2016年12月31日 星期六

2016年度回顧

一年又過去了,又到了年底的這個時間點,每一年還是要做一下回顧,看一下今年自己做了那些事,在新的一年裡也準備新的展望及新的開始。下面就回顧一下今年買了什麼及做了什麼事吧....

工作方面:

考了iOS初級證照

就在二寶出生之前,我也順利的拿到了經濟部的iOS初級證照,雖然考這張證照只是為了升遷用,不過對自己也算是基本的能力驗證吧。

合寫了GIS 年刊

和同事合寫了年刊,分享了iOS的離線圖台技術,雖然某部分而言也是為了升遷,但至少也讓自己有花了一點時間整理自己的東西。

寫了GIS月刊

也因為升遷的需求(前面這幾件事都算是吧XD),也投稿了月刊,分享了Github的教學文章,相關的內容也分享到了自己的blog裡,這算是2016年寫最認真的文章吧,2016年文章的產量真的少的可憐....

工作升遷

完成了前面的幾項任務,最終也達成了升遷的條件,很感謝主管的提拔讓我能順利的升職,來到這裡也十年了,雖然嚐試過當SA,但最後還是覺得自己還是喜歡技術、喜歡Coding,也謝謝主管的支持,讓我可以當一個高級PG.......XD

生活上的變化

二寶小蘋果出生

四月的時候迎來我的二千金-小蘋果,她也夠折騰的,讓媽媽在醫院裡安胎一個多星期,也讓老爸我在年初就把假都快請光了,平安順利的來到人世

買了什麼??

看了下面的清單,2016年也花了不少錢丫.....

買了Herman Miller 人體工學椅 Embody Chair

年初的時候因為不滿意現在公司坐的椅子,所以就狠下心來敗了這張椅子,這張椅子坐起來真的滿舒服的,坐下去以後會不想起來,雖然還是會定期起來上廁所,效率上有一定的提升,因為身體不會因為坐的不舒服而動來動去的,屁股也不再酸痛了,也算是一筆不錯的投資啦.....XD

買了Apple Watch Series 2

因為年前老婆有禮劵,所以趁我生日的時候就入手了,我是一個不喜慣在身上帶東西的人,所以手錶很久之前就沒有再戴過了,因為這一代的apple watch有支援了GPS,終於可以不用帶手機去跑步了(後來因為空汙越來越嚴重,也沒什麼出門跑步了><),剛開始使用時還有些不習慣,不過一下子就感受到它帶來的方便,而且在外面用手錶講電話帥氣度破表丫,用siri來設鬧鐘跟提醒也很方便,還有每小時的站立提醒是一個讓我離開Embody Chair的好工具,但它在第三方的app的開啟上還是不夠快速,但通知的功能很夠用,Line跟簡訊也可以直接用手錶回,還是一項不錯的科技產品。

換了iPhone 7 Plus

iPhone 6 Plus也用了二年,電信合約也到期了,入手apple watch的同時也用公司的企業方案入手了iPhone 7 Plus,5.5吋的用習慣以後就很難再回去小畫面的手機了,新的手機也支援了Touch 3D等新的硬體功能,讓我可以用來測試自己寫的app(這是一個很好換手機的理由XD)

** 再見了2016 ,你好2017 **

期待明年的自己有更好的進步!!

2016年9月2日 星期五

Social Coding ~ GitHub使用介紹

本文是我發表在公司月刊上的文章,介紹如何使用GitHub來參加開源專案或是自己開一個新的專案~沒使用過GitHub的朋友可以參考看看。

前言

GitHub是目前最火紅的程式碼管理庫,以前工程師在撰寫程式往往都只有一個人或是小小的一個團隊進行程式開發,程式在開發的過程中可能只有自己或是少數幾個人進行交流,這樣的方式是比較封閉的,能夠讓腦力激盪出的火花有限,由於GitHub的興起提供了一個程式交流的平台,工程師們可以開放他們所撰寫的程式和軟體開源放到GitHub上,讓其他人來進行使用,當使用過這些軟體後,別的工程師可能發現到程式可以改進的地方,可以讓這些程式或軟體的功能變的更好用、更強大,於是也幫忙開始撰寫程式,透過GitHub這個平台大家可以相互的溝通、交流,當你的程式碼有改動時,其他有在關注的人可以收到程式變更的訊息,當你的程式有bug時,會有人主動回報給你,GitHub也提供了很多社交網路具有的功能:例如:按讚、關注、評論...等。儼然形成了一個很大的社群,大家在上面進行程式開發、討論,當你有一個很棒的主意,架構了一個很好的系統,但是你一個人可能沒辦法很快的完成它,就好像你設計了一個很精美的建築,你自己一個人可能要花上好幾十年的時間才能完成所有的工作。但是如果有世界上其他很厲害的人一起來幫你一起打造,也許只要花幾個星期或是幾個月的時間就可以完成它。這就是Social Coding的魅力,集合眾人之力一同打造更好的軟體或系統。

身為一個工程師的我們有滿腔的熱血想要協助別的工程師進行開發,但是要怎麼入門呢?本篇文章就用一個實際的例子來教導大家如何運用GitHub來進行Social Coding。

新增儲存庫

當在GitHub上找不到合適的專案,自己就可以建立一個屬於自己的開源專案,在GitHub頁面中有一個"New repository",點選之後就會進入到新增的頁面中(如圖1所示),輸入所要建立的儲存庫名稱,選擇是否要建立專案的README說明文件,還有是否直接加入.gitignore及專案的授權方式(如:GPL、MIT License...等),按下"Create repository"即可建立屬於你自己的專案。
圖1 新增儲存庫

README.md說明文件

GitHub在新增遠端儲存庫時,會詢問是否要新增一個readme.md(如圖1所示),這是一個使用Markdown語法的文件,Markdown是用來作為一種網路內容的寫作用語言,它運用一些簡單的符號來協助建立標題等格式化的排版功能,讓文件更容易閱讀、編寫,相關的語法可以參考:1(Markdown文件),當你建立了一個新的儲存庫後,就可以編寫README.md,把跟這個儲存庫相關的資訊寫在這個檔案中,就可以在GitHub的首頁中看到這個被編譯排版過的Markdown的文件內容(如圖2所示),因為它是顯示在首頁的內容中,若你建立一個良好的readme說明文件,其他使用者搜尋進入到你的端遠儲存庫頁面時,就可以很容易了解你專案的目的、用途及如何使用它。
圖2 README.md

尋找及加入專案

GitHub裡面資源非常多,也由於資源太豐富了,想要找到你要的資訊可以透過一些簡單的搜尋技巧來幫忙:
1. 基本搜尋:當開啟Github的首頁時,最上方就有一個Search bar,只要輸入關鍵字就可以搜尋到跟關鍵字相關的管理庫(repo)。
2. 搜尋檔案中的關鍵字:當想要找管理庫(repo)的檔案中有某些關鍵字時,可以在搜尋列中先輸入關鍵字,空一格後加入in:file,即可針對檔案來進行搜尋的動作。
3. 搜尋檔案名稱及路徑:也可以針對檔案名稱及路徑進行搜尋,只要在搜尋列中輸入filename:檔案名稱即可搜尋有該檔案名稱的管理庫(repo);在搜尋列中輸入path:路徑名稱即可搜尋有該路徑名稱的管理庫(repo)。
4. 搜尋某個程式語言的關鍵字:當想要針對某個程式語言進行搜尋,可以在關鍵字後面空一格後加入language:語言名稱(例:language:c++),就可以只搜尋該語言的關鍵字相關的管理庫(repo)資訊。
透過這些搜尋技巧可以快速的找到自己想要專案。

Clone & Fork

當在GitHub上看到了一個很不錯的專案,想要把儲存庫(Repository)複製回到自己本機來進行程式開發,GitHub上有二種方式來進行:Clone和Fork,這二方式有什麼差異呢?很多第一次使用GitHub的人一定都會有這樣的疑問,Clone的指令是從遠端的儲存庫上把所有的內容全部複製回到自己的本機,建立自己本機的儲存庫及工作目錄;而Fork指令是把對方的遠端儲存庫複製一份到自己遠端的儲存庫裡,並且在新建的遠端儲存庫中留下來源端的連結, Fork是在遠端進行與本地端無關,若要把資料複製回自己的本機則還需要再下Clone指令把內容複製回來,這二者的差異在直接Clone對方的儲存庫,若你沒有編寫的權限,那就無法再將自己修改的程式碼提交回去;而Fork別人的儲存庫等同於建立一份自己的遠端儲存庫,你就可以自由的在自已的儲存庫上進行提交更新。Fork回來的專案可以從專案的網頁上看出這個專案Fork的來源出處(如圖3所示)。
圖3 Fork來出處及如何建立合併請求

Pull Request

前面提到的使用Fork可以建立自己遠端的儲存庫,並進行程式提交及更新,但當你在自己遠端儲存庫上完成自已的程式及提交後,如何把這個更新提交貢獻給原來的作者呢?可以使用Pull Request功能來發送一個合併請求(如圖3所示),按下New pull request後,GitHub會先進行儲存庫比對,檢查要合併的分支是否會有衝突,若沒有程式碼衝突就可以在下方描述你的程式修改說明,請對方可以看一下你所撰寫的程式碼,並可以告訴原作者你修改了那些項目內容,這些內容是對原專案有幫助的,請他合併進入到他的專案中(如圖4所示)。
圖4 合併請求

程式審查

當新增完pull request,儲存庫的開發者便會收到通知,他可以連進到該儲存庫的管理頁面中針對你的提交進行Code Review,查看你的程式碼是不是開發規範及對這個專案是不是真的有幫助,若有幫助他就會把你的程式碼合併(merge)到他的儲存庫中(如圖5所示),這個pull request是以一個討論串的型式,作者群跟專案相關的開發者都可以在這個討論串進行發言表達意見,也可以幫忙協助進行程式碼審查的工作,若你的程式碼可能有些部分需要再進行修改,開發者也可以針對這些內容的部分,給你一些建議請你再進行修改,修改完成後符合原作者的要求,他就會把你的程式合併進他的儲存庫,當你對這個專案貢獻度越來越高時,原作者也可以邀請你直接加入專案一起進入開發,這個時候你就可以直接對原作者的儲存庫進行直接的PUSH及PULL,也可以幫助其他開發者進行程式審查及提供意見,當然還是要符合作者所定訂的開發規範來進行協同合作。
圖5 pull request合併

問題追蹤(Issue Tracking)

程式在開發上總是會有新的需求或是Bug的出現,當這些問題發生時若能有個地方可以做資訊匯整及記錄,那就可以進行簡單的專案管理,在GitHub上就提供了問題追蹤(Issue Tracking)的功能,當你使用專案時發現這個專案有Bug或是你對這個專案有比較好的功能性建議,都可以透過問題追蹤的功能來與專案的開發者進行溝通,使用的方式很簡單直接點選專案端遠儲存庫網頁上的Issues的頁籤,按下New issue並輸入問題的標題及內容描述來新增問題追蹤(如圖6所示),若是Bug回報最好能提供詳細的操作步驟,讓開發者可以更快的找到問題的發生點,盡快的幫你解決這個問題,每個Issue都是一個討論串的形式,每個關心這個專案的人都可以加入討論及回覆。
圖6 新增問題追蹤

每個問題都會有一個問題的編號,問題追蹤的功能也可以結合git的程式碼提交(commit),當開發者收到這個問題回報,針對這個問題進行程式開發修改完成後,透過程式碼提交(commit)時,在提交的提交訊息(message)中可以加入"closed #問題編號"或是"fixed #問題編號",代表這次的提交(commit)修正了這個問題,當提交被推送(PUSH)回後端儲存庫時,提交訊息裡所標示的問題編號的問題就會被關閉(如圖7所示),當然開發者也可以從問題頁面中直接手動的方式將問題關閉,代表這個問題討論串己經結束了。
圖7 提交關閉問題

總結

透過上述的介紹,可以了解到Social Coding在GitHub的運作流程,透過Fork及Clone等功能,可以很輕易就取得別人開發好的完整程式專案;透過pull request及issue tracking等功能,讓每個對專案有興趣的人都可以加入討論並且進行協同合作,讓專案可以一直的迭代、改進變的更加完整。Social Coding讓你不再是一個人開發程式,而是可以找到一群志同道合的工程師一起討論、一起開發,完成許多又好又棒的開源程式,相信大家也忍不住想大顯身手一番了吧?趕快開啟GitHub網站,一起進入這個Social Coding的美妙世界吧!

2015年11月10日 星期二

Git學習資源介紹

跟大家分享幾個我在學習Git時,覺得不錯的Git學習資源

30 天精通 Git 版本控管: https://github.com/doggy8088/Learn-Git-in-30-days

Will保哥之的大作,從Git的結構跟原理開始介紹怎麼使用Git,可以幫你理清很多觀念很值得一讀,保哥也開過相關的課程,可以帶領新手很快入門,有機會可以去上一下,會很有收獲哦~

Git 版本控制系統:https://ihower.tw/git/index.html

作者是在台灣上教Git的數一數二的大師ihower寫的,我看了他很多簡報,滿能幫助理清觀念的,可以依教材的順序往下看,再搭配中間的簡報及blog的文章,這也是大推學習Git的好地方!

Pro Git : http://iissnan.com/progit/index.zh-tw.html

這本應該可以算是Git的聖經本,裡面很詳細的介紹各種Git的使用技巧,有些部分寫的比較文言一點,算是比較深入的書,可以選擇你要的章節看,等你學習到一定的程度想再更加精進,再回來看其他的章節

LearnGitBranching:http://pcottle.github.io/learnGitBranching/

這是一個做中學(Learn by doing)的網站,一步步依指示教導git的使用,建議是先把保哥及ihower裡先研讀一篇再來這裡實作會更有效果哦

Code School :https://www.codeschool.com/paths/git

Code School也是一個標榜做中學的網站,不只是用影片先教導你觀念,再來會用練習的方式讓你更加了解剛才影片裡教導的觀念及技巧,不過除了Try Git課程外,其他課程是付費才可以觀看,不過目前因為他被另一家程式教學網站(pluralsight)併購了,現在推出三天免費的優惠,可以趁這三天好好的把其他課程一次學完......XD

連猴子都能懂的Git入門指南:http://backlogtool.com/git-guide/tw/

連猴子都懂了,你應該也會吧?網站用了很多圖文來教你使用Git,不過我覺得在觀念沒有講的很深入,但還是滿值得看的

GIT教學: http://kingofamani.gitbooks.io/git-teach/

這個應該是新北市教研中心-程式設計班的課程教材,內容也不錯也可看一看,不過好像還沒寫完,有些章節還不完全

TortoiseGit + GitHub : https://www.youtube.com/watch?v=73lJ6hcWMho&list=WL&index=4

講英文的不太懂,國語的又講不好,那用台語來介紹Git李共賀唔賀,這是在youtube上找到的一個用台語教你如何使用TortoiseGit及GitHub的教學影片,作者講話的方式有濃濃的台味,看了會讓你會心一笑:)

再分享幾個git的簡報資料....

















 

以上是我學習Git覺得不錯的幾個網站,如果有新的再補上來,也歡迎大家有看到不錯的網站也可以分享上來~~3Q

2015年10月11日 星期日

[Swift][UIView _accessibilitySetNavigationControllerInset:]: unrecognized selector sent to instance

這二天開發iOS程式遇到的一個奇怪問題
我完全用手刻去產生版面,沒有使用storyeboard及nib,用SnipKit做Constraints
今天寫一個新的頁面,只要一下拉就會出現
-[UIView _accessibilitySetNavigationControllerInset:]: unrecognized selector sent to instance 0x7f8c01686980
google了半天也找不到問題,做了好多測試都還是一樣.....
後來把宣告的變數全都改一下名稱(全部都在一個i)就沒有問題了
我在想可能是我的變數名跟其他程式裡宣告的名稱可能重覆了吧.....
但是怎麼找都找不到....@@
特此記錄一下

2015年5月15日 星期五

ios憑證過期如何重簽ipa而不用重compiler

最近遇到一個需求,要把別人做好但憑證己過期的ipa檔案,用我們自己的apple帳號重新簽署發行,原本以為不可行,原來還真的可以,記錄一下參考來源及步驟
本篇參考這篇文章的作法:http://dev.mlsdigital.net/posts/how-to-resign-an-ios-app-from-external-developers/

建立APP ID

首先如果你沒有App ID你必需申請一個新的app ID,因為我們拿別人的ipa檔所以它的app ID是綁在對方的帳號裡,為了要重新簽署,所以我們要新增一個自己的app ID,在apple developer portal下點選左邊的Identitifiers->App IDs功能選項進行到App ID的管理頁面,點選右上的"+"來新增App ID
iOS_App_IDs_-_Apple_Developer.png
依指示輸入App ID的名稱
Register_-_iOS_App_IDs_-_Apple_Developer.png
App ID Suffix選擇Explicit App ID並輸入Bundle ID,Bundle ID不能跟原來的一模一樣哦,因為這個app ID必需是唯一的,名稱取一樣apple也不會給你過的
Register_-_iOS_App_IDs_-_Apple_Developer 2.png
下方的App Services依你的需求來做選擇,如果需要推播就把Push Notification選項給勾起來,好了以後就可以點選下面的Continue來完成新增App ID

新增Provisioning Profiles

接下來用剛才新增的App ID來建立Provisioning Profile,點選portal左邊的Provisioning Profile選項進行到管理頁面,點選右上的"+"來新增Provisioning Porfile
iOS_Provisioning_Profiles_-_Apple_Developer.png
設定好你要的Profile發布方式,然後按Continue
Add_-_iOS_Provisioning_Profiles_-_Apple_Developer.png
接下來選取剛才新增的App ID,然後按Continue,完成新增Provisioning Profile
Add_-_iOS_Provisioning_Profiles_-_Apple_Developer 2.png
新增完成後就可以點選Download來把Provisioning Profile下載回來,點二下安裝到Xcode裡
iReSign_provisioning_profile.png

建立Entitlements Plist

在你的mac本機裡,開啟你最愛的編輯器新增一個檔案,檔名為entitlements.plist,內容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>PREFIX.yourappBundleID</string>
    <key>aps-environment</key>
    <string>production</string>
    <key>get-task-allow</key>
    <false/>
    <key>keychain-access-groups</key>
    <array>
        <string>PREFIX.yourappBundleID</string>
    </array>
</dict>
</plist>

再回到Apple Developer portal裡的App IDs選項裡,找到你新增的那筆App ID,點開後可以看到PREFIX及BundleID的值,把這二個值取代掉entitlements.plist的PREFIX.yourappBundleID的值

# 執行iReSign app
到GitHub下載iReSign程式

iReSign

下載後直接點二下執行程式,依程式指示輸入你的ipa的路徑、Provisioning profile的路徑、entitlements.plist的路徑,如果Bundle ID有改的話,請把Change ID打勾並在左邊輸入新的Bundle ID(這裡要跟你上面申請新的Bundle ID一致),下拉選單選擇你要執行簽署的apple帳號,設定完成後按下ReSign!
iReSign_和_blog_和_blog.png
如果沒有問題的話就可以在原本ipa的路徑下找到被Resign過新的ipa檔案,可以直接把ipa放你的新的裝置上測試看看囉~

2015年5月4日 星期一

iOS App不同狀態下的推播處理方式

最近在進行iOS程式開發時遇到的推播問題,特此記錄一下
我程式的需求是在收到推播後,針對推播的收到的內容進行頁面的切換
依App的狀態,推播發生時會有下面三種狀況:

1. App在背景執行的情況下收到推播    

這個情況就是一般的情況,推播會透過didReceiveRemoteNotification來進行處理

2. App在執行的情況下收到推播    

在App開啟的情況下收到推播,這種情況下推播也是會透過didReceiveRemoteNotification來進行處理,但通常就不會有推播的音效及跳出訊息,使用者收到推播時會不知道自己有收到推播,因此可以在didReceiveRemoteNotification裡進行app狀態的判斷後,加入其他提醒方法來讓使用者知道有推播發生

3. App在未開啟的情況下收到推播

在App未開啟的狀態下,收到推播後會透過推播來進行開啟App的動作,但是就不會執行didReceiveRemoteNotification,因此在這種情況下需要在AppDelegate的didFinishLaunchingWithOptions裡的launchOptions來進行判斷

針對三種狀況進行推播判斷的程式碼如下:

swift程式碼:
AppDelegate_swift_—_Edited.png

obj-c程式碼:
AppDelegate_m_—_Edited.png

2013年12月31日 星期二

2013年已讀書單

列一下2013年看過的書,今年看的書還滿雜的,有小說、管理類、經營.....
因為買了Kindle Paperwhite、裝了多看閱讀,大陸的書相對於台灣便宜很多,後來就直接在多看上直接買書看了
2013還有很多待看的書都還沒看呢,真的要趕快好好的補一下進度了
習慣也要改變一下,不要東看一下西看一下,不能好好的收吸

書籍

  • 做自己
  • 台灣軟體產業的失落十年
  • 29張當票 2:當舖裡特有的人生風景
  • MacTalk·人生元编程
  • 波西傑克森﹣神火之賊
  • 我是个算命先生
  • 29張當票
  • 20個月賺130億:YouTube創始人陳士駿自傳
  • 康師傅中國兵法:頂新魏家教你世界規格集團戰略
  • 海底撈你學不會
  • 全中國最窮的小伙子發財日記

雜誌

  • Cheers 1~12月

預祝新年快樂~~
希望2014年會更好

2013年11月12日 星期二

Design Pattern - 6大設計原則

單一職責原則(Single Responsibility Principle)

  • 定義
    • There should never be more than one reason for a class to change
    • 應該有且僅有一個原因引起類別的變更
  • 好處
    • 類別的複雜性降低,實現什麼職責都有清晰明確的定義
    • 可讀性提升。複雜性降低,可讀性當然提升
    • 可維護性提升
    • 變更引起的風險降低

里氏替換原則

  • 繼承
    • 優點
      • 程式碼共享,減少創建類別的工作量,每個子類別都擁有父類別的方法和屬性
      • 提升程式碼的重用性
      • 子類別可以形似父類別,但又異於父類別
      • 提升程式碼的可擴展性
      • 提升產品或專案的開放性
    • 缺點
      • 繼承是侵入性的,只要繼承就必須擁有父類別的所有屬性和方法
      • 降低程式碼的靈活性。子類別必須擁有父類別的屬性和方法,讓子類別自由的世界多了些約束
      • 增強了耦和性。當父類別的常數、變數和方法被修改時,必需要考慮子類別的修改,而且在缺乏規範的環境下,這種修改可能會帶來非常糟糕的結果﹣大量的程式碼需要重構
  • 定義
    • If for eachobject p1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T
      如果對每一個型別為S的物件o1,都有型別為T的物件o2,使得以T定義的所有程式P在所有的物件o1都替換成o2時,程式P的行為沒有發生變化,那麼型別S就是型別T的子型別
    • Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
      所有參照基礎類別的地方必須能透明地使用其衍生類別的物件
  • 含義
    1. 子類別必須完全實作父類別的方法
    2. 子類別可以有自已的個性
    3. 覆寫或實作父類別的方法時輸入參數可以被放大
    4. 覆寫或實作父類別的方法時輸出結果可以被縮小

倚賴倒置原則(Dependence Inversion Principle,DIP)

  • 定義
    • High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should not depend upon abstractions.
    • 高層模組不應讓倚賴低層模組,兩者都應該倚賴其抽象
    • 抽象不應該倚賴細節
    • 細節應該倚賴抽象
  • 倚賴的三種寫法
    1. 構造函式傳遞倚賴物件
    2. Setter方法傳遞倚賴物件
    3. 介面聲明倚賴物件

物件導向基礎

以前看大話程式設計整理的物件導向基礎,現在剛好在重看就順便把它再整理一下囉~


物件(Object)

  • 一個獨立自主的實體,用一組可識別的特性和行為來標示

類別(Class)

  • 具有相同之屬性和功能的物件的抽象集合

實體(instance)

  • 一個真實的物件
  • 實體化就是建立建件的過程,使用new關鍵字來建立

建構式(constructor)

  • 又叫建構函式,其實就是對類別進行初始化。
  • 建構式與類別同名,無返回值
  • 所有類別都有建構式,若無定義,系統會自動產生空的建構式;若有定義,則預定的建構式就會失效

方法重載(Overload)

  • 提供建立同名的多個方法的能力,這些方法需使用不同的參數類型
  • Overload方法名相同,參數類型或個數要有所不同
  • Overload可在不改變原方法的基礎上,新增功能

屬性(Property)

  • 一個方法或一對方法,但在調用它的程式碼看來,它是一個欄位,即屬性適合於以欄位的方式使用方法調用的場合
  • 欄位是儲存類別要滿足其設計所需要的資料,欄位是與類別相關的變數
  • 屬性有二個方法get和set
    • get存取器返回與宣告的屬性相同的資料類型,調用時可以得到內部欄位的值或參考
    • set存取器沒有顯示設定參數,但它有一個隱式參數,用關鍵字value表示,它的作用是調用屬性時,可以給內部的欄位或參考賦值

封裝(Encapsulation)

  • 每個物件都包含它進行操作所需要的所有資訊,物件不必依賴其他物件來完成自已的操作
  • 好處
    • 良好的封裝能夠減少耦合
    • 類別內部的實現可以自由的修改
    • 類別具有清晰的對外介面

繼承(Inheritance)

  • 物件的繼承代表了一種“is-a"的關係
  • 繼承者可以理解為是對被繼承者的特殊化,它除了具備被繼承者的特性外,還具備自已獨有的個性
  • 繼承定義了類別如何相互關聯,共用特性
  • 父類別和子類別,或叫基礎類別和衍生類別,其中子類別繼承父類別的所有特性,還可以定義新的特性
    • 子類別擁有父類別非private的屬性和功能
    • 子類別具有自已的屬性和功能
    • 子類別還可以用自已的方式實現父類別的功能(方法重寫)
  • 優點
    • 繼承使得子類別公共的部分都放在父類別,使得程式碼得到共用,避免了重覆
    • 繼承可使得修改或擴展繼承而來的實現都較為容易
  • 缺點
    • 父類別變動,子類別也不得不變
    • 繼承會破壞包裝,父類別實現細節暴露給子類別
  • 繼承是一種類別與類別之間強耦合的關係
  • 當二類別之間具備“is-a"的關係時,就可以考慮用繼承

修飾子

  • Public
    • 所修飾的類別成員可以允許其他任何類別來存取
  • Protected
    • 子類別可對基礎類別有完全的存取權
  • Private
    • 只允許同一個類別中的成員存取

多型(Polymorphism)

  • 不同的物件可以執行相同的動作,但要透過它們自已的實現程式碼來執行
  • 特性
    • 子類別以父類別的身份出現
    • 子類別在工作時以 自已的方式來實現
    • 子類別以父類別的身份出現時,子類別特有的屬性和方法不可以使用
  • 子類別將父類別的實現替換為自已的實現,這就是方法重寫(Override),或者叫方法覆寫
  • 多型的原理是當方法被調用時,無論物件是否轉換為其父類別,都只有位於物件繼承的最末端的方法實現會被調用,也就是說,虛擬方法是按照其執行時類型,而非編譯時類型進行動態繫結調用

2013年10月31日 星期四

無瑕的程式碼心得記錄(一)

這篇是無瑕的程式碼的心得筆記.....

有意義的命名

  • 讓名稱帶表意圖
    • 讓名稱名符其實
  • 避免誤導
  • 產生有意義的區別
  • 使用能唸出來的名稱
  • 使用可被搜尋的名字
  • 避免編碼
  • 避免思維的轉換
    • 清楚明白才是王道
  • 類別的命名
    • 使用名詞或名詞片語命名
  • 方法的命名
    • 使用動詞或動詞片語
  • 不要裝可愛
    清楚闡述比起娛樂價值來的重要
  • 每種概念使用一種字詞
    Ex:取得方法不要fetch、retrieve又get
  • 別說雙關語
  • 使用解決方案領域的命名
  • 使用問題領域的命名
  • 添加有意義的上下文資訊(context)
  • 別添加無理由的上下文資訊

函式

  • 簡短
  • 只做一件事
  • 每個函式只有一層抽象概念
    • 降層準則
      • 由上而下閱讀程式碼
  • 使用具描述能力的名稱
  • 函式的參數
    • 參數數量
      • 最理想是零個
      • 其次是一個
      • 盡量避免超過三個參數
    • 物件型態的參數
      • 可減少參數的數量
    • 輸出型的參數
      • 避免使用
  • 動詞和關鍵字
    • 替函式取個好名稱可產生許多良好的附加價值
  • 要無副作用
    • 一次只做一件事,不要在函式底下偷做其他事
  • 指令和查詢要分離
    函式要能做某事或能回答某個問題,但二者不該同時發生
  • 使用例外處理取代回傳錯誤
    • 錯誤處理就是一件事
  • 不要重覆自己(DRY)
  • 結構化程式設計
    • 每個函式及函式裡的區塊都應該只有一個進入點及一個離開點
    • 不能有break或continue敍述
    • 永遠不能有goto敍述
  • 如何寫出這樣的函式
    • 像寫文章一樣
      • 初稿通常粗糙而雜亂無章
      • 重新組織整個文章段落,將文章改善至你要的樣子

註解

  • 不要替糟糕的程式碼寫註解—重寫它
  • 註解無法彌補糟糕的程式碼
  • 用程式碼表達你的本意
  • 有益的註解
    • 法律型註解
    • 資訊型註解
      • 透過註解提供一些基本資訊是非常有用的
    • 對意圖的解釋
    • 闡明
      • 把難解的參數或回傳值翻譯成具有可讀性的文字
    • 對後果的告誡
      • 做為一種警告
    • 待辦事項註解
    • 放大重要性
  • 糟糕的註解
    • 喃喃自語
    • 多餘的註解
      • 有時候程式碼本身就可以提供明白的意圖,加了註解反而比程式碼更難理解
    • 誤導型註解
      • 不精確讓人看不懂
    • 規定型註解
      • 因為規定加上去的註解,有時候反而會產生更多困惑或造成散亂的程式結構
    • 日誌型註解
      • 現在有好的原始碼管控系統,可以不需要
    • 干擾型註解
      • 某些註解毫無用處,只會干擾
  • 可以使用函式或變數時就別使用註解
  • 位置的標誌物
  • 右大括號後面的註解
  • 出處及署名
  • 被註解起來的程式碼
  • 非區域性的資訊
  • 過多的資訊
  • 不顯著的關聯
  • 函式的標頭
    • 為小型函式選一個好的名稱,通常比「將註解寫在函式標頭」來的更優

編排

  • 編排的目的
    • 讓程式碼更具可讀性
  • 報紙的啟發
    • 頭條的敍述
    • 概要
    • 全文細節
  • 垂直的編排
    • 概念間的垂直空白區隔
      • 用空白來分隔不同的思緒
        • 宣告
        • 引用類別庫
        • 不同函式
    • 垂直密度
      • 程式密切相關的程度
        • 密切相關的程式應該垂直緊密,不要被無用的註解或其他的程式碼切開其關聯性
    • 垂直距離
      • 具類似的概念應盡可能的靠近
      • 變數宣告
        • 應盡可能靠近變數使用的地方
      • 實體變數
        • 應被宣告在類別的上方
      • 相依的函式
        • 如果A函式呼叫了B函式,那麼這二個函式在垂直編排上要盡可能靠近
      • 概念相似性
        • 概念上有相似性質的程式碼盡可能的相近
      • 垂直的順序
        • 呼叫敍述應在被呼叫函式的上方
  • 水平的編排
    • 水平的空白間隔和密度
      • 高度相關及完全不相關的事情,都可以利用水平的空白將之分開
      • 設定運算子(assignment operators)
      • 強調運算子的優先權
    • 水平的對齊
      • 沒有必要
      • 長度會太長
    • 縮排
      • 階層結構
      • 讓視野層次結構更顯而易見
      • 違反縮排的規則
        • 有時候因if、while或簡短的函式想違反縮排的規則
        • 盡量不要
      • 空視野範圍
        • While或for迴圈的程式是空白
        • 確保空白區塊也被縮排,否則很容易被誤導
  • 團隊的共同準則
    • 統一的編排規則

物件及資料結構

  • 資料抽象化
  • 資料/物件的反對稱性
    • 結構化的程式碼容易添加新的函式,而不需要變動已有的資料結構。而物件導向的程式碼,容易添加新的類別,而不用變動已有的函式。
    • 結構化的程式碼難以添加新的資料結構,因為必須改變所有的函式。物件導向的程式碼難以添加新的函式,因為必須改變所有的類別。
  • 德摩特爾法則(The Law of Demeter)
    • 類別C內的方法f,應該只能呼叫以下事項的方法
      • C
      • 任何由f所產生的物件
      • 任何當作參數傳遞給f的物件
      • C類別裡的實體變數所持有的物件
    • 方法不該呼叫「由任何函式所回傳之物件」的方法
  • 資料傳輸物件(Data transfer Objects,DTO)
    • 最佳的資料結構形式
    • 類別裡只有公用變數,沒有任何函式

2013年10月21日 星期一

[MS SQL]如何透過Database Mail進行郵件發送

Microsoft SQL Server裡提供了Database Mail可以用來設定外部的email,當主機有問題或是有發送Email需求時,就可以透過Database Mail來進行發送,設定方法如下:

開啟SQL Server Management Studio並連到SQL Server上,點開管理選項找到Database Mail,在Database Mail選項上按右鍵開啟選單,選擇設定Database Mail

dbmail1.png

dbmail2.png

dbmail3.png

dbmail4.png

dbmail5.png

dbmail6.png

dbmail7.png

dbmail8.png

dbmail9.png

dbmail10.png

dbmail11.png

如果有收到Email表示Database Mail設定成功囉~~

那要如何在用SQL進行Email發送呢?

直接執行下面的SQL指令
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'mail sender', --這裡輸入Database Mail設定檔的名稱
@recipients = 'test@mail.com', --要發送的Email
@body = 'Email本文內容', --Email的本內容
@body_format = 'HTML', --本文的格式,設定為HTML,在Email的本文內可以使用HTML語法
@subject = 'Email主旨' ; --這裡設定Email 主旨

這樣就可以發送Email了,是不是很簡單呢?
如果要在網頁程式或應用程式中發送Email,可以直接在程式中EXECUTE上面的SQL語法,就可以把Email發送出去了,用Database Mail這種做法發送Email還有一個優點,就是可以查到Email發送的記錄,只要執行下面的SQL就可以查詢到Email的發送記錄

   SELECT * FROM [msdb].[dbo].[sysmail_mailitems]

2013年10月20日 星期日

改變人生,從跑步開始~讀後心得

改變人生,從跑步開始~讀後心得

0425f6b89.jpg

最近從圖書館裡借了幾本有關跑步的書,最近剛好把改變人生,從跑步開始看完了,簡單的來寫一下心得,這本書不是教導跑步技巧的書,我覺得比較像一本勵志的書,作者班‧戴維斯 (Ben Davis)原來本是一個大胖子,每天的生活就是吃,因為胖讓他極度的缺乏自信,讓他無法跟人群相處,每每生活上有什麼不如意就用吃來發洩,而這是種惡性循環讓他吃更多、變更胖,活在這樣生活裡無法自拔,直到有一天家庭聚會上,奶奶問了他一句:「班,你快樂嗎?」點醒了他,讓他決定進行了do life—好活人生,開始了他的馬拉松生涯,也改變了他的人生。

書裡我得到幾個心得:

  1. 家人是重要的支柱 :
    不論你在做什麼事,有家人的支持及幫忙真的是一件很重要的事,班如果沒奶奶的那句話來讓他覺悟;如果沒有父親在他已經要放棄第二次的長跑時,陪著他一起參加比賽,我想班可能又要走回頭路;如果沒有哥哥陪著他一路參加比賽,憑自已一個人的參加比賽,一定也很難撐到最後。所以家人是最重要的支柱,支持你可以努力向前的動力之一。

  2. 堅持 :
    做什麼事都一樣要能堅持下去,很多時候我們有滿腔熱血的要開始進行某件事,但是往往只有前面幾次可以努力做到,到後面可能因為工作忙碌或其他的藉口就不了了之,所以要能有所堅持。班一開始跑出了興趣,但是差一點又因為心裡有障礙(覺得自已無法完成十公里的賽事)差點就放棄了,還好有父親的幫忙才又再跑下去,我一開始跑步也是有同樣的狀況,前幾個星期很熱血的想天天起來晨跑,跑了幾天之後就開始慢慢的偷懶了,還好心裡一直有個聲音告訴自已,為了健康要趕快運動,督促自已要去進行,到後面變成了一種習慣,養成了興趣你就有所改變了..

痛苦是有限的,折磨也是有限的,只要撐下去,就會度過難關。
如果你這一輩子都活得舒舒服服,就永遠不會經歴鼓舞你的時刻。

共勉之~

[Javascript] Array操作方法

javascript中Array的幾個常用到的方法:

  • concate()

在原本的array中,產生新的Array副本並將參數值加入到新的Array中,其結果不會影響到原來的Array內容。

    
  var users = ["jonn","keny","jeffrey"];
  var users2 = users.concat("frank","joe");

  //原始的array內容不受影響 ["jonn", "keny", "jeffrey"]
  console.log(users);
  //新的array為原始的array + 參數內容 ["jonn", "keny", "jeffrey", "frank", "joe"]
  console.log(users2);
    
  • slice()

  • splice()
    splice跟slice不同,只差一個字母很容易讓人家搞混了,splice()的主要用途是
    向數組的中部插入項,但使用這種方法的方式則有如下3種。
    刪除:可以刪除任意數量的項,只需指定2個參數:要刪除的第一項的位置和要刪除的項數。例如,splice(0,2)會刪除數組中的前兩項。
    插入:可以向指定位置插入任意數量的項,只需提供3個參數:起始位置、0(要刪除的項數)和要插入的項。如果要插入多個項,可以再傳入第四、第五,以至任意多個項。例如,splice(2,0,"red","green")會從當前數組的位置2開始插入字符串"red"和"green"。
    替換:可以向指定位置插入任意數量的項,且同時刪除任意數量的項,只需指定3個參數:起始位置、要刪除的項數和要插入的任意數量的項。插入的項數不必與刪除的項數相等。例如,splice (2,1,"red","green")會刪除當前數組位置2的項,然後再從位置2開始插入字符串"red"和"green"。

2013年10月16日 星期三

晨跑新記錄~11K達成!

PR

昨天晚上把之前看了一半的改變人生,從跑步開始:甩掉120磅、啟動新生活的汗水旅程又拿起來看,看到11點多剩下最後一章就上床睡覺了,不知道是不是受到了書的影響,今天早上五點就醒來上廁所,回到床上翻了一下睡不太著,於是就起身把書最後一章給看完了(沒想到太早起來還把老婆給吵醒了),吃了半根的香蕉補充了一下體力,五點半左右就準備要動身出門去跑步了,一般時候我都是六點起床然後出門跑步,今天比平常多半個小時出門,心裡想著:今天應該可以多跑一點吧....

外面涼風陣陣,終於比較有秋天的感覺了,雖然這樣的天氣跑步感覺有點涼,但不過還是比大熱天好很多,跑起來也還滿順的,前5K一下子就過了,跑步的過程當中心裡還想著Do Life書中的作者都可以在一年內就完成那麼長的賽事,我想我應該也可以完成,於是心裡就燃起了要跑10K的心,一般我大概能跑到7K左右,其實這個距離讓我撞牆撞很久,一直都無法突破,參加岱宇的9.27K算是那段時間的最長距離了,而且那天跑完我整個人都虛脫了,除了吃不下飯還喝了好幾瓶運動飲料,直到上個星期我才第一次突破了10K的距離,短短的一個星期又再挑戰了第二次10K,這次其實沒有什麼覺得很困難的,過了7K之後還是很順,身體沒有什麼不舒服的感覺,但是到了8K多的時候就開始有點疲累感了,但是還是可以撐的下去,心裡想著:_都跑到這個階段了,好不容易離新記錄這麼近了,我一定可以完成的。_所以就這樣完成了11K囉~~

我覺得跑步最重要的就是意志力吧,很多時候其實我們是可以達到目標的,但也很容易因為意志不堅定一下子就放棄了,這樣子真的很可惜,跑步除了讓我體力變好,我也是在鍛鍊我的意志力,學習不要輕易的放棄,一步一腳印的跑下去,一點一滴的累積你的努力,只要撐過去就有美好的勝利果實在等待著你。