@linux1s1s
2019-02-18T18:10:50.000000Z
字数 5774
阅读 2846
Java设计模式
我们先来明确一下 适配器模式有三种,分别是 类适配器模式、对象适配器模式、接口适配器模式
。
接下来不打算直接看这些模式的定义以及实例源码,我们直接从问题出发。
假如有如下类
public class ViewController {
public void getView() {
System. out.println("This is Original getView() method!" );
}
}
现在有新的需求,需要转换这个类,如果直接修改这个类可能会带来不必要的风险,那么如何在保持该类不动的情况下转换这个类呢?
方法大体上有两种
我们不说上面两种方法有什么优缺点,先来看看如何实现
定义接口抽取功能方法
public interface Adapter {
public void getView();
public void getCount();
}
接着定义继承类,一并实现该功能接口
public class BaseAdapter extends ViewController implements Adapter {
@Override
public void getView() {
super.getView();
}
@Override
public void getCount() {
System. out.println("This is Adapter extends ViewController getCount() method!");
}
}
然后 就可以在 测试用例中体现多态了
public class TestCase {
public static void main(String[] args) {
/*
* Call Adapter Method;
*/
Adapter adapter = new BaseAdapter();
adapter.getView();
adapter.getCount();
}
}
上面这种解决方式就是设计模式上所说的 类适配器模式
.
接下来看看第二种实现方法
定义一个聚合类
public class Wrapper implements Adapter {
private ViewController source;
public Wrapper( final ViewController source ) {
this.source = source;
}
@Override
public void getView() {
source.getView();
}
@Override
public void getCount() {
System. out.println("This is wrapper adapter method!" );
}
}
构造器 需要传入ViewController
的实例
然后直接看测试用例
public class TestCase {
public static void main(String[] args) {
/*
* Call Original Method;
*/
ViewController source = new ViewController();
source.getView();
/*
* Call Wrapper Adapter Method;
*/
Adapter wrapper = new Wrapper(source);
wrapper.getView();
wrapper.getCount();
}
}
这种实现思路在设计模式上叫做 对象适配器模式
.
当然 我们也可以将上面的Wrapper类做如下调整
public class Wrapper implements Adapter {
private ViewController source;
public Wrapper( final ViewController source ) {
this.source = source;
}
@Override
public void getView() {
System. out.println("Before getview() method call, you can do something here before getview method");
source.getView();
System. out.println("After getview() method call, you can do something here after getview method");
}
@Override
public void getCount() {
System. out.println("This is wrapper adapter method!" );
}
}
这个时候我们也可以称之为 装饰器模式, Android中比较常见的装饰器模式是 ContextWrapper 这个类
通过上面这个例子,可能感觉到 装饰器模式和适配器模式 不是一样的吗?干嘛还弄两个设计模式?
其实 装饰模式和适配器模式都有一个别名,就是包装模式,但是这两个模式是很不一样的。适配器模式的用意是要改变所考虑对象的接口,将其转换成所需要的形式,而装饰模式的用意是保持接口,只是为了扩展功能,一个是转换,一个是扩展。
小结一下:
上面两种实现思路 迥然不同 对象适配器可以很好的解决类适配器模式中遇到的兼容问题, 他们俩孰优孰劣 还需视不同的情况区别对待。
接下来我们看一下Android中广为人知的Adapter源码:
public interface Adapter {
void registerDataSetObserver(DataSetObserver observer);
void unregisterDataSetObserver(DataSetObserver observer);
int getCount();
Object getItem(int position);
long getItemId( int position );
boolean hasStableIds();
View getView(int position, View convertView , ViewGroup parent);
int getItemViewType( int position );
int getViewTypeCount();
boolean isEmpty();
}
再看一下它的子接口
public interface SpinnerAdapter extends Adapter {
public View getDropDownView( int position , View convertView, ViewGroup parent);
}
public interface ListAdapter extends Adapter {
public boolean areAllItemsEnabled();
boolean isEnabled( int position );
}
接着看它的实现抽象类
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public boolean hasStableIds() {
return false ;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer );
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer );
}
/**
* Notifies the attached observers that the underlying data has been changed
* and any View reflecting the data set should refresh itself.
*/
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
/**
* Notifies the attached observers that the underlying data is no longer valid
* or available. Once invoked this adapter is no longer valid and should
* not report further data set changes.
*/
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
public boolean areAllItemsEnabled() {
return true ;
}
public boolean isEnabled(int position) {
return true ;
}
public View getDropDownView( int position , View convertView, ViewGroup parent) {
return getView(position , convertView , parent );
}
public int getItemViewType(int position) {
return 0;
}
public int getViewTypeCount() {
return 1;
}
public boolean isEmpty() {
return getCount() == 0;
}
}
看完上面的这个BaseAdapter以后,到这我们可能不知道这个BaseAdapter类究竟有啥作用,继续往下看
public class ScheduleAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem( int position ) {
// TODO Auto-generated method stub
return null ;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView( int position , View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null ;
}
}
这么一个适配器类相信大家都不陌生,从这个类是不是就看出BaseAdapter类的好处了,如果还看不出来,最简单的办法是自己写个Adapter类 不经过BaseAdapter 就会像下面这样
public class ScheduleAdapter implements ListAdapter, SpinnerAdapter {
@Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem( int position ) {
// TODO Auto-generated method stub
return null ;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false ;
}
@Override
public View getView( int position , View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null ;
}
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false ;
}
@Override
public View getDropDownView( int position , View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return null ;
}
@Override
public boolean areAllItemsEnabled() {
// TODO Auto-generated method stub
return false ;
}
@Override
public boolean isEnabled(int position) {
// TODO Auto-generated method stub
return false ;
}
}
是不是原先接口的每个方法都需要一一实现,而大部分接口方法是不需要从新实现一遍的,因此BaseAdapter这个抽象类就充当了中间适配的角色。
上面这个就是设计模式中的接口适配器模式
用一张图形象的表述如下: