@linux1s1s
2019-02-18T10:10:50.000000Z
字数 5774
阅读 3194
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 {@Overridepublic void getView() {super.getView();}@Overridepublic 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;}@Overridepublic void getView() {source.getView();}@Overridepublic 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;}@Overridepublic 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");}@Overridepublic 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 {@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 0;}@Overridepublic Object getItem( int position ) {// TODO Auto-generated method stubreturn null ;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView( int position , View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null ;}}
这么一个适配器类相信大家都不陌生,从这个类是不是就看出BaseAdapter类的好处了,如果还看不出来,最简单的办法是自己写个Adapter类 不经过BaseAdapter 就会像下面这样
public class ScheduleAdapter implements ListAdapter, SpinnerAdapter {@Overridepublic void registerDataSetObserver(DataSetObserver observer) {// TODO Auto-generated method stub}@Overridepublic void unregisterDataSetObserver(DataSetObserver observer) {// TODO Auto-generated method stub}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn 0;}@Overridepublic Object getItem( int position ) {// TODO Auto-generated method stubreturn null ;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic boolean hasStableIds() {// TODO Auto-generated method stubreturn false ;}@Overridepublic View getView( int position , View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null ;}@Overridepublic int getItemViewType(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic int getViewTypeCount() {// TODO Auto-generated method stubreturn 0;}@Overridepublic boolean isEmpty() {// TODO Auto-generated method stubreturn false ;}@Overridepublic View getDropDownView( int position , View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null ;}@Overridepublic boolean areAllItemsEnabled() {// TODO Auto-generated method stubreturn false ;}@Overridepublic boolean isEnabled(int position) {// TODO Auto-generated method stubreturn false ;}}
是不是原先接口的每个方法都需要一一实现,而大部分接口方法是不需要从新实现一遍的,因此BaseAdapter这个抽象类就充当了中间适配的角色。
上面这个就是设计模式中的接口适配器模式
用一张图形象的表述如下:

