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

本文围绕设计模式展开,先介绍了设计模式的分类,包括创建型、结构型和行为型模式及各自包含的常见模式。重点讲解了工厂方法模式,阐述其定义、使用场景,分析 UML 类图中的角色,还通过夏目友人帐的例子给出简单实现,提及可用反射方式生产产品对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

之前一直想了解关于设计模式相关内容,看了何红辉 大神的 《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)
    在这里插入图片描述
    下面来看一下工厂方法模式

2. 工厂方法模式的定义

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

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

3.使用场景

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

4.UML 类图

在这里插入图片描述
从 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 extends Sansan> T createSansan(Class<T> clz);
}

/**
 * 具体工厂方法,用来决定生产哪一个产品(猫咪老师)
 */
public class CreateSansanFactory extends SanSanFactoty {
    @Override
    public <T extends Sansan> T createSansan(Class<T> 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();
        
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值