设计模式解析与实战之工厂方法模式

买了大神关爱民与何红辉所著书籍《设计模式解析与实战》,观后有所感、有所悟。

工厂方法模式是一种非常简单的模式,开发中应用广泛,这里我用一段简短的话来描述:腾讯公司旗下有不同的品牌产品,每个品牌产品的生产制造都有不同的工厂,每个工厂生产不同的零件,而这些零件组合起来就是他所谓的产品。再细一点说,腾讯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。

补充:受个人编码习惯影响,一不小心把抽象工厂模式运用到了这里,下篇抽象工厂模式就不写了,这里做个简单说明,抽象工厂模式的优点:分离接口与实现,客户端只需要面向产品编程,使其从具体的产品的实现中解耦,使用灵活、简单。缺点:不容易扩展新产品类,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值