顯示具有 Design pattern 標籤的文章。 顯示所有文章
顯示具有 Design pattern 標籤的文章。 顯示所有文章

2015年8月27日 星期四

使用newInstance來初始化Fragment (Android的一百種奇技淫巧)

原文出處:Using newInstance() to Instantiate a Fragment

問題: 使用new MyFragment()MyFragment.newInstance() 有什麼不同?哪個比較好?
答: 使用newInstance()比較好,兩個原因:
1. 方便使用者使用。
2. 
通過強制宣告一個static factory method去迫使使用者提供良好定義的行為,
並能同時確保使用者免受錯誤的初始化時機,使用者不再需要擔心不小心忘了初始化的參數或錯誤的使用。
I recently came across an interesting question on StackOverflow regarding Fragment instantiation:
What is the difference between new MyFragment() andMyFragment.newInstance()? Should I prefer one over the other?
Good question. The answer, as the title of this blog suggests, is a matter of proper design. In this case, the newInstance() method is a "static factory method," allowing us to initialize and setup a new Fragment without having to call its constructor and additional setter methods. Providing static factory methods for your fragments is good practice because it encapsulates and abstracts the steps required to setup the object from the client. For example, consider the following code:
public class MyFragment extends Fragment {

    /**
     * Static factory method that takes an int parameter,
     * initializes the fragment's arguments, and returns the
     * new fragment to the client.
     */
    public static MyFragment newInstance(int index) {
        MyFragment f = new MyFragment();
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);
        return f;
    }

}
Rather than having the client call the default constructor and manually set the fragment's arguments themselves, we provide a static factory method that does this for them. This is preferred over the default constructor for two reasons. One, it's convenient for the client, and two, it enforces well-defined behavior. By providing a static factory method, we protect ourselves from bugs down the line—we no longer need to worry about accidentally forgetting to initialize the fragment's arguments or incorrectly doing so.
Overall, while the difference between the two is mostly just a matter of design, this difference is really important because it provides another level of abstraction and makes code a lot easier to understand.
Feel free to leave a comment if this blog post helped (it will motivate me to write more in the future)! :)

2015年8月25日 星期二

ysl-好用的 Activity.getView()(Android的一百種奇技淫巧)

原文出處:好用的 Activity.getView()

在 Activity 中最常看到的函式呼叫,就是 findViewById(),常見用法如下:

TextView tv = (TextView)findViewById(R.id.my_text_view);
...
ImageView iv = (ImageView)findViewById(R.id.preview);

由於 findViewById() 傳回的是 View 這個通用型別。因此實務上每次都要強制轉型成實際的型別,這樣的程式碼看起來實在有點礙眼。

要解決這樣的問題,你只要在 Activity 中,加入底下這個 getView() 函式。

public final <E extends View> E 
getView(int id) 
{
    return (E)findViewById(id);

}


之後,你就可以將原先的 findViewById() 呼叫改寫成底下這個方式:


TextView tv = getView(R.id.my_text_view);
...
ImageView iv = getView(R.id.preview);


一個小技巧,卻可以讓你的程式碼看起來清爽許多。當然在 Fragment 中,你也可加上自己的 getView(),至於如何寫?建議自己研究一下。

2015年4月21日 星期二

設計模式(自我測試版本,撰寫中)

  試著以我的語言來解釋不同設計模式:

題目是由非關語言: 設計模式這裡去出

Chapter A: Creational 模式 
  根據我對Design pattern的理解,Creational主要是探討建立物件設計之間的一些方法,這些方法可以幫助我實做一個新的物件時,更精確達成我所想要達成的目標。
  1. Simple Factory 模式
      這個模式簡而言之,就是隱藏一個具體物件的細節設定。
    例如我如果在程式中建立了一個蘋果,那我應該將其內容如「顏色」、「口感」、「重量」...,都在建構子裡面處理掉,而不是讓第一次撰寫程式的人員花時間去了解這些設定的意思,及如何去設定他。
  2. Abstract Factory 模式
      這個模式蠻令我映象深刻的,因為我剛開始求職時,遇到一位面試官出了這題,請用一個for迴圈印出圓形、方形、三角形的圖案,那時的我還沒有經驗,學生時期也沒有碰過設計模式的相關概念,只好殘念下一間。
      簡而言之,這個模式就是使用不同物件繼承一個抽象類別,然後在使用這個抽象類別的時候可以讓各自的不同物件按照自己設定的情況去執行。
      例如:馬、貓、狗,都是動物,因此都繼承在動物的類別下,我們可以依據每個動物去實作他跑的細節,但最後程式執行時只要寫,動物跑即可。
  3. Factory Method 模式
      這個模式的概念是在設計的過程中,先將程式的大綱寫好,在實際實做的時候再補充細節,譬如我寫一篇文章先把起、承、轉、合的綱要擬好,然後再開始寫這幾個章節的內容。
      通常這個模式我都是在程式寫完後,才思考哪些功能是可以抽出來集合在一起的Factory,比較少在寫的過程中去思考可以先寫這個模式,然後在補充內容。
  4. Builder 模式
      我覺得連結中的比喻非常好了(暫時想不到比迷宮更能描述的說法),這個模式比較注重的是建立的子物件其內容比較完整,不像Abstract Factory還有留白的空間,這個比較適合已經確定子物件有哪些,然後透過排序或種種的使用方法去使用這些物件的時候。
  5. Prototype 模式
      這個建立物件的概念,其實就是實做繼承物件中不同的參數之間的窗口,例如我在專案中曾經遇過從韌體傳來的參數方式 跟資料庫所需要的資料格式不同,但資料是同一份,那我就必須在繼承的同時,告訴這個物件你的某某資料,他需要繼承的是父類別的某某資料,並且應該如何複製。
  6. Singleton 模式
      這個模式簡而言之就是設定一個程式中的全域變數,程式中的每個地方都能呼叫這個變數,而且不會有不一樣的數值﹔反之,每個地方都可能改變這個變數。
  7. Registry of Singleton 模式
      有時候我們希望這個全域變數是可以被註冊,被誰?在甚麼時候?因為甚麼事情?而註冊,然後在程式結束的時候可以取消這個註冊之類的情境即需要這個設計概念。