设计模式之工厂方法模式

设计模式之工厂方法模式

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

优点:

  • 良好的封装性,代码结构清晰,降低模块间的耦合。
  • 扩展性较好,可以通过增加产品类来增加产品,或者增加工厂类来增加工厂。

常见应用场景: 可以在所有需要生成对象的地方使用,尤其是复杂度较高的结构里。

工厂方法模式的通用模板:

抽象产品类:负责定义产品的共性,实现抽象的定义,可以通过接口和抽象类实现

/**
 * @author: lvshui5u
 * @date: 2021/7/18 10:46
 * @describe: 抽象产品类 也可以使用接口
 */
public abstract class Product {
    /**
     * 产品类的公共方法
     */
    public abstract void doSomething();
}

具体产品类:继承抽象产品类,实现对产品的定义

public class ConcreteProduct extends Product{
    @Override
    public void doSomething() {
        // 执行的具体业务逻辑
    }
}

抽象工厂类:负责定义工厂的共性,实现抽象的定义

public abstract class Factory {
    /**
     * 生产一个产品
     * @param c 该产品的 class
     * @param <T> 泛型
     * @return a T extends Product
     */
    public abstract <T extends Product> T createProduct(Class<T> c);
}

具体工厂类:继承抽象工厂类,实现对产品的创建

public class ConcreteFactory extends Factory {
    @Override
    public <T extends Product> T createProduct(Class<T> c) {
        Product product = null;
        try {
            // 通过类反射找到并创建产品
            product = (Product) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T)product;
    }
}

案例: 一家手机代工厂需要生产两种品牌的手机。

手机的定义

/**
 * @author: lvshui5u
 * @date: 2021/7/18 11:30
 * @describe:
 */
public abstract class Phone {
    /**
     * 开机
     */
    public abstract void open();
    /**+
     * 打电话
     */
    public abstract void call();

    /**
     * 关机
     */
    public abstract void shutdown();
}

两种品牌的手机

public class HuaWei extends Phone{
    @Override
    public void open() {
        System.out.println("HuaWei is opening ...");
    }

    @Override
    public void call() {
        System.out.println("HuaWei is calling ...");
    }

    @Override
    public void shutdown() {
        System.out.println("HuaWei is shutdown ing ...");
    }
}
public class Samsung extends Phone{
    @Override
    public void open() {
        System.out.println("Samsung is opening ...");
    }

    @Override
    public void call() {
        System.out.println("Samsung is calling ...");
    }

    @Override
    public void shutdown() {
        System.out.println("Samsung is shutdown ing ...");
    }
}

手机工厂的定义

public abstract class PhoneFactory {
    /**
     * 生产手机
     * @param c 需要生产哪一款呢
     * @param <T> 泛型 是手机就行
     * @return 特定手机
     */
    public abstract <T extends Phone> T createPhone(Class<T> c);

}

手机工厂的实现

public class ConcretePhoneFactory extends PhoneFactory{
    @Override
    public <T extends Phone> T createPhone(Class<T> c) {
        Phone phone = null;
        try {
            // 通过类反射找到并创建产品
            phone = (Phone) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T)phone;
    }
}

进行测试

public class Test {
    public static void main(String[] args) {
        PhoneFactory concretePhoneFactory = new ConcretePhoneFactory();
        HuaWei huaWei = concretePhoneFactory.createPhone(HuaWei.class);
        huaWei.open();
        huaWei.call();
        huaWei.shutdown();
        System.out.println("=================");
        Samsung samsung = concretePhoneFactory.createPhone(Samsung.class);
        samsung.open();
        samsung.call();
        samsung.shutdown();
    }
}

结果

HuaWei is opening ...
HuaWei is calling ...
HuaWei is shutdown ing ...
=================
Samsung is opening ...
Samsung is calling ...
Samsung is shutdown ing ...

Process finished with exit code 0

如果该工厂又接到了苹果的订单,则无需改变其他内容,只需要添加一个 Apple 类继承 Phone 抽象类即可。

public class Apple extends Phone{
    @Override
    public void open() {
        System.out.println("Apple is opening ...");
    }

    @Override
    public void call() {
        System.out.println("Apple is calling ...");
    }

    @Override
    public void shutdown() {
        System.out.println("Apple is shutdown ing ...");
    }
}

参考 《设计模式之禅》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值