Prototype Pattern
名稱由來
不是利用類來產生實例對象,而是從一個對象實例產生出另一個新的對象實例 ,根據被視為原型的對象實例 ,建立起的另一個新的對象實例就稱為原型模式(Ptototype Pattern)。
?
需求場景
?
- 種類過多無法整合成類時
第一種情形:若須處理的對象種類太多,如果要一個個設成不同的類,須產生大量的源程序文件 - 不容易利用類產生對象實例時
第二種情形:該對象的實例產生過程太復雜,很難利用類來建立。 - 希望把框架和所產生的對象實例分開時
第三種情形:希望讓產生對象實例時的框架不會只存在于某些特殊類時。
功能演示
?
測試程序類結構圖如下:
模式UML圖中,共有三個類:
- 接口,Product 己聲明抽象方法use 和 createClone的接口
- 管理類,Manager 利用createClone 復制對象實例的類
- 普通類,MessageBox 把字符串框起來use 的類,實現Product的createClone 和use 方法。
Product 接口
?
????public?abstract?String?use(String?s);
????
????public?abstract?Product?createClone();
}
有了Product 接口 ,才可能進行復制。這個接口繼承java.lang.Cloneable 接口 ,利用clone 方法可自動對實現此接口 的類進行復制。
use 方法是“使用”的部分,“使用”代表何種意義則需看子類的實現。
createClone方法負責復制對象實例的部分。
Manager類
?
????private?Hashtable<String,?Product>?showCase?=?new?Hashtable<String,?Product>();
????public?void?register(String?name,?Product?proto)?{
????????showCase.put(name,?proto);
????}
????public?Product?create(String?protoName)?{
????????Product?p?=?showCase.get(protoName);
????????return?p.createClone();
????}
}
唯一跟其他類溝通的橋梁,負責添加和負責對象的實例。
?
MessageBox類
?
????private?char?decochar;
????public?MessageBox(char?dechar)?{
????????this.decochar?=?dechar;
????}
????@Override
????public?Product?createClone()?{
????????//?TODO?Auto-generated?method?stub
????????Product?p?=?null;
????????try?{
????????????p?=?(Product)?clone();
????????}?catch?(CloneNotSupportedException?e)?{
????????????//?TODO:?handle?exception
????????????e.printStackTrace();
????????}
????????return?p;
????}
????@Override
????public?String?use(String?s)?{
????????//?TODO?Auto-generated?method?stub
????????int?length?=?s.getBytes().length;
????????StringBuffer?sb?=?new?StringBuffer();
????????for?(int?i?=?0;?i?<?length?+?4;?i++)?{
????????????sb.append(decochar);
????????}
?
????????sb.append(decochar?+?"\n\""?+?s?+?"\"\n"?+?decochar);
????????for?(int?i?=?0;?i?<?length?+?4;?i++)?{
????????????sb.append(decochar);
????????}
????????sb.append("");
????????return?sb.toString();
????}
}
?
createClone 方法是復制本身的方法,這里所調用的clone 方法規定在java 語言規格內,它會產生另一個分身(本身的復制品)。在產生復制品時,若該字段包含對象實例,則其值也會跟著復制到新的對象實例。能利用clone 方法進行復制的只限于實現java.lang.Cloneable 接口 的類。如無實現則會報異常。但MessageBox 本身實現了Product ,而Product 是己經繼承了Cloneable接口。
Java 語言的clone 方法只能從本身的類(含子類)調用,所以如果是其他類的要求而進行復制時,則須另以其他方法(如createClone)把clone 抓起來。
?
android 界面入口測試該原型 Prototype 的PrototypeActivity
?
????/**?Called?when?the?activity?is?first?created.?*/
????@Override
????public?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.main);
????????((Button)?findViewById(R.id.Button01))
????????????????.setOnClickListener(new?OnClickListener()?{
????????????????????@Override
????????????????????public?void?onClick(View?v)?{
????????????????????????//?TODO?Auto-generated?method?stub
????????????????????????Manager?manager?=?new?Manager();
????????????????????????MessageBox?messageBox?=?new?MessageBox('*');
????????????????????????manager.register("prototype",?messageBox);
????????????????????????Product?product?=?manager.create("prototype");
????????????????????????((EditText)?findViewById(R.id.EditText01))
????????????????????????????????.setText(product.use("android?ap?Pattern"));
????????????????????}
????????????????});
????}
}
?
運行效果如下:
?
源碼下載:
原型模式
?
再發個求職信息:
求職android(可勝任Framework及 以上工作。一年半經驗) 、Windows Phone 7(軟件、XNA) 開發工作。
?