学习自
http://baijiahao.baidu.com/s?id=1586800950048933907&wfr=spider&for=pc
何为工厂?
戴尔电脑
public class DellComputer { private String computerName; }
戴尔电脑工厂
public class DellComputerFactory { public DellComputer createDellComputer() { return new DellComputer(); } }
代码中如何调用
DellComputerFactory dellComputerFactory = new DellComputerFactory(); dellComputerFactory.createDellComputer();
其实可以看到, 使用工厂前和使用工厂后,我们创建对象的过程发生了怎样的转变呢?
new DellComputer();——>new DellComputerFactory().createDellComputer();
之所以有工厂模式的存在, 也就是说,创造 这个模式的人,认为创建对象的这个过程,是可以被抽象的。也就是说,创造这个模式的人, 认为
1.创建一个对象 是复杂的
2.创建一个 对象虽然复杂, 但是却是有规律可循的
3.创建一个对象是频繁的,不易于修改的,我们可以用工厂避免 频繁的修改,带来的巨大的工作量
怎么去理解这3句话呢?我们可以用Java线程池来弄清这一点
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { }
这么长的参数,可想而知其 复杂性。熟悉线程池的人会知道,这些参数的含义:
1.核心线程数量
2.最大线程数量(=核心线程数量+非核心线程数量)
3.非核心线程保活时间
4.时间单位
5.阻塞队列
6.线程工厂,也就是说我们可以自己定义创建一个线程的逻辑
7.拒绝策略
可想而知,我们需要进行一系列复杂的配置才能有效地使用它。但是:
1.这些东西写在比如Activity里会很不美观,其实我们 只需要知道他做了 什么事就可以了。业务和框架应该是抽离的。
2. 这些东西改动起来太麻烦
3.往往一个项目某一个业务模块使用的线程池是一致的,所以完全可以 抽象出来。
可以看到Android 线程池已经提供了一些默认的工厂实现
public class Executors { public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newWorkStealingPool(int parallelism) { return new ForkJoinPool (parallelism, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); } public static ExecutorService newWorkStealingPool() { return new ForkJoinPool (Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); } public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); } public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
比如第一个定长线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
可以看到核心线程池就是只有核心线程的线程池。他把原来的 线程池抽象成了一个只有 核心线程的线程池。
我们可以从中借鉴的第一点:我们也可以学着 这样,把自己项目用到的线程池,全部封装到这里面。
我们可以从中借鉴的第二点:工厂模式可以在原有的基础上再度简化。Android源码中处处都应用了设计模式,不仅如此, 他在原有的基础上做的 更加简洁。比如这里的工厂方法, 直接弄成静态;比如建造者模式,他舍弃了冗余的构建,采用简洁的链式调用。
所以根据第二点,我们的工厂可以这样 改造:
public class DellComputerFactory { public static DellComputer createDellComputer() { return new DellComputer(); } }
再根据第一点,我们的工厂可以 这样改造:
public class ComputerFactory { public static DellComputer createDellComputer() { return new DellComputer(); } public static MSIComputer createMSIComputer() { return new MSIComputer(); } }
在优化一点点
public class Computer { private String computerName; public Computer(String computerName) { this.computerName = computerName; } }
public class ComputerFactory { public static Computer createDellComputer() { return new Computer("dell computer"); } public static Computer createMSIComputer() { return new Computer("msi computer"); } }
接下来使用
Computer dellComputer = ComputerFactory.createDellComputer(); Computer msiComputer = ComputerFactory.createMSIComputer();
再次感叹Android的源码水平境界之高。探索到这里结束,进入工厂正文。同时我们也可以认识到了,工厂并不是那么看起来的没有用,只是我们往往忽视了它罢了。
实际上,未简化版的工厂模式 要冗余的多
他需要有
1.抽象产品
public abstract class AbstractComputer { public abstract void getComputerName(); }
2.实际产品
public class DellComputer extends AbstractComputer{ @Override public void getComputerName() { System.out.println("dell computer"); } }
public class MSIComputer extends AbstractComputer{ @Override public void getComputerName() { System.out.println("msi computer"); } }
3.抽象工厂
public abstract class AbstractComputerFactory { public abstract AbstractComputer createComputer(); }
4.实际工厂
public class DellComputerFactory extends AbstractComputerFactory{ @Override public AbstractComputer createComputer() { return new DellComputer(); } }
public class MSIComputerFactory extends AbstractComputerFactory { @Override public AbstractComputer createComputer() { return new MSIComputer(); } }
所以我们现在 创建实例是这样的
AbstractComputerFactory computerFactory = new MSIComputerFactory(); computerFactory.createComputer(); AbstractComputerFactory computerFactory1 = new DellComputerFactory(); computerFactory1.createComputer();
反射工厂
原来我们有两种 工厂
1.抽象工厂
2.具体工厂
我们具体工厂在继承了抽象工厂以后,通过new的形式来创建实例。其实对于创建实例,不仅仅只是new一种方法,也可以通过 反射方式创建实例。
所以把抽象工厂类改写一下
public class ComputerFactory { public <T extends AbstractComputer> AbstractComputer createComputer(Class<T> computerClass) { try { Object computer = computerClass.newInstance(); return (AbstractComputer) computer; } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return null; } }
所以现在是 这样创建实例的
ComputerFactory computerFactory = new ComputerFactory(); MSIComputer msiComputer = computerFactory.createComputer(MSIComputer.class); DellComputer dellComputer = computerFactory.createComputer(DellComputer.class);
而且原有的具体工厂都不必再写了
总结下工厂模式,方便记忆
本来是直接MSI工厂创建MSI电脑即可,现在是通过抽象父类,让我们隔绝了细节,相当于降低了耦合。
抽象工厂
比工厂模式要难理解一点,不过是面试官的常考点之一。
可以通过这样一张图去理解
这里我们就有了对这个工厂的定义了:这个工厂可以生产A、B两种产品,A和B都有多种实现。
比如我们这里是MSI电脑工厂,那么A可以是一种MSI机型,B是另一种MSI机型吗?不行,因为这里是抽象的工厂,所以的工厂都需要创建同类的产品,如果把A、B产品定义成某机型, 只能对于MSI适用。所以这里的东西应该是所以电脑公有的东西。 所以这里不应该是机型,而是比如A是低配电脑,B是高配电脑。
总结一下, 在这里就是: 这里是电脑工厂,我们生产产品A是低配电脑,B是高配 电脑。具体的第一个实现类,MSI电脑,我们的生产产品A是MSI低配电脑,B是MSI高配电脑。第二个实现类,DELL电脑,我们的生产产品A是DELL低配电脑,B是DELL高配电脑。以此类推。
这就是抽象工厂的含义,比如这里抽象的是电脑,然后创建的产品, 必定是所有电脑的共性产品,低配电脑,高配电脑。
工厂模式和抽象工厂的区别
前者
一步步来一遍,为了方便记忆
一开始是最简单的new
public class MSIComputer { }
MSIComputer msiComputer = new MSIComputer();
后来用最简单的工厂封装一下
public class MSIComputerFactory { public MSIComputer createMSIComputer() { return new MSIComputer(); } }
MSIComputerFactory msiComputerFactory = new MSIComputerFactory(); MSIComputer msiComputer = msiComputerFactory.createMSIComputer();
工厂模式,弄出产品和工厂的抽象类,然后就不是直接的耦合了
public interface IComputer { }
public interface IComputerFactory { IComputer createComputer(); }
public class MSIComputer implements IComputer{ }
public class MSIComputerFactory implements IComputerFactory{ @Override public IComputer createComputer() { return new MSIComputer(); } }
IComputerFactory computerFactory = new MSIComputerFactory(); IComputer iComputer = computerFactory.createComputer();
抽象工厂。 上面的是工厂模式,只生产电脑; 如果是抽象工厂,会生产好电脑,差电脑。
1.电脑抽象
public interface IComputer { }
2.坏电脑抽象
public class IBadComputer implements IComputer{ }
3.好电脑抽象
public interface IGoodComputer extends IComputer{ }
4.MSI坏电脑
public class MSIBadComputer implements IBadComputer{ }
5.MSI好电脑
public class MSIGoodComputer implements IGoodComputer{ }
6.DELL坏电脑
public class DELLBadComputer implements IBadComputer { }
7.DELL好电脑
public class DELLGoodComputer implements IGoodComputer{ }
8.电脑工厂
public interface IComputerFactory { IComputer createGoodComputer(); IComputer createBadComputer(); }
9.MSI电脑工厂
public class MSIComputerFactory implements IComputerFactory{ @Override public IComputer createGoodComputer() { return new MSIGoodComputer(); } @Override public IComputer createBadComputer() { return new MSIBadComputer(); } }
10.DELL电脑工厂
public class DELLComputerFactory implements IComputerFactory{ @Override public IComputer createGoodComputer() { return new DELLGoodComputer(); } @Override public IComputer createBadComputer() { return new DELLBadComputer(); } }
11.最终使用
IComputerFactory computerFactory = new MSIComputerFactory(); IComputer computer = computerFactory.createBadComputer(); IComputer computer1 = computerFactory.createGoodComputer(); IComputerFactory computerFactory1 = new DELLComputerFactory(); IComputer computer2 = computerFactory1.createGoodComputer(); IComputer computer3 = computerFactory1.createBadComputer();