工厂模式-简单工厂模式

工厂模式

代码仓库:https://gitee.com/jerry_top/wm_design_patterns.git

1、普通写法

类图

原始类图

案例

package top.jerrymo.pattern.factory.before;
public abstract class Fruit {

    abstract String getName();

    void wash(){
        System.out.println("洗水果");
    }

    void cut(){
        System.out.println("切水果");
    }

}

public class AppleFruit extends Fruit {

    @Override
    String getName() {
        return "苹果";
    }
}

public class BananaFruit extends Fruit {

    @Override
    String getName() {
        return "香蕉";
    }
}

public class FruitShop {

    // 根据类型判断生成对应的水果
    public Fruit create(String type){
        Fruit fruit = null;
        switch (FruitTypeEnum.getInstance(type)){
            case BANANA:
                fruit = new BananaFruit();
                break;
            case APPLE:
                fruit = new AppleFruit();
                break;
            default:
                fruit = new Fruit() {
                    @Override
                    String getName() {
                        return "水果无法识别";
                    }
                };
        }
        System.out.println(fruit.getName());
        return fruit;
    }
}

public enum FruitTypeEnum {

    APPLE("apple", "苹果"),
    BANANA("banana", "香蕉"),
    UNDEFINE("undefine", "无法识别"),
    ;
    ...
    ...    
}

/**
 * @Auther: jerry
 * @Date: 2021-07-03 16:27
 * @Description: 问题:FruitShop 与具体的创建水果类耦合,假如我们需要更换对象,
 *                    则所有new对象的地方都要修改一遍,不符合开闭原则
 *               改进:使用工厂来生成对象,只和工厂类对接,彻底解耦对象,
 *                    如果对象发生改变也只修改工厂类,具体的使用方无需修改(simple_factory)
 */
public class Client {
    public static void main(String[] args) {
        FruitShop fruitShop = new FruitShop();
        Fruit fruit = fruitShop.create(FruitTypeEnum.APPLE.getType());
        fruit.wash();
        fruit.cut();
    }
}

输出:
    苹果
    洗水果
    切水果

总结

  • 问题:FruitShop 与具体的创建水果类耦合,假如我们需要更换对象,则所有new对象的地方都要修改一遍,不符合开闭原则
  • 改进:使用工厂类来生成对象,只和工厂类对接,彻底解耦对象, 如果对象发生改变也只修改工厂类,具体的使用方无需修改

2、简单工厂模式

定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

结构

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。(Fruit)
  • 具体产品 :实现或者继承抽象产品的子类。(BananaFruit,AppleFruit)
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。(SimpleFruitFactory)

类图

idea类图
简单工厂类图

案例

package top.jerrymo.pattern.factory.simple_factory;

public abstract class Fruit {

    abstract String getName();

    void wash(){
        System.out.println("洗水果");
    }

    void cut(){
        System.out.println("切水果");
    }

}

public class AppleFruit extends Fruit {

    @Override
    String getName() {
        return "苹果";
    }
}

public class BananaFruit extends Fruit {

    @Override
    String getName() {
        return "香蕉";
    }
}

public class SimpleFruitFactory {

    public Fruit create(String type){
        Fruit fruit = null;
        switch (FruitTypeEnum.getInstance(type)){
            case BANANA:
                fruit = new BananaFruit();
                break;
            case APPLE:
                fruit = new AppleFruit();
                break;
            default:
                fruit = new Fruit() {
                    @Override
                    String getName() {
                        return "水果无法识别";
                    }
                };
        }
        System.out.println(fruit.getName());
        return fruit;
    }
}

public class FruitShop {

    public Fruit create(String type){
        SimpleFruitFactory factory = new SimpleFruitFactory();
        Fruit fruit = factory.create(type);
        return fruit;
    }
}

/**
 * @Auther: jerry
 * @Date: 2021-07-03 16:27
 * @Description: 优点:封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,
 * 这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,
 * 这样就降低了客户代码修改的可能性,更加容易扩展。
 *               缺点:添加了新的耦合,有新的水果时还是需要修改工厂类,违背了"开闭原则"。
 */
public class Client {
    public static void main(String[] args) {
        FruitShop fruitShop = new FruitShop();
        Fruit fruit = fruitShop.create(FruitTypeEnum.BANANA.getType());
//        fruit.wash();
        fruit.cut();
    }
}
输出:
    香蕉
    切水果

总结

  • 优点:封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户(FruitShop)代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
  • 缺点:添加了新的耦合,有新的水果时还是需要修改工厂类,违背了"开闭原则"。

NEXT

工厂方法模式针对该缺点做了改进。读书百遍,其义自见。我是二十三月,下次见。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值