Skip to content

Commit 5ecfd28

Browse files
committed
适配器模型review
1 parent bd5811a commit 5ecfd28

File tree

1 file changed

+83
-105
lines changed

1 file changed

+83
-105
lines changed

design-mode/Structural-Patterns/Adapter-Pattern.md

Lines changed: 83 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424

2525

26-
26+
2727
在上图中可以看出,Adaptee类并没有sampleOperation2\(\)方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的:
2828

2929
模式所涉及的角色有:
@@ -82,7 +82,7 @@ public class Adapter extends Adaptee implements Target {
8282

8383

8484

85-
85+
8686
从上图可以看出,Adaptee类并没有sampleOperation2\(\)方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装\(Wrapper\)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
8787

8888
```java
@@ -168,53 +168,47 @@ JDK1.1 之前提供的容器有 Arrays,Vector,Stack,Hashtable,Properties,BitSet
168168
```java
169169
Vector v=new Vector();
170170
for (Enumeration enum =v.elements(); enum.hasMoreElements();) {
171-
Object o = enum.nextElement();
172-
processObject(o);
171+
Object o = enum.nextElement();
172+
processObject(o);
173173
}
174174
```
175175

176176
JDK1.2 版本中引入了 Iterator 接口,新版本的集合对(HashSet,HashMap,WeakHeahMap,ArrayList,TreeSet,TreeMap, LinkedList)是通过 Iterator 接口访问集合元素。
177177

178178
```java
179179
List list=new ArrayList();
180-
for(Iterator it=list.iterator();it.hasNext();)
181-
{
182-
System.out.println(it.next());
180+
for(Iterator it=list.iterator();it.hasNext();){
181+
System.out.println(it.next());
183182
}
184183
```
185184

186185
这样,如果将老版本的程序运行在新的 Java 编译器上就会出错。因为 List 接口中已经没有 elements\(\),而只有 iterator\(\) 了。那么如何将老版本的程序运行在新的 Java 编译器上呢? 如果不加修改,是肯定不行的,但是修改要遵循“开-闭”原则。我们可以用 Java 设计模式中的适配器模式解决这个问题。
187186

188187
```java
189-
public class NewEnumeration implements Enumeration
190-
{
191-
192-
Iterator it;
193-
public NewEnumeration(Iterator it)
194-
{
195-
this.it=it;
196-
}
197-
198-
public boolean hasMoreElements()
199-
{
200-
return it.hasNext();
201-
}
202-
203-
public Object nextElement()
204-
{
205-
return it.next();
206-
}
207-
public static void main(String[] args)
208-
{
209-
List list=new ArrayList();
210-
list.add("a");
211-
list.add("b");
212-
list.add("C");
213-
for(Enumeration e=new NewEnumeration(list.iterator());e.hasMoreElements();)
214-
{
215-
System.out.println(e.nextElement());
216-
}
217-
}
188+
public class NewEnumeration implements Enumeration {
189+
Iterator it;
190+
191+
public NewEnumeration(Iterator it) {
192+
this.it = it;
193+
}
194+
195+
public boolean hasMoreElements() {
196+
return it.hasNext();
197+
}
198+
199+
public Object nextElement() {
200+
return it.next();
201+
}
202+
203+
public static void main(String[] args) {
204+
List list = new ArrayList();
205+
list.add("a");
206+
list.add("b");
207+
list.add("C");
208+
for (Enumeration e = new NewEnumeration(list.iterator()); e.hasMoreElements(); ) {
209+
System.out.println(e.nextElement());
210+
}
211+
}
218212
}
219213
```
220214

@@ -225,63 +219,56 @@ NewEnumeration 是一个适配器类,通过它实现了从 Iterator 接口到
225219
在开发过程中,ListView的Adapter是我们最为常见的类型之一。一般的用法大致如下:
226220

227221
```java
228-
// 代码省略
229-
ListView myListView = (ListView)findViewById(listview_id);
230-
// 设置适配器
231-
myListView.setAdapter(new MyAdapter(context, myDatas));
222+
// 代码省略
223+
ListView myListView = (ListView) findViewById(listview_id);
224+
// 设置适配器
225+
myListView.setAdapter(new MyAdapter(context,myDatas));
232226

233227
// 适配器
234-
public class MyAdapter extends BaseAdapter{
235-
236-
private LayoutInflater mInflater;
237-
List
238-
<
239-
String
240-
>
241-
mDatas ;
242-
243-
public MyAdapter(Context context, List
244-
<
245-
String
246-
>
247-
datas){
248-
this.mInflater = LayoutInflater.from(context);
249-
mDatas = datas ;
250-
}
251-
@Override
252-
public int getCount() {
253-
return mDatas.size();
254-
}
228+
public class MyAdapter extends BaseAdapter {
255229

256-
@Override
257-
public String getItem(int pos) {
258-
return mDatas.get(pos);
259-
}
230+
private LayoutInflater mInflater;
231+
List<String> mDatas;
260232

261-
@Override
262-
public long getItemId(int pos) {
263-
return pos;
264-
}
233+
public MyAdapter(Context context, List<String> datas) {
234+
this.mInflater = LayoutInflater.from(context);
235+
mDatas = datas;
236+
}
265237

266-
// 解析、设置、缓存convertView以及相关内容
267-
@Override
268-
public View getView(int position, View convertView, ViewGroup parent) {
269-
ViewHolder holder = null;
270-
// Item View的复用
271-
if (convertView == null) {
272-
holder = new ViewHolder();
273-
convertView = mInflater.inflate(R.layout.my_listview_item, null);
274-
// 获取title
275-
holder.title = (TextView)convertView.findViewById(R.id.title);
276-
convertView.setTag(holder);
277-
} else {
278-
holder = (ViewHolder)convertView.getTag();
279-
}
280-
holder.title.setText(mDatas.get(position));
281-
return convertView;
282-
}
238+
@Override
239+
public int getCount() {
240+
return mDatas.size();
241+
}
242+
243+
@Override
244+
public String getItem(int pos) {
245+
return mDatas.get(pos);
246+
}
247+
248+
@Override
249+
public long getItemId(int pos) {
250+
return pos;
251+
}
283252

253+
// 解析、设置、缓存convertView以及相关内容
254+
@Override
255+
public View getView(int position, View convertView, ViewGroup parent) {
256+
ViewHolder holder = null;
257+
// Item View的复用
258+
if (convertView == null) {
259+
holder = new ViewHolder();
260+
convertView = mInflater.inflate(R.layout.my_listview_item, null);
261+
// 获取title
262+
holder.title = (TextView) convertView.findViewById(R.id.title);
263+
convertView.setTag(holder);
264+
} else {
265+
holder = (ViewHolder) convertView.getTag();
266+
}
267+
holder.title.setText(mDatas.get(position));
268+
return convertView;
284269
}
270+
271+
}
285272
```
286273

287274
我们知道,作为最重要的View,ListView需要能够显示各式各样的视图,每个人需要的显示效果各不相同,显示的数据类型、数量等也千变万化。那么如何隔离这种变化尤为重要。
@@ -294,27 +281,22 @@ Android的做法是增加一个Adapter层来应对变化,**将ListView需要
294281
ListView继承自AbsListView,Adapter定义在AbsListView中,我们看一看这个类。
295282

296283
```java
297-
public abstract class AbsListView extends AdapterView
298-
<
299-
ListAdapter
300-
>
301-
implements TextWatcher,
284+
public abstract class AbsListView extends AdapterView<ListAdapter>
285+
implements TextWatcher,
302286
ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
303287
ViewTreeObserver.OnTouchModeChangeListener,
304288
RemoteViewsAdapter.RemoteAdapterConnectionCallback {
305289

306-
ListAdapter mAdapter ;
290+
ListAdapter mAdapter;
307291

308292
// 关联到Window时调用的函数
309293
@Override
310294
protected void onAttachedToWindow() {
311295
super.onAttachedToWindow();
312296
// 代码省略
313297
// 给适配器注册一个观察者。
314-
if (mAdapter != null
315-
&
316-
&
317-
mDataSetObserver == null) {
298+
if (mAdapter != null&&
299+
mDataSetObserver == null){
318300
mDataSetObserver = new AdapterDataSetObserver();
319301
mAdapter.registerDataSetObserver(mDataSetObserver);
320302

@@ -327,7 +309,7 @@ ListAdapter
327309
mIsAttached = true;
328310
}
329311

330-
/**
312+
/**
331313
* 子类需要覆写layoutChildren()函数来布局child view,也就是Item View
332314
*/
333315
@Override
@@ -336,18 +318,14 @@ ListAdapter
336318
mInLayout = true;
337319
if (changed) {
338320
int childCount = getChildCount();
339-
for (int i = 0; i
340-
<
341-
childCount; i++) {
321+
for (int i = 0; i<childCount; i++) {
342322
getChildAt(i).forceLayout();
343323
}
344324
mRecycler.markChildrenDirty();
345325
}
346326

347-
if (mFastScroller != null
348-
&
349-
&
350-
mItemCount != mOldItemCount) {
327+
if (mFastScroller != null&&
328+
mItemCount != mOldItemCount){
351329
mFastScroller.onItemCountChanged(mOldItemCount, mItemCount);
352330
}
353331
// 布局Child View
@@ -376,7 +354,7 @@ ListAdapter
376354

377355
return child;
378356
}
379-
}
357+
}
380358
```
381359

382360
通过增加Adapter一层来将Item View的操作抽象起来,ListView等集合视图通过Adapter对象获得Item的个数、数据元素、Item View等,从而达到适配各种数据、各种Item视图的效果。

0 commit comments

Comments
 (0)