工厂方法模式(Factory Method Pattern)

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到了其子类。
通用类图:
这里写图片描述

  • 抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义。
  • Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。

鉴于我媳妇太爱吃糖那么,我就以Sugar为例。嗯…如图:
这里写图片描述

AbstractSugarFactory是我们的抽象工厂类

public abstract class AbstractSugarFactory {
    public abstract <T extends Sugar> T createSugar(Class<T> c);
}

具体生产Sugar的工厂类SugarFactory

public class SugarFactory extends AbstractSugarFactory{

    @Override
    public <T extends Sugar> T createSugar(Class<T> c) {
        Sugar sugar = null;
        try {
            sugar  = (Sugar) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) sugar;
    }

}

糖果的总称Sugar

public interface Sugar {
    public void getMaterial();//原料
    public void getFlavor();//味道
}

MM豆,我媳妇喜欢吃,嗯..加上

public class MMBean implements Sugar{

    @Override
    public void getMaterial() {
        System.out.println("make chocolate..");
    }

    @Override
    public void getFlavor() {
        System.out.println("sweet..");
    }

}

还有喜欢吃彩虹糖,也加上

public class Skittles implements Sugar{

    @Override
    public void getMaterial() {
        System.out.println("make fruit...");
    }

    @Override
    public void getFlavor() {
        System.out.println("so sweet...");
    }

}

最后测试类,大家自己掂掂量量写写,demo还是要敲敲的。以上就是一个工厂方法模式。

那么工厂方法有什么优点呢?

  • 良好的封装,代码结构杠杠滴。如果需要哪一个具体的对象,只用知道类名就可以了,降低模块间的耦合。
  • “拥抱变化”,只需要扩展Sugar类或者修改具体的工厂类,比如要增加一个棒棒糖,则只需要增加一个Lollipop类,工厂类不需要修改就可以完成系统扩展。
  • 产品类的实现如何变化,调用者都不用关心,我们只需要关心产品的接口,只要接口不变,系统中的上层模块就不要发生变化。因为产品类的实例化是由工厂类来完成的,一个产品对象具体由哪个产品生成也是由工厂类决定的。
  • 工厂方法模式是典型的解耦框架。高层模块值只要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,我不需要的就不要去交流。符合依赖倒置原则,只依赖产品类的抽象。符合里氏替换原则,使用产品子类替换产品父类。

使用场景:

  • 需要灵活的、可扩展的框架时。

工厂方法模式也可扩展为简单工厂模式:去掉一层抽象工厂类,同时把createSugar方法设置为静态,简化类的创建过程。

public class SugarFactory {

    public static <T extends Sugar> T createSugar(Class<T> c) {
        Sugar sugar = null;
        try {
            sugar  = (Sugar) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) sugar;
    }

}

上述代码实现了简单工厂模式,也叫做静态工厂模式。

当然在复杂项目,可能会遇到初始化一个对象耗费精力情况,使整个系统的代码结构不清晰。那么考虑到结构清晰,那么我们就可以为每个产品类顶一个工厂类,比如MMBean就定义一个MMBeanFactory

public class MMBeanFactory extends AbstractSugarFactory{
    public MMBean createSugar(){
        return new MMBean();
    }
}

Skittles也是一样的…其他代码几乎不变。每一个产品类都创建一个产品工厂类,好处就是结构清晰了很多,但是影响了扩展和维护。当然在一个多工厂模式的应用中,可以增加一个协调类来避免调用者与各个子工厂交流,协调类的作用是封装子工厂类,对高层模块提供统一的访问接口。

Android中也有使用工厂方法模式,相信大家也都用过,BitmapFactory(静态工厂方法模式)。

  • BitmapFactory.decodeFile(String pathName, Options opts)
  • BitmapFactory.decodeResource(Resources res, int id, Options opts)
  • BitmapFactory.decodeStream(InputStream is, Rect outPadding, Options opts)
  • 等等…

BitmapFactory是具体工厂类,返回的都是Bitmap对象(产品类),也都是静态调用的,跟我们上面所说的几乎一样。

吃糖去…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值