2019年4月27日 星期六

這兩周開始寫 Android 程式

寫下來的心得是,API Level 會搞死人!!

看來設定 Android 專案開發時,要先定死 API Level,不然有些開發人員用了新版,有些用舊的,那就玩不完,或者是玩完了!!!

2016年7月19日 星期二

Learning JavaScript Design Patterns 筆記 6

The Mixin Pattern

不透過繼承的方式,將其它物件的部分 method 「拿來使用」。此模式主要目的是「程式碼重用」。但也因為如此,會讓物件關係變得比較混亂。因此,如果沒有必要,這模式最好少使用。可能的使用時機是,「除錯」或是,太複雜的原程式碼只能透過借用的方式處理。

使用 underscorejs 的 extend

// 要被「借用method」的物件
var myMixins = {
  moveUp: function(){ /* ... */ },
  moveDown: function(){ /* ... */ },
  stop: function(){ /* ... */ }
};

// 借用方
function CarAnimator(){
  this.moveLeft = function(){ /* ... */ };
} 
 
// 將 myMixins 的方法給借用方
_.extend( CarAnimator.prototype, myMixins );
 
var myAnimator = new CarAnimator();
// 使用「借用」的method
myAnimator.moveLeft();
myAnimator.moveDown();
myAnimator.stop();


另外此部分有提供只借用部分method的方式,但將欲借用的method,當作第三個參數以後傳入。可是這個function只有定義兩個參數,雖然javascript可以用這樣的方式來接收「多」出來的參數作處理,但最好還是定義第三個參數,直接處理比較好。免得日後還要猜第三個未定義的參數,到底是什麼意思。

// t: targetClass, s:sourceClass, m:methods array
function augment(t, s, m) {
    // 只需部分 methods
    if (m) {
        for (var i=0; i < m.length; i++ ) {
            t.prototype[m[i]] = s.prototype[m[i]];
        }
    }
    // 將 s 的 all methods 傳給 t
    else {
        for (var mName in s.prototype ) {
            if ( !Object.hasOwnProperty.call(t.prototype, methodName) ) {
                t.prototype[mName] = s.prototype[methodName];
            }
        }
    }
}

// 使用方式
augment(target, source, ["methodA", "methodB"]);
augment(target, source);

2016年7月17日 星期日

Learning JavaScript Design Patterns 筆記 5

The Command Pattern

原文中,此部分只是把一個存在的物件,另外包起來而已,應參考Command pattern的實作方式。分成下列三個物件:
  • 管控命令的物件(Invoker):
    • 加入、記錄、執行Command的物件。
    • 可將 Command 的實例「抽出」成一個 String 對應的參數,如此在 Client 端就完全不需知道實際使用到的 Receiver Class
  • 命令物件(Command):
    • 均實作Command Interface,有共同的一個method -- execute
    • 由 Invoker 呼叫 execute。
  • 執行命令的物件(Receiver)
    • 在 Command 的 execute 中,實際運作的物件。
    • 這些物件可能有不一樣的constructor,不一樣的參數設定,但都需在 Command execute 之前,建構完成。
範例可直接參考 Wiki 
圖例可參考 Google 查詢


The Facade Pattern 

「表面」模式 ,將「特定」物件複雜的API,透過表面模式,包裝成一個較易於了解和使用的物件。如 JQuery 把許多複雜的判斷 DOM 操作,變成單一 method 呼叫,例如 $(el).css(),$(el).animate()。

表面模式的使用,要從 Client 的角度來看,由於複雜物件及 API ,在使用上可能需一步一步設定,才能達到「某」特定功能。而對 Client 端,它「只」需這「某」特定功能。故透過表面模式,將此「某」特定功能「包」起來,讓 Client 直接使用。

效能注意,以JQuery為例,直接使用 getElementById("identifier") 比 $("#identifier") 快很多很多

發射飛彈的流程 ,每一層都可用表面模式
  • 對發射控制官而言,它需要長官確認,核對密碼,插入Key等等一連串動作,最後讓長官按發射鈕。但他不用去管實際飛彈要發射或發射時的一連串機械動作。
  • 對長官而言,他只需要總統的命令,將密碼提供給發射官,最後按按鈕。
  • 對總統而言,只是打個電話,要求發射飛彈。


