亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android源碼學習之工廠方法模式應用及優勢介紹

2020-04-11 12:36:11
字體:
來源:轉載
供稿:網友
工廠方法模式定義
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
定義一個用于創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。

常用的工廠方法模式結構

   


如上圖所示(截取自《Head First Design Patterns》一書),主要包括四個部分:
抽象產品類Product負責定義產品的共性,實現對事物抽象的定義;Creator是抽象創建類,也就是抽象工廠,具體如何創建產品類是由具體的實現工廠ConcreteCreator完成的。其中在《Head First Design Patterns》對工廠方法模式做了細節的說明,原文如下:
As in the official definition, you'll often hear developers say that the Factory Method lets subclasses decide which class to instantiate. They say “decides” not because the pattern allows subclasses themselves to decide at runtime, but because the creator class is written without knowledge of the actual products that will be created, which is decided purely by the choice of the subclass that is used.

工廠方法模式有什么優勢呢
良好的封裝性,代碼結構清楚。一個對象創建具有條件約束的,如果一個調用者需要一個具體的產品對象,只要知道這個產品的類名就可以了,不用知道創建對象的過程,降低模塊間的耦合。

可擴展性好。在增加產品類的情況下,只要適當的修改具體的工廠類或擴展一個工廠類,就可以完成。
屏蔽產品類。產品類的實現如何變化,調用者都不需要關心,它只需要關心產品的接口,只要接口保持不變,系統中的上層模塊就不用改變。因為產品類的實例化工作是由工廠類負責的,一個產品對象具體由哪一個產品生成是由工廠類決定的。此外工廠方法模式是典型的松耦合結構。高層模塊只需要知道產品的抽象類,其他的實現類都不用關系,符合迪米特法則、依賴倒置原則、里氏替換原則等。

在Android源碼中,ListActivity繼承自Activity,將Activity作為工廠方法,生成具有ListView特點的Activity,對ListActivity的說明如下:
An activity that displays a list of items by binding to a data source such as an array or Cursor, and exposes event handlers when the user selects an item.
ListActivity hosts a ListView object that can be bound to different data sources, typically either an array or a Cursor holding query results. Binding, screen layout, and row layout are discussed in the following sections.

Screen Layout
ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "@android:id/list" (or listif it's in code)

在Activity類中有這么一個函數
復制代碼 代碼如下:

/**
* This method is called after {@link #onStart} when the activity is
* being re-initialized from a previously saved state, given here in
* <var>savedInstanceState</var>. Most implementations will simply use {@link #onCreate}
* to restore their state, but it is sometimes convenient to do it here
* after all of the initialization has been done or to allow subclasses to
* decide whether to use your default implementation. The default
* implementation of this method performs a restore of any view state that
* had previously been frozen by {@link #onSaveInstanceState}.
*
* <p>This method is called between {@link #onStart} and
* {@link #onPostCreate}.
*
* @param savedInstanceState the data most recently supplied in {@link #onSaveInstanceState}.
*
* @see #onCreate
* @see #onPostCreate
* @see #onResume
* @see #onSaveInstanceState
*/
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
mWindow.restoreHierarchyState(windowState);
}
}
}

在注釋中“but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.”,英語不太好,但大致的意思是Activity子類可以重載這個函數來決定是否使用默認的實現。

在看子類ListActivity
復制代碼 代碼如下:

