设计模式之禅笔记---工厂方法模式

工厂方法模式

Define an interface for creating an object,but let subclasses decide whichclass to instantiate.Factory Method lets a class defer instantiation tosubclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

抽象产品类

拆解一下这段定义,第一步,定义一个用于创建对象的接口,我们以流传已广的种水果举例,水果的通用特性取颜色和名称,因为是通用特性,所以此处水果是一个接口。

public interface Fruit {
    void getFruitName();
    void getFruitColor();
}

为了简化过程,此处只加入苹果和香蕉两种,分别实现水果的接口。

public class Banana implements Fruit {
    @Override
    public void getFruitName() {
        System.out.println("this is banana");
    }

    @Override
    public void getFruitColor() {
        System.out.println("this is yellow");
    }
}

public class Apple implements Fruit{

    @Override
    public void getFruitName() {
        System.out.println("this is apple");
    }

    @Override
    public void getFruitColor() {
        System.out.println("this is red");
    }
}

创建抽象工厂

既然水果的接口有了,那么该种水果了,至于种什么水果,这里不需要操心,那是实现类中的事情。

public abstract class AbsCreateFruit {
    public abstract <T extends Fruit> T createFruit(Class<T> c);
}

定义一个抽象接口,加入一个抽象的种水果的方法交给子类去实现,子类通过反射获取到自己想实现的水果即可。

实现工厂

public class CreateFruit extends AbsCreateFruit {

    Fruit fruit = null;

    @Override
    public <T extends Fruit> T createFruit(Class<T> c) {
        try {
            fruit = (Fruit) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T)fruit;
    }
}

利用反射获取到需要种的水果,完成创建工作。

最后的实现

public class GrowFruit {
    public static void main(String[] args) {
        CreateFruit createFruit = new CreateFruit();
        Fruit apple = createFruit.createFruit(Apple.class);
        apple.getFruitColor();
        apple.getFruitName();

        Fruit banana = createFruit.createFruit(Banana.class);
        banana.getFruitName();
        banana.getFruitColor();
    }
}

在设计模式之禅中给出了通用类图

  • Product :负责定义产品的公共的特性
  • ConcreteProduct :具体的产品
  • Create :抽象创建类,也就是抽象工厂
  • ConcreateCreator : 具体的实现类

工厂方法模式的优点

一、封装良好,结构清晰

需要创建一个具体的产品,只需要知道产品类的名称即可,降低了模块之间的耦合。

二、扩展性优秀

如果需要添加一个新的水果品种,只需要加入一个新的实现类,工厂类本身是不需要任何修改的。符合对修改关闭,对增加开发的原则。

三、屏蔽产品类

产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化

简单工厂模式

在首次接触工厂模式的时候,第一次见到的大概就是简单工厂模式,工厂模式就是在上述框架的基础上去掉了抽象的创建类,使用了方法,简化了代码逻辑,但是出现了扩展困难的问题,也不符合开闭原则。

实现类和场景类修改如下

public class CreateFruit {

    public static <T extends Fruit> T createFruit(Class<T> c) {
        Fruit fruit = null;
        try {
            fruit = (Fruit) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T)fruit;
    }
}

public class GrowFruit {
    public static void main(String[] args) {
        Fruit apple = CreateFruit.createFruit(Apple.class);
        apple.getFruitColor();
        apple.getFruitName();

        Fruit banana = CreateFruit.createFruit(Banana.class);
        banana.getFruitName();
        banana.getFruitColor();
    }
}

多工厂类

多工厂模式

每一个具体的产品类都会对应一个创建者,每一个创建者都会独立负责创建对应的产品对象,符合单一职责。

于是,水果的抽象类可以修改如下

public abstract class AbsCreateFruit {
    public abstract Fruit createFruit();
}

工厂实现

public class AppCreateFruit extends AbsCreateFruit {
    @Override
    public Fruit createFruit() {
        return new Apple();
    }
}

最后的调用

public class GrowFruit {
    public static void main(String[] args) {
        Fruit apple = new AppCreateFruit().createFruit();
        apple.getFruitColor();
        apple.getFruitName();
    }
}

优势

创建简单,结构清楚,通俗易懂

参考和引用

设计模式之禅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值