创建型模式是将创建和使用代码解耦。
    然后还是从最原始的代码开始写起:

    1. //申请贷款流程 fundBank 为资金方
    2. public static void applyLoan(String fundBank){
    3. if("CCB".equals(fundBank)){
    4. //走建行提款流程,然后写一堆代码
    5. }else if("ABC".equals(fundBank)){
    6. //走农行提款流程,然后写一堆代码
    7. }
    8. }

    这是一个贷款申请流程,根据传入的资方名称不同,然后走不同资方的贷款流程。这是最原始的代码,直接把所有的操作都写在了这个方法里面,就是想到啥就写啥的那种,完全面向过程的那种,基本应该不会有人这样写。
    然后呢,我们知道了面向对象,知道了要学会封装,继承,抽象,多态,然后我们发现这都是一个申请贷款的逻辑,我们抽象出这套逻辑,用一个方法来走这段逻辑,然后由于功能比较独立,需要封装,然后我们使用类来封装这种功能。
    然后我们就多出了些接口和类,接着就有了第二代代码:

    1. public interface LoanHandler {
    2. void handler();
    3. }
    1. public class CCBLoan implements LoanHandler{
    2. //抽象出来的行为逻辑
    3. @Override
    4. public void handler() {
    5. //原来的主流程的代码放到了这里
    6. }
    7. }
    1. public class ABCLoan implements LoanHandler {
    2. @Override
    3. public void handler() {
    4. }
    5. }

    然后调用的地方:

    1. //申请贷款流程 fundBank 为资金方
    2. public static void applyLoan(String fundBank){
    3. LoanHandler loan = null;
    4. if("CCB".equals(fundBank)){
    5. loan = new CCBLoan();
    6. }else if("ABC".equals(fundBank)){
    7. loan = new ABCLoan();
    8. }
    9. //自己处理空指针。。。
    10. loan.handler();
    11. }

    这样,我们就把原来的复杂的代码,根据面向对象的思想,分散到了各个类当中。嗯,一切起因都是代码太臃肿了。然后,随着业务的渐渐发展,接入的资方越来越多,然后你的贷款申请的主流程的代码就越来越多,其实都是根据不同的资方创建不同的处理对象,也就是都是在创建对象,然后最后进行调用。那么,我们能不能把这里创建类的过程也单独拎到一个独立的类当中呢? 这里根据输入进行选择的过程,可以参考:

    然后其实这里已经引入了简单工厂模式,一般而言就是建立一个map来缓存标识和处理类的映射关系,然后在创建类的地方替换为从工厂类中取出。
    demo代码如下:

    1. public class FundFactory {
    2. private HashMap<String,LoanHandler> hm = new HashMap<>();
    3. public void init(){
    4. hm.put("CCB",new CCBLoan());
    5. hm.put("ABC",new ABCLoan());
    6. }
    7. //单例模式
    8. public LoanHandler getSingleLoanHandler(String fundBank){
    9. LoanHandler loanHandler = hm.get(fundBank);
    10. return loanHandler;
    11. }
    12. //多例模式
    13. public LoanHandler getNotSingleLoanHandler(String fundBank){
    14. LoanHandler loan = null;
    15. if("CCB".equals(fundBank)){
    16. loan = new CCBLoan();
    17. }else if("ABC".equals(fundBank)){
    18. loan = new ABCLoan();
    19. }
    20. return loan;
    21. }
    22. }

    然后主流程代码:

    1. //申请贷款流程 fundBank 为资金方
    2. public void applyLoan(String fundBank){
    3. LoanHandler singleLoanHandler = fundFactory.getSingleLoanHandler(fundBank);
    4. singleLoanHandler.handler();
    5. }

    然后来简单分析一下,如果单例模式,那么利用缓存就可以建立映射,不需要if/else,也叫查表法。如果是多例,那么还是要if/else,只不过这里进行了转移,把这段逻辑转移到了工程类当中,那么我们主流程代码就变得结构清晰明了,也就是我们一开始就强调过的,对象的创建和使用解耦。一旦代码开始变得复杂臃肿,那么就需要开始分离解耦了!(这里主要是解决创建多个对象时的复杂)
    然后,继续随着业务的发展,创建一个单独的建行贷款申请类的时候需要做很多操作,然后才能真正开始创建这个类,那么由于这部分代码都要在工厂类里面全部写上去,那么这个工厂类就显得很臃肿了,所以,这个时候就需要工厂方法模式了。
    比如原来的代码是这样:

    1. //多例模式
    2. public LoanHandler getNotSingleLoanHandler(String fundBank){
    3. LoanHandler loan = null;
    4. if("CCB".equals(fundBank)){
    5. //判断是否满足建行贷款申请的条件
    6. //查询申请所需数据
    7. loan = new CCBLoan();
    8. }else if("ABC".equals(fundBank)){
    9. //判断是否满足农行贷款申请的条件
    10. //查询申请所需数据
    11. loan = new ABCLoan();
    12. }
    13. return loan;
    14. }

    随着资方和处理逻辑的增加,工厂类就显得很臃肿了。然后就有工厂方法模式(工厂方法模式是有抽象工厂)。

    1. public interface LoanHandlerFactory {
    2. LoanHandler getLoanHandler();
    3. }

    具体工厂:

    1. public class CCBLoanHandlerFactory implements LoanHandlerFactory{
    2. @Override
    3. public LoanHandler getLoanHandler() {
    4. //先判断是否符合创建建行贷款申请条件
    5. //然后获取创建建行贷款申请的数据
    6. //最后才创建建行贷款申请类
    7. return new CCBLoan();
    8. }
    9. }

    实际的外层的大工厂:

    1. //多例模式
    2. public LoanHandler getNotSingleLoanHandler(String fundBank){
    3. LoanHandlerFactory loanHandlerFactory = null;
    4. if("CCB".equals(fundBank)){
    5. loanHandlerFactory = new CCBLoanHandlerFactory();
    6. }else if("ABC".equals(fundBank)){
    7. //````
    1. }
    2. LoanHandler loan = loanHandlerFactory.getLoanHandler();
    3. return loan;
    4. }

    ``` 这样就进一步进行了代码的分离和解耦。

    工厂方法模式的优点:
    1.争哥说的,当单个对象创建的逻辑比较复杂的时候,推荐使用工厂方法模式进行封装创建流程。即创建具体的ccbhandler的时候,需要先提前做一些其它事情,比如获取建行账户信息,确认企业是否有建行账户之类的。也就是说,当你选择建行资方的时候,可以在建行工厂类当中先判断是否符合创建建行贷款申请类的条件,然后进行相应的初始化,最后再创建建行贷款申请类。

    争哥的观点:
    那什么时候该用工厂方法模式,而非简单工厂模式呢?我们前面提到,之所以将某个代码块剥离出来,独立为函数或者类,原因是这个代码块的逻辑过于复杂,剥离之后能让代码更加清晰,更加可读、可维护。但是,如果代码块本身并不复杂,就几行代码而已,我们完全没必要将它拆分成单独的函数或者类。基于这个设计思想,当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。而使用简单工厂模式,将所有的创建逻辑都放到一个工厂类中,会导致这个工厂类变得很复杂。

    2.一般认为的优点:
    工厂方法模式把具体产品的创建推迟到工厂类的子类(具体工厂)中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式在添加新产品的时候就不修改工厂类逻辑而是添加新的工厂子类,符合开放封闭原则,克服了简单工厂模式中缺点。

    我不是非常能理解这种优点,关键是我看他们的demo代码,都是直接创建具体工厂的,抽象工厂只是用来充当一个多态,在实际开发当中这只是一部分而已,也就只能说是推迟了创建具体处理器的实际,这里算一个小的隔离。。。只能说现在的我还不能充分理解他们所认为的优点吧,在实际开发中我可不会为了抽象而抽象。。然后每个给每个处理器都创建一个处理工厂类,但是里面又啥都不干,只是单纯new一个处理器。 不过,如果你说这是为了以后的扩展的话,那也行,毕竟抽象出来后,角色分明,结构清晰是挺好的。但是无故加了这么多的类,类还那么简单,这可在类结构上有些臃肿了。

    https://zhuanlan.zhihu.com/p/314453087
    http://c.biancheng.net/view/1351.html