public class ListActivity extends Activity {
/**
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected ListAdapter mAdapter;
/**
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected ListView mList;
private Handler mHandler = new Handler();
private boolean mFinishedStart = false;
private Runnable mRequestFocus = new Runnable() {
public void run() {
mList.focusableViewAvailable(mList);
}
};
/**
* This method will be called when an item in the list is selected.
* Subclasses should override. Subclasses can call
* getListView().getItemAtPosition(position) if they need to access the
* data associated with the selected item.
*
* @param l The ListView where the click happened
* @param v The view that was clicked within the ListView
* @param position The position of the view in the list
* @param id The row id of the item that was clicked
*/
protected void onListItemClick(ListView l, View v, int position, long id) {
}
/**
* Ensures the list view has been created before Activity restores all
* of the view states.
*
*@see Activity#onRestoreInstanceState(Bundle)
*/
@Override
protected void onRestoreInstanceState(Bundle state) {
ensureList();
super.onRestoreInstanceState(state);
}
/**
* @see Activity#onDestroy()
*/
@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
/**
* Updates the screen state (current list and other views) when the
* content changes.
*
* @see Activity#onContentChanged()
*/
@Override
public void onContentChanged() {
super.onContentChanged();
View emptyView = findViewById(com.android.internal.R.id.empty);
mList = (ListView)findViewById(com.android.internal.R.id.list);
if (mList == null) {
throw new RuntimeException(
"Your content must have a ListView whose id attribute is " +
"'android.R.id.list'");
}
if (emptyView != null) {
mList.setEmptyView(emptyView);
}
mList.setOnItemClickListener(mOnClickListener);
if (mFinishedStart) {
setListAdapter(mAdapter);
}
mHandler.post(mRequestFocus);
mFinishedStart = true;
}
/**
* Provide the cursor for the list view.
*/
public void setListAdapter(ListAdapter adapter) {
synchronized (this) {
ensureList();
mAdapter = adapter;
mList.setAdapter(adapter);
}
}
/**
* Set the currently selected list item to the specified
* position with the adapter's data
*
* @param position
*/
public void setSelection(int position) {
mList.setSelection(position);
}
/**
* Get the position of the currently selected list item.
*/
public int getSelectedItemPosition() {
return mList.getSelectedItemPosition();
}
/**
* Get the cursor row ID of the currently selected list item.
*/
public long getSelectedItemId() {
return mList.getSelectedItemId();
}
/**
* Get the activity's list view widget.
*/
public ListView getListView() {
ensureList();
return mList;
}
/**
* Get the ListAdapter associated with this activity's ListView.
*/
public ListAdapter getListAdapter() {
return mAdapter;
}
private void ensureList() {
if (mList != null) {
return;
}
setContentView(com.android.internal.R.layout.list_content_simple);
}
private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
onListItemClick((ListView)parent, v, position, id);
}
};
}

其中復寫了函數onRestoreInstanceState(Bundle state),并在View中設置了默認的setContentView(com.android.internal.R.layout.list_content_simple);
復制代碼 代碼如下:

/**
* Ensures the list view has been created before Activity restores all
* of the view states.
*
*@see Activity#onRestoreInstanceState(Bundle)
*/
@Override
protected void onRestoreInstanceState(Bundle state) {
ensureList();
super.onRestoreInstanceState(state);
}
。。。
private void ensureList() {
if (mList != null) {
return;
}
setContentView(com.android.internal.R.layout.list_content_simple);
}

Activity中的setContentView()函數
復制代碼 代碼如下:

/**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
*
* @param layoutResID Resource ID to be inflated.
*
* @see #setContentView(android.view.View)
* @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initActionBar();
}
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
* view hierarchy. When calling this method, the layout parameters of the
* specified view are ignored. Both the width and the height of the view are
* set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use
* your own layout parameters, invoke
* {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
* instead.
*
* @param view The desired content to display.
*
* @see #setContentView(int)
* @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(View view) {
getWindow().setContentView(view);
initActionBar();
}
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
* view hierarchy.
*
* @param view The desired content to display.
* @param params Layout parameters for the view.
*
* @see #setContentView(android.view.View)
* @see #setContentView(int)
*/
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
initActionBar();
}


總結:Activity作為“工廠方法”,具體View中顯示什么由默認設置或者由子類來實現;ListActivity作為具體實現,它決定在View中顯示的是ListView;這里的View是Activity中的默認顯示,即為“Product”,而ListView是“ConcreteProduct”,由ListActivity來決定顯示。

