《Android 源码设计模式》读书笔记(1)-- 工厂方法模式之基础

前言

之前一直想了解关于设计模式相关内容,看了何红辉 大神的 《Android 源码设计模式解析与实战》 一书的部分章节,感觉写的很好。正巧最近在进行代码重构,加上 RecycleView 系列下篇文章的 demo 想结合一下设计模式,于是重读这本书,并简单记录一下,加深印象。

首先先大致了解下都有哪些设计模式。

1.设计模式分类

按照模式的应用目标分类,设计模式可以分为创建型模式结构型模式行为型模式

  • 创建型模式 ,是对对象创建过程的各种问题和解决方案的总结。
    包括:各种工厂模式(Factory、Abstract Factory)、单例模式(Singleton)、构建器模式(Builder)、原型模式(ProtoType)

  • 结构型模式,关注于类、对象继承、组合方式
    常见的有:桥接模式(Bridge)、适配器模式(Adapter)、装饰者模式(Decorator)、代理模式(Proxy)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)

  • 行为型模式,从类或对象间交互、职责划分等角度总结的模式。
    常见的有:策略模式(Strategy)、解释器模式(Interpreter)、命令模式(Command)、观察者模式(Observer)、迭代器模式(Iterator)、模板方法模式(Template Method)、访问者模式(Visitor)
    《Android 源码设计模式》读书笔记(1)-- 工厂方法模式之基础_第1张图片
    下面来看一下工厂方法模式

2. 工厂方法模式的定义

工厂方法模式(Factory Pattern),是创建型设计模式之一。根据上面总结的,我们知道肯定是跟对象的创建有关。

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

3.使用场景

需要生成复杂对象的地方
用 new 就可以完成创建的对象不需要使用。

4.UML 类图

《Android 源码设计模式》读书笔记(1)-- 工厂方法模式之基础_第2张图片
从 UML 类图中可以看出工厂方法模式主要包含4个角色:

  • 抽象工厂(Factory),为核心
  • 具体工厂(ConcreteFactoty)。实现了具体的业务逻辑
  • 抽象产品(Product)。是创建的产品的父类
  • 具体产品(ConcreteProduct)。实现了抽象产品的某个具体产品

5.简单实现

举个小例子,前些天看了夏目友人帐剧场版,其中猫咪老师变成了三个,那我假设树洞是个工厂(哈哈哈),然后生产出猫咪老师一号、二号和三号这三个产品。
按照上面的几大角色,首先我们写下我们最终需要生产出的猫咪老师(具体产品,一号、二号和三号 ) 的抽象特征(喝酒),即抽象产品这一角色:

/**
 * 所有生产出的猫咪老师的抽象方法
 */
public abstract class Sansan {
    /**
     * 抽象方法,喝酒
     */
    public abstract   void drink();
}

然后,我们要生产出1号、2号和3号,即具体产品这一角色:

/**
 * 猫咪老师 1 号
 */
public class SansanNo1 extends Sansan{
    @Override
    public void drink() {
        System.out.println(" Hello! Im sansan No.1,I want to drink\n");
    }
}
/**
 * 猫咪老师 2 号
 */
public class SansanNo2 extends Sansan{

    @Override
    public void drink() {
        System.out.println(" Hello! Im sansan No.2,I want to drink\n");
    }
}
/**
 * 猫咪老师 3 号
 */
public class SansanNo3 extends Sansan{

    @Override
    public void drink() {
        System.out.println(" Hello! Im sansan No.3,I want to drink\n");
    }
}

接着,看一下抽象工厂


/**
 * 抽象工厂类,树洞
 */
public abstract class SanSanFactoty {
    /**
     * 抽象工厂方法,具体生产什么让子类去实现
     * @return sansan猫咪老师
     */
    public abstract Sansan createSansan();
}

有了抽象工厂,让我们来实现具体工厂,来生产具体类型的产品:


/**
 * 具体工厂方法,用来决定生产哪一个产品(猫咪老师)
 */
public class CreateSansanFactory extends SanSanFactoty {

    /**
     * 生产猫咪老师
     * @return 具体类型的猫咪老师
     */
    @Override
    public Sansan createSansan() {
//        return  new SansanNo1();
//        return new SansanNo2();
        return new SansanNo3();

    }
}

在需要调用的类里面这样调用:

public static void factoryTest(){
        SanSanFactoty factory = new CreateSansanFactory();
        Sansan sansan = factory.createSansan();
        sansan.drink();
    }

这种比较简单,需要哪个就生产哪个,但是需要改动具体工厂的类。

有时可以利用反射的方式更简洁的来生产具体产品对象,这时需要在工厂方法的参数列表里传入一个 class 类来决定是哪一个产品类。可以如下改动:

/**
 * 抽象工厂类,树洞
 */
public abstract class SanSanFactoty {
    /**
     * 抽象工厂方法,具体生产什么让子类去实现
     * @param clz 产品对象类类型
     * @return 具体的产品对象
     */
    public abstract  T createSansan(Class clz);
}

/**
 * 具体工厂方法,用来决定生产哪一个产品(猫咪老师)
 */
public class CreateSansanFactory extends SanSanFactoty {
    @Override
    public  T createSansan(Class clz) {
        Sansan sansan = null;
        try {
            sansan = (Sansan) Class.forName(clz.getName()).newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }

        return (T) sansan;
    }
  }

需要调用的类改写为:

public static void factoryTest(){
        SanSanFactoty factory = new CreateSansanFactory();
        //Sansan sansan = factory.createSansan(SansanNo1.class);
         Sansan sansan = factory.createSansan(SansanNo2.class);
        sansan.drink();
        
    }

你可能感兴趣的:(设计模式,设计模式,工厂方法)