《Android源码设计模式解析与实战》读书笔记(五)——工厂方法模式

第五章 应用最广泛的模式——工厂模式

工厂方法模式是创建型设计模式之一,是一种结构简单的模式,在平时开发中应用很广泛。

1.定义

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


2.使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。


3.简单实现

工厂模式主要有四大角色,一是抽象工厂,它是工厂方法模式的核心;二是具体工厂,它实现了具体的业务逻辑;三是抽象产品,它是工厂方法模式所创建的产品的父类;四是具体产品,它是实现抽象产品的某个具体产品的对象。

/**
 * Description:抽象工厂类
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public abstract class Factory {
    public abstract Product crecteProduct();
}


/**
 * Description:具体工厂类,多工厂方法模式
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public class ConcreteFactoryA extends Factory {
    @Override
    public Product crecteProduct() {
        return new ConcreteProductA();
    }
}

/**
 * Description:工厂设计模式产品抽象类
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public abstract class Product {

    public abstract void design();

    public abstract void assemble();

    public abstract void produce();

}

/**
 * Description:工厂设计模式产品具体类A
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public class ConcreteProductA extends Product {
    @Override
    public void design() {
        System.out.println("design ConcreteProductA");
    }

    @Override
    public void assemble() {
        System.out.println("assemble ConcreteProductA");
    }

    @Override
    public void produce() {
        System.out.println("produce ConcreteProductA");
    }
}

/**
 * Description:工厂设计模式产品具体类A
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public class ConcreteProductB extends Product {
    @Override
    public void design() {
        System.out.println("design ConcreteProductB");
    }

    @Override
    public void assemble() {
        System.out.println("assemble ConcreteProductB");
    }

    @Override
    public void produce() {
        System.out.println("produce ConcreteProductB");
    }
}


如何使用:

在客户端构造一个工厂对象,并通过其工厂方法生产具体的产品对象:

//多工厂方法模式,根据不同工厂类创建不同产品对象
        ConcreteFactoryA concreteFactoryA = new ConcreteFactoryA();
        Product concreteProductA = concreteFactoryA.crecteProduct();
        concreteProductA.design();
        concreteProductA.assemble();
        concreteProductA.produce();


如果想生成别的产品对象,则需要修改工厂方法:

    @Override
    public Product crecteProduct() {
//        return new ConcreteProductA();
        return new ConcreteProductB();
    }

这种方式比较常见,需要某个产品对象就生产哪一个。


有时候可以利用反射来简化生产,而不用去修改代码,这时就需要在工厂方法中传入一个参数Class类来决定具体生产哪一个产品类。

抽象工厂改为:

public abstract class Factory {

    public abstract <T extends Product> T crecteProduct(Class<T> tClass);
    
}

具体工厂类改为:

/**
 * Description:具体工厂类,动态传入需要生产的产品类
 * Created by 禽兽先生
 * Created on 2017/5/8
 */
public class ConcreteFactory extends Factory {

    @Override
    public <T extends Product> T crecteProduct(Class<T> tClass) {
        Product product = null;
        try {
            product = (Product) Class.forName(tClass.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) product;
    }
}


客户端调用时:

        //动态传入需要生产的产品类的类别方式
        ConcreteFactory concreteFactory = new ConcreteFactory();
        Product concreteProduct = concreteFactory.crecteProduct(ConcreteProductA.class);
        concreteProduct.design();
        concreteProduct.assemble();
        concreteProduct.produce();

需要哪一个类的对象就传入哪一个类的类型,这样的方式比较动态,如果不喜欢这种方式,也可以构建多个工厂,各司其职:
public class ConcreteFactoryA extends Factory {
    @Override
    public Product crecteProduct() {
        return new ConcreteProductA();
//        return new ConcreteProductB();
    }

}
public class ConcreteFactoryB extends Factory {
    @Override
    public Product crecteProduct() {
        return new ConcreteProductB();
    }

}
拥有多个工厂的方式称为多工厂方法模式。当工厂只有一个的时候,我们可以简化掉工厂的抽象类,并将工厂方法改为静态方法,这样的方式称为简单工厂模式或静态工厂模式,它是工厂方法模式的一个弱化版本。

4.总结

工厂方法模式是一个很好的设计模式,优点不必多说,它完全符合设计原则,既降低了对象之间的耦合,又将实例化的任务交给子类去做,有很好的扩展性。缺点也在所难免,每次添加新产品时就需要写一个新产品类,还需要引入抽象层,必然会导致类结构的复杂化,所以,在某些情况比较简单时是否需要使用工厂方法模式,就需要设计者自己权衡。
Demo下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值