除了ListActivity以外,還有ExpandableListActivity也是以Activity為工廠類,創建自己的顯示效果。
本人能力和時間有限(缺少“模式使用”內容,以后會添加),寫的很粗糙,恭候大家的批評指正,謝謝~~~
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
一道本无吗dⅴd在线播放一区| 国产成人精品999| 日韩精品免费综合视频在线播放| 最近2019年中文视频免费在线观看| 亚洲国产精品久久久久秋霞不卡| 欧美老妇交乱视频| 国产精品吴梦梦| 亚洲精品电影在线| 日韩高清人体午夜| 久久中文字幕视频| 亚洲电影免费观看高清| 国产国语videosex另类| 97精品欧美一区二区三区| www欧美xxxx| 亚洲天堂男人天堂| 欧美国产日韩一区| 日韩中文字幕在线播放| 久久精品美女视频网站| 国产精品一区二区电影| www.国产精品一二区| 国产午夜精品理论片a级探花| 国产精品美女无圣光视频| 日本精品性网站在线观看| 国产免费亚洲高清| 狠狠久久五月精品中文字幕| 亚洲xxx大片| 亚洲国产欧美一区二区丝袜黑人| 亚洲精品久久视频| 久久激情视频免费观看| 国产激情综合五月久久| 日韩中文字幕av| 亚洲国产成人91精品| 91九色综合久久| 中文字幕亚洲一区二区三区| 欧美电影免费看| 亚洲成人亚洲激情| 日韩精品免费综合视频在线播放| 91精品国产777在线观看| 欧美日韩免费观看中文| 日韩久久午夜影院| 国产精品亚洲片夜色在线| 欧美激情视频在线观看| 国产精品99久久久久久久久| 亚洲精品99久久久久| 欧美日韩性视频在线| 欧美激情一区二区三区高清视频| 这里只有精品在线观看| 性日韩欧美在线视频| 日韩一区二区三区国产| 国产亚洲欧美日韩美女| 久久青草精品视频免费观看| 日韩女优人人人人射在线视频| 欧美极品美女电影一区| 色噜噜狠狠色综合网图区| 国产69久久精品成人看| 亚洲精品综合久久中文字幕| 国产成人av在线播放| 色偷偷噜噜噜亚洲男人的天堂| 欧美一区二粉嫩精品国产一线天| 成人精品在线视频| 国产精品久久久久不卡| 亚洲精品视频二区| 日韩中文字幕久久| 欧美一区二区三区艳史| 中文字幕亚洲综合久久筱田步美| 亚洲天堂av图片| 欧美二区在线播放| 日韩中文字幕欧美| 亚洲欧美日本伦理| 中日韩美女免费视频网站在线观看| 欧美精品www在线观看| 久久九九有精品国产23| 欧美激情第99页| 欧美精品18videos性欧| 欧美日韩国产丝袜美女| 久久人人爽人人爽人人片av高请| 欧美视频在线观看免费| 国产日产欧美a一级在线| 2021国产精品视频| 国产精品久久久久久久久久久不卡| 青草成人免费视频| 国产激情999| 欧美精品videos| 久久影院免费观看| 狠狠操狠狠色综合网| 亚洲视频在线观看免费| 亚洲性猛交xxxxwww| 5566日本婷婷色中文字幕97| 国内自拍欧美激情| 这里只有精品在线观看| 久久九九国产精品怡红院| 51视频国产精品一区二区| 国产有码在线一区二区视频| 久久理论片午夜琪琪电影网| 亚洲最大福利视频| 奇米影视亚洲狠狠色| 欧美激情国产日韩精品一区18| 亚洲欧美制服另类日韩| 成人国内精品久久久久一区| 国产精品视频大全| 欧美乱大交xxxxx另类电影| 欧美精品一区在线播放| 中文字幕在线看视频国产欧美在线看完整| 欧美一区二区三区……| 久久久成人av| 国产成人91久久精品| 国产在线98福利播放视频| 欧美极品美女视频网站在线观看免费| 久久精品小视频| 国产福利视频一区二区| 亚洲精品免费一区二区三区| 精品无人区太爽高潮在线播放| 久久久久久中文| 欧美日韩中国免费专区在线看| 日韩在线视频免费观看高清中文| 国产精品大陆在线观看| 97在线视频精品| 日本免费在线精品| 久久久999精品视频| 91福利视频网| 欧美日韩高清在线观看| 97涩涩爰在线观看亚洲| 69av在线视频| 欧美成人精品激情在线观看| 久久在线精品视频| 98精品国产自产在线观看| 国产91色在线| 欧美大全免费观看电视剧大泉洋| 国语自产精品视频在线看抢先版图片| 亚洲一二在线观看| 久久网福利资源网站| 久久久久久这里只有精品| 欧美成人四级hd版| 91夜夜未满十八勿入爽爽影院| 欧美精品18videos性欧美| 国产亚洲欧洲黄色| 国产va免费精品高清在线观看| 国产亚洲欧美aaaa| 欧美国产视频一区二区| 亚洲午夜精品视频| 中文字幕日韩欧美精品在线观看| 亚洲国产三级网| 欧美黑人视频一区| 亚洲专区在线视频| 成人a在线观看| 亚洲美女黄色片| 国产日韩欧美中文| 国产精品美女www| 欧美日本高清一区| 国产精品91免费在线| 成人国产精品久久久| 在线日韩av观看| 国产精品免费观看在线| 国产在线a不卡| 欧美一级片一区| 国产精品视频白浆免费视频| 8090成年在线看片午夜| 亚洲午夜未满十八勿入免费观看全集| 亚洲91精品在线| 97超级碰碰碰久久久| 国产成人综合精品在线| 亚洲精品美女视频| 国产一区二区视频在线观看| 成人国产在线视频|