The Factory Pattern

不直接使用 new ,而是透過這個 Factory pattern 來取得物件實例,何時使用:
  • 當建立此物件實例的過程很繁雜
  • 需依環境需求,同一物件需有不同的參數設定時
  • 當共用相同properties的許多小物件時
  • 建立同interface但不同的實例實作時
Abstract Factory Pattern v.s. Factory Pattern
  • Abstruct Factory Pattern 將物件的生成,用一個Class處理。因此個別實作的 Factroy 可產生個別的物件。
  • Factory Pattern 將物件的生成,用一個Method處理,所以只能針對特定物件的生成作處理。 
參考 Abstract Factory

2016年7月12日 星期二

Learning JavaScript Design Patterns 筆記 4

The Mediator Pattern

透過中介者,將多個物件的運作及處理流程寫在其中,例如飛機彼此的通訊,全通過塔台統一處理,而不是由個別的飛機互相溝通。

Mediator:
  • 處理流程主要由此處理
  • 協調個別執行的物件
  • 此模式使用到的物件,彼此多少有關係,才會有處理流程可放在Mediator中

Event Aggregation:
  • 處理流程主要藉由 event 傳給由各個Subscriber處理
  • 本身不含處理流程
  • 像是 JQuery 的 on,可以讓個別的 HTML 元件,透過這個 on 而有自己的 event 處理機制
  • 物件彼此間較無直接關連


The Prototype Pattern

The GoF refer to the prototype pattern as one which creates objects based on a template of an existing object through cloning.

使用 Object.create 的方式,在原有的程式(物件)上,產生新的物件。
實作方式應採用 Javascript OOP 最佳實作 ,此篇主要介紹 prototype 的概念。

Javascript 標準及一些 API

You-Dont-Need-jQuery
You-Dont-Need-Lodash-Underscore

由於最近幾年,隨著 Browser 「再次」大戰 ,Google Chrome 取得了主導的地位。而 Javascript 也在「這幾年」開始有進一步的標準,及許多新的原生標準 API 出現。使得原先為解決功能不足而產生的 js lib,突然間許多 API 都有原生版本。也因此開始有人提倡使用新的 Javascript 標準 API 來寫作 js 。

其實,要求已經使用這些 js lib 的人改回用原生 API 的作法,就算新寫的程式可以,舊版的及早期開發完成的系統,也很難逐一修改。這之中比較適當的作法,應該是在新版 js lib 中,把原生 API 包進去,把那些不適宜的部分,予以註記不再使用 (deprecated),這樣應該會比較好。

Vanilla JS 很有趣,把需要的功能全部選一選,結果下載的vanilla.js,檔案大小為「零」。意思就是,直接用 browser 提供的 javascript 即可,也就是用標準的 javascript API 就對了。

Learning JavaScript Design Patterns 筆記 3

Publish/Subscribe Implementations

pubsubz/pubsubz.js

key point:
publish(topic, args): 執行特定topic的所有subscriber的func,並將參數args傳入
subscribe(topic, func): 將特定topic跟func綁定,以便publish中使用
unsubscribe: 移除 subscriber

Usage:
// 要綁定的 func
var mlog = function (t, d) { console.log(t+ ": " + d);};
// 綁定 topic (inbox/newMessage) 跟 mlog
var subscription = pubsub.subscribe("messagee", mlog);
// publish !
pubsub.publish("message", "hello world!");
pubsub.publish("message", ["test", "a", "b", "c"]);

2016年7月11日 星期一

Windows 7 沒事自動開機的解決辦法

查看已設定喚醒電腦的裝置
powercfg /devicequery wake_armed

查看可程式喚醒電腦的裝置
powercfg /devicequery wake_programmable

1. powercfg -lastwake 查看是誰起動 windows.
2. 裝置管理員 -> 內容 -> 電源管理 -> 取消勾選「允許這個裝置喚醒電腦」
3. 控制台 -> 電源選項 -> 目前電源計劃 -> 變更計劃設定 -> 變更進階電源設定 -> 睡眠 -> 允許喚醒計時器 -> 停用

參考 Powercfg 命令列選項