设计模式解析与实战之工厂方法模式
2015-12-04 17:30
363 查看
买了大神关爱民与何红辉所著书籍《设计模式解析与实战》,观后有所感、有所悟。
工厂方法模式是一种非常简单的模式,开发中应用广泛,这里我用一段简短的话来描述:腾讯公司旗下有不同的品牌产品,每个品牌产品的生产制造都有不同的工厂,每个工厂生产不同的零件,而这些零件组合起来就是他所谓的产品。再细一点说,腾讯IM工厂,生产了腾讯qq、qq空间、微博等,这里以腾讯为主题,写一段工厂方法模式的代码。
先来创建QQ空间抽象类:
接下来分别创建我的空间、朋友空间、陌生人空间的实现类,这里以我的空间实现类为例,以避免代码冗杂:
定义腾讯工厂抽象类:
腾讯工厂实现类(单例模式+泛型):
测试类和输出如下:
当你看过上面代码,相信对工厂方法有一定的理解了,当然如果对泛型应用不解,我表示无能为力 了,api应该可以帮助你理解。下面再来看看在Android源码中的工厂方法模式的实现:
原书中举例ArrayList 和 HashSet中的迭代器对象Iterator,我就想我不能每次都照着书写吧,那多没意思,于是乎我就在源码中找到了一个新的工厂方法模式实战ArrayAdapter 和 SimpleAdapter.先来看源代码Adapter类:
ListAdapter继承Adapter新增方法areAllItemsEnabled()、isEnabled(int position):
BaseAdapter来实现ListAdapter并重新相关方法。
ArrayAdapter和SimpleAdapter都来继承抽象类BaseAdapter,并实现FilterAble接口
通过对比发现都分别new了 各自的内部类,内部类都继承了抽象类口Filter,下面是相关代码:
控件ListView GridView等列表控件内部提供方法setAdapter(ListAdapter adapter),用户在调用时可更具界面选择传入不同的adapter。
补充:受个人编码习惯影响,一不小心把抽象工厂模式运用到了这里,下篇抽象工厂模式就不写了,这里做个简单说明,抽象工厂模式的优点:分离接口与实现,客户端只需要面向产品编程,使其从具体的产品的实现中解耦,使用灵活、简单。缺点:不容易扩展新产品类,
工厂方法模式是一种非常简单的模式,开发中应用广泛,这里我用一段简短的话来描述:腾讯公司旗下有不同的品牌产品,每个品牌产品的生产制造都有不同的工厂,每个工厂生产不同的零件,而这些零件组合起来就是他所谓的产品。再细一点说,腾讯IM工厂,生产了腾讯qq、qq空间、微博等,这里以腾讯为主题,写一段工厂方法模式的代码。
先来创建QQ空间抽象类:
public abstract class QQSpace { public QQSpace(){ init(); } /** * 创建空间 */ public abstract void init(); }
接下来分别创建我的空间、朋友空间、陌生人空间的实现类,这里以我的空间实现类为例,以避免代码冗杂:
public class MyselfSpace extends QQSpace{ @Override public void init() { System.out.println("创建我自己的空间"); } }
定义腾讯工厂抽象类:
public abstract class Factory { public abstract <T extends QQSpace> T createTecentSpace(Class<T> cls); public abstract <T extends TecentMusic> T createTecentMusic(Class<T> cls); }
腾讯工厂实现类(单例模式+泛型):
public class TecentFactory extends Factory{ private static TecentFactory instance; public TecentFactory() { } public static TecentFactory getInstance(){ if(instance==null){ synchronized (TecentFactory.class) { if(instance==null){ instance=new TecentFactory(); } } } return instance; } @Override public <T extends QQSpace> T createTecentSpace(Class<T> cls) { T mSpace=null; try { mSpace=(T) cls.forName(cls.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return mSpace; } @Override public <T extends TecentMusic> T createTecentMusic(Class<T> cls) { T mMusic=null; try { mMusic=(T) cls.forName(cls.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return mMusic; } }
测试类和输出如下:
public class FactoryTest { public static void main(String[] args) { MyselfSpace mSpace=TecentFactory.getInstance().createTecentSpace(MyselfSpace.class); } } //输出结果:创建我自己的空间
当你看过上面代码,相信对工厂方法有一定的理解了,当然如果对泛型应用不解,我表示无能为力 了,api应该可以帮助你理解。下面再来看看在Android源码中的工厂方法模式的实现:
原书中举例ArrayList 和 HashSet中的迭代器对象Iterator,我就想我不能每次都照着书写吧,那多没意思,于是乎我就在源码中找到了一个新的工厂方法模式实战ArrayAdapter 和 SimpleAdapter.先来看源代码Adapter类:
package android.widget; import android.database.DataSetObserver; import android.view.View; import android.view.ViewGroup; /** * An Adapter object acts as a bridge between an {@link AdapterView} and the * underlying data for that view. The Adapter provides access to the data items. * The Adapter is also responsible for making a {@link android.view.View} for * each item in the data set. * * @see android.widget.ArrayAdapter * @see android.widget.CursorAdapter * @see android.widget.SimpleCursorAdapter */ 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); static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE; int getItemViewType(int position); int getViewTypeCount(); static final int NO_SELECTION = Integer.MIN_VALUE; boolean isEmpty(); }
ListAdapter继承Adapter新增方法areAllItemsEnabled()、isEnabled(int position):
public interface ListAdapter extends Adapter { public boolean areAllItemsEnabled(); boolean isEnabled(int position); }
BaseAdapter来实现ListAdapter并重新相关方法。
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { }
ArrayAdapter和SimpleAdapter都来继承抽象类BaseAdapter,并实现FilterAble接口
public class ArrayAdapter<T> extends BaseAdapter implements Filterable { //......................其他部分不是重点略....................... /** * {@inheritDoc} */ public Filter getFilter() { if (mFilter == null) { mFilter = new ArrayFilter(); } return mFilter; } }
public class SimpleAdapter extends BaseAdapter implements Filterable { //......................其他部分不是重点略....................... public Filter getFilter() { if (mFilter == null) { mFilter = new SimpleFilter(); } return mFilter; } }
通过对比发现都分别new了 各自的内部类,内部类都继承了抽象类口Filter,下面是相关代码:
private class SimpleFilter extends Filter { //................略................. } private class ArrayFilter extends Filter { //................略................. } public abstract class Filter { /** * <p>Creates a new asynchronous filter.</p> */ public Filter() { mResultHandler = new ResultsHandler(); } public void setDelayer(Delayer delayer) { synchronized (mLock) { mDelayer = delayer; } } public final void filter(CharSequence constraint) { filter(constraint, null); } //................略................. }
控件ListView GridView等列表控件内部提供方法setAdapter(ListAdapter adapter),用户在调用时可更具界面选择传入不同的adapter。
补充:受个人编码习惯影响,一不小心把抽象工厂模式运用到了这里,下篇抽象工厂模式就不写了,这里做个简单说明,抽象工厂模式的优点:分离接口与实现,客户端只需要面向产品编程,使其从具体的产品的实现中解耦,使用灵活、简单。缺点:不容易扩展新产品类,
相关文章推荐
- HDUOJ Number Sequence找规律
- 关于SQL SERVER 2008 R2配置管理器出现“远程过程调用失败”【0x800706be】的解决办法(
- jquery radio的取值 radio的选中 radio的重置
- C语言函数入栈顺序
- 使用 alias 以及 sshpass 命令简化ssh登陆步骤
- java笔记-面向对象(封装)
- yii2 嵌套布局 layout
- Failed to load javaHL Library
- NOIP滚粗
- 对数组对象按某些属性排序方法
- 设置一个字符串中的个别字符的特殊格式
- rman备份出现ORA-19625错误
- 常用正则
- 第一阶段:2015.12 - 2016.03
- 困扰我多次的内存溢出问题终于解决了
- NSArray, NSSet, NSOrderedSet, and NSDictionary
- nil,Nil,NULL和NSNull理解(ios)
- 在代码中设置字体加粗的方法
- 森林病虫防治系统 (十二)
- 资源分享来源