Android设计模式(六)--工厂方法模式

1、定义:

Define an interface for creating an object, but let subclasses decide which class to instantiate. 
Factory Method lets a class defer instantiation to subclasses.

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


2、意义:

工厂方法使得类的实例化延伸到子类。


3、四大角色:

3.1、抽象工厂:工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。

3.2、具体工厂:实现了抽象工厂接口的具体JAVA类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建导出类。

3.3、抽象角色:工厂方法模式所创建的对象的超类。

3.4、具体角色:实现抽象角色的某个具体角色的实例。


4、优点:

4.1、工厂方法模式是完全符合开闭原则的;
4.2、摈弃了简单工厂模式的缺点;
4.3、工厂模式是一种典型的解耦模式,可以降低对象之间的耦合度;
4.4、工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。

4.5、可以使代码结构清晰,有效地封装变化。

4.6、对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。


5、缺点:

简单的对象应用时,不适合工厂方法模式。


6、写了一个简单的demo:

首先是普通的 抽象 对象

<span style="font-size:14px;">package com.example.demo.FactoryMethod;
/**
 * 抽象</span><span style="font-size:12px;"><span style="font-family: Arial;">角色</span>
</span><span style="font-size:14px;"> * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public interface Lottery {

	public String getLotteryName();
}
</span>
实现:

package com.example.demo.FactoryMethod;
/**
 * 具体角色
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class SSQLottery implements Lottery{

	@Override
	public String getLotteryName() {
		return "双色球";
	}

}

package com.example.demo.FactoryMethod;
/**
 * 具体角色
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class DLTLottery implements Lottery{

	@Override
	public String getLotteryName() {

		return "大乐透";
	}

}

然后是核心的 抽象工厂:

package com.example.demo.FactoryMethod;
/**
 * 抽象工厂
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public interface LotteryFactory {

	public Lottery getLottery();
}

具体工厂:

package com.example.demo.FactoryMethod;
/**
 * 具体工厂
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class SSQFactory implements LotteryFactory{

	@Override
	public Lottery getLottery() {

		return new SSQLottery();
	}

}

package com.example.demo.FactoryMethod;
/**
 * 具体角色
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class DLTLottery implements Lottery{

	@Override
	public String getLotteryName() {

		return "大乐透";
	}

}

使用:

package com.example.demo.FactoryMethod;

import android.util.Log;
/**
 * 工厂方法的使用
 * 
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class UseFactory {
	private static final String TAG="UseFactory";

	public void use()
	{
		//若是需要修改,只需要修改 new SSQFactory(); 即可;
		//
		LotteryFactory factory= new SSQFactory();
		
		//此处的操作完成是,接口的操作;
		// 也就是说:使用工厂模式,调用者只关心产品的接口就可以了,
		//至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
		Lottery lottery = factory.getLottery();
		Log.i(TAG,lottery.getLotteryName());
	}
}

在Android中的使用广泛,其中:

1、 关于ArrayList,HashSet,与 Iterator 之间都能算是一种工厂方法;

		Set<String> set = new HashSet<String>();
		Iterator<String> iterator = set.iterator();
		while(iterator.hasNext())
		{
			// 具体操作
		}
		List<String> list =new ArrayList<String>();
		Iterator<String> it = list.iterator();
		while(it.hasNext())
		{
			// 具体操作
		}
		

其中List和Set都是工厂接口
/**
 * A {@code Set} is a data structure which does not allow duplicate elements.
 *
 * @since 1.2
 */
public interface Set<E> extends Collection<E>
{
    /**
     * Returns an iterator on the elements of this {@code List}. The elements are
     * iterated in the same order as they occur in the {@code List}.
     *
     * @return an iterator on the elements of this {@code List}.
     * @see Iterator
     */
    public Iterator<E> iterator();

}

/**
 * A {@code List} is a collection which maintains an ordering for its elements. Every
 * element in the {@code List} has an index. Each element can thus be accessed by its
 * index, with the first index being zero. Normally, {@code List}s allow duplicate
 * elements, as compared to Sets, where elements have to be unique.
 */
public interface List<E> extends Collection<E> 
{
    /**
     * Returns an iterator on the elements of this {@code List}. The elements are
     * iterated in the same order as they occur in the {@code List}.
     *
     * @return an iterator on the elements of this {@code List}.
     * @see Iterator
     */
    public Iterator<E> iterator();

}


自然,ArrayList与HashMap 都有关于其中的实现了。

public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess {
    @Override public Iterator<E> iterator() {
        return new ArrayListIterator();
    }

    private class ArrayListIterator implements Iterator<E> {
        /** Number of elements remaining in this iteration */
        private int remaining = size;

        /** Index of element that remove() would remove, or -1 if no such elt */
        private int removalIndex = -1;

        /** The expected modCount value */
        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) ourList.array[removalIndex = ourList.size - rem];
        }

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值