【Android-设计模式】工厂方法模式

【工厂方法模式的定义】:

定义一个用于创建对象的接口,让子类决定实例化哪个类

【工厂方法模式的使用场景】:

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。

【工厂方法模式的通用模式代码】:

抽象产品类:

public abstract class Product {
  /**
   *产品.
  public abstract void ethod();
}

具体产品A:

public class ConcreteProductA extends Product {
  @Override
  public void method(){
    System.out.println("我是具体产品A");
  }
}

具体产品B:

public class ConcreteProductB extends Product {
  @Override
  public void method(){
    System.out.println("我是具体产品B");
  }
}

抽象工厂类:

public abstract class Factory {
  /**
   * 抽象工厂方法
   * 具体生产什么由子类去实现
   * @return 具体的产品对象
   */
  public abstract Product createProduct():
}

具体工厂类:

public ConcreteFactory extends Factory {
  @Overide
  public Product createProduct() {
    return new ConcreteProductA();
    //return new ConcreteProductB();
  }
}

客户类:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product p = factory.creatProduct();
    p.method();
  }
}

这里的几个角色都很简单,主要分为四大模块:

  • 抽象工厂,其为工厂方法模式的核心;
  • 具体工厂,其实现了具体的业务逻辑;
  • 抽象产品,是工厂方法模式所创建的产品的父类;
  • 具体产品,为实现抽象产品的某个具体产品的对象。

上述的代码中我们在Client类中构造了一个工厂对象,并通过其生产了一个产品对象,这里我们得到的产品对象是ConcreteProductA的实例,如果想得到ConcreteProductB的实例,更改ConcreteFactory中的逻辑即可:

public ConcreteFactory extends Factory {
  @Overide
  public Product createProduct() {
    //return new ConcreteProductA();
    return new ConcreteProductB();
  }
}

这种方式比较觉,需要哪一个产品就生产哪一个,有时候也可以利用反射的方式更简洁地来生产具体产品对象,此时,需要在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类:

public abstract class Factory {
  /**
   * 抽象工厂方法
   * 具体生产什么由子类去实现
   * @return 具体的产品对象
   */
  public abstract <T extends Product> T createProduct(Class<T> clz):
}

具体工厂类:(通过反射获取类的实例)

public ConcreteFactory extends Factory {
  @Overide
  public <T extends Product> T createProduct(Class<T> clz) {
    Product p = null;
    try {
      p = (Product) Class.forName(clz.getName()).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)p;
  }
}

Client:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product p = factory.createProduct(ConcreateProductB.class);
    p.method();
  }
}

【Android源码中的工厂方法模式实现】

以List和Set为例,List和Set都继承于Collection接口,而Collection接口继承于Iterable接口,Iterable接口很简单,就一个iterator方法。

public iterface Iterable<T> {
  Iterator<T> iterator();
}

这意味着List和Set接口也会继承该方法,平时比较常用的两个间接实现类ArrayList和HasSet中iterator方法的实现就是构造并返回一个迭代器对象。

public class ArrayList<E> extends AbstractList<E> impolements Cloenable, Serializeble, RandomAccess {
  @Override public Iterator<E> iterator() {
    return new ArrayListIterator();
  }

  private class ArrayListIterator implements Iterator<E> {
    private int remaining = size;
    private int removalIndex = -1;
    private int expectedModCount = modCount;
    public boolean hasNext(){
      return remaining != 0;
    }

    @SuppressWarnings("unchecked")
    public E next {
      ArrayList<E> ourList = ArrayLIst.this;
      int rem = remaining;
      if (ourLIst.modCount != expectedModCount) {
        throw new ConcurrentModificationException();
      }
      if (rem == 0) {
        throw new NoSuchElementException();
      }
      remaining = rem - 1;
      return (E) outList.array[removalIndex = ourList.size - rem];
    }

    public void remove() {
      Object[] a = array;
      int removalIdx = removalIndex;
      if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
      }
      if (removalIdx < ) {
        throw new IllegalStateException();
      }
      System.arraycopy(a, removalIdx + 1, a, removalIdx, remaining);
      a[--size] = null; //Prevent memory leak
      removalIndex = -1;
      expectedModCount = ++modCount;
    }
  }
}

public class HasSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
{
  @Override
  public Iterator<E> iterator() {
    return backingMap.keySet().iterator();
  }
}

HashSet的iterator方法中会返回成员变量backingMap中对应HashSet对象元素的迭代器对象,最终返回的是KeySet中的一个迭代器对象:

public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneabl, Serializable
{
  Iterator<K> newKeyIterator() {
    return new KeyIterator();
  }
  private final class KeySet extends AbstractSet<K> {
    public Iterator<K> iterator() {
      return newKeyIterator();
    }
  }
}

ArrayList和HasSet中的iterator方法其实就相当更进一于一个工厂方法,专为new对象而生,这里iterator方法是构造并返回一个具体的迭代器。当然,Java源码中对工厂方法的应用范例也不少,大家可以自己体会。Android中对工厂方法模式的应用更多:

Public class AActivity extends Activity {
  @Overrid 
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreat(saveInstanceState);
    setContentView(new LinearLayout(this));
  }
}

这里构造一个纯属布局LinearLayout对象并设置为当前Activity的根而已,这段代码看亿再桂皮过了,实质上,onCreate方法就相当于一个工厂方法,为什么呢?因为我们知道LinearLayout是一个ViewGroup,而ViewGroup又继承于View,简单地说就是,所有控件都是View的子类,上面的代码中,我们的AActivity的onCreat方法中构造一个View对象,并设置为当前界面的ContentView返回给framework处理,如果现在又有一个BActivity,这里我们又在其onCreate方法中通过setContentView方法设置另外不同的View,这是不是就是一个工厂模式的结构呢?其实设计离我们非常近!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值