简单工厂模式、工厂方法模式、抽象工厂模式

博客介绍了简单工厂模式、工厂方法模式和抽象工厂模式。简单工厂模式通过封装、继承、多态降低程序耦合度,便于代码复用;工厂方法模式遵循单一职责原则,解决了简单工厂模式违背开放封闭原则的问题;抽象工厂模式易于更换产品,让创建实例过程与客户端分离,还可使用简单工厂改进或反射加配置文件实现。

简单工厂模式、工厂方法模式、抽象工厂模式

1.简单工厂模式

1.1 原始计算器

一个最简单的计算器类。

package factory.simplenessfactory.Simpleness_two;


import java.util.Scanner;

/**
 * @ClassName CalculatorOne
 * @Description 计算器原始版本
 * @Author 萌白
 * @Date 2019/7/15 11:00
 * @Version 1.0
 */
public class CalculatorOne {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入参数:");
        double num1 = scanner.nextDouble();
        System.out.println("请输入运算方式:");
        String s = scanner.next();
        System.out.println("请输入参数:");
        double num2 = scanner.nextDouble();
        Double d = null;
        switch (s) {
            case "+":
                d = num1 + num2;
                break;
            case "-":
                d = num1 - num2;
                break;
            case "*":
                d = num1 * num2;
                break;
            case "/":
                d = num1 * num2;
                break;
            default:
                System.out.println("此功能待扩展");
                break;
        }
        System.out.println(d);
    }
}

在这个类中计算器的基本功能已经实现,但是该程序不易维护,不易扩展,不易复用。所以该代码的质量极差。所以这样的代码是会被人给唾弃的。所以我们如何写一个容易维护,容易扩展,又容易复用呢?

1.2 面向对象的计算器

面向对象通过封装继承多态把程序的耦合度降低,如上面在其他地方使用的时候就得再次写一次代码,这就是代码的耦合度太高所致,可以使用设计模式使得程序更加的灵活。

我们只需要业务逻辑将其抽取到一个单独类即可。下面这个类,在你想使用它的时候,你只需要进行实例化该对象,然后调用该方法即可使用。这个就可以达到代码的复用性

这里是面向对象的封装。

/**
 * @ClassName CalculatorTwo
 * @Description 计算器面向对象版本
 * @Author 萌白
 * @Date 2019/7/15 11:28
 * @Version 2.0
 */
class Calculator {
    public static Double Calculator(double num1, double num2, String s) {
        Double d = null;
        switch (s) {
            case "+":
                d = num1 + num2;
                break;
            case "-":
                d = num1 - num2;
                break;
            case "*":
                d = num1 * num2;
                break;
            case "/":
                d = num1 * num2;
                break;
            default:
                System.out.println("此功能待扩展");
                break;
        }
        return d;
    }
}

再来一个客户端类

/**
 * @ClassName CalculatorTwo
 * @Description 计算器面向对象版本
 * @Author 萌白
 * @Date 2019/7/15 11:28
 * @Version 2.0
 */
public class CalculatorTwo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入参数:");
        double num1 = scanner.nextDouble();
        System.out.println("请输入运算方式:");
        String s = scanner.next();
        System.out.println("请输入参数:");
        double num2 = scanner.nextDouble();
        Double calculator = Calculator.Calculator(num1, num2, s);
        System.out.println(calculator);
    }
}

在这个类中,也存在问题,那就是紧耦合,虽然我们已经将业务和客户端进行了分离,但是如果我们需要在添加一个开根原酸,我们就需要在Operation类中的switch中添加分支,虽然这种方式是可行的,但是需要改动运算类,所以,有可能导致把加法改成减法,这样问题就大发了^ _ ^,所以我们应该将所有的运算进行分离。

首先我们定义一个抽象类。

package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName Operation
 * @Description 抽象类
 * @Author 萌白
 * @Date 2019/7/15 14:33
 * @Version 3.0
 */
public abstract class Operation {
    private Double num1;
    private Double num2;

    //抽象方法,继承该类必须实现,功能:返回运算结果。
    public abstract Double getResult();

    public Double getNum1() {
        return num1;
    }

    public void setNum1(Double num1) {
        this.num1 = num1;
    }

    public Double getNum2() {
        return num2;
    }

    public void setNum2(Double num2) {
        this.num2 = num2;
    }
}

实现类,加减乘除类

package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationSum
 * @Description 加法运算
 * @Author 萌白
 * @Date 2019/7/15 14:36
 * @Version 3.0
 */
public class OperationSum extends Operation {
    @Override
    public Double getResult() {
        return getNum1() + getNum2();
    }
}
package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationSub
 * @Description 减法类
 * @Author 萌白
 * @Date 2019/7/15 14:36
 * @Version 3.0
 */
public class OperationSub extends Operation {
    @Override
    public Double getResult() {
        return getNum1() + getNum2();
    }
}
package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationMul
 * @Description 乘法类
 * @Author 萌白
 * @Date 2019/7/15 14:37
 * @Version 3.0
 */
public class OperationMul extends Operation {
    @Override
    public Double getResult() {
        return getNum1() + getNum2();
    }
}
package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationMul
 * @Description 乘法类
 * @Author 萌白
 * @Date 2019/7/15 14:37
 * @Version 3.0
 */
public class OperationMul extends Operation {
    @Override
    public Double getResult() {
        return getNum1() + getNum2();
    }
}

工厂类

package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationFactory
 * @Description 简单工厂类
 * @Author 萌白
 * @Date 2019/7/15 14:39
 * @Version 3.0
 */
public class OperationFactory {
    public static Operation createOperation(String operate) {
        Operation ope = null;
        switch (operate) {
            case "+":
                ope = new OperationSum();
                break;
            case "-":
                ope = new OperationSub();
                break;
            case "*":
                ope = new OperationMul();
                break;
            case "/":
                ope = new OperationDiv();
                break;
            default:
                System.out.println("功能有待扩展...");
                break;
        }
        return ope;
    }
}

客户端

package factory.simplenessfactory.Simpleness_two.SimplenessFactory;

/**
 * @ClassName OperationClient
 * @Description 客户端类
 * @Author 萌白
 * @Date 2019/7/15 14:43
 * @Version 3.0
 */
public class OperationClient {
    public static void main(String[] args) {
        Operation operation = OperationFactory.createOperation("+");
        operation.setNum1(11d);
        operation.setNum2(12d);
        Double result = operation.getResult();
        System.out.println(result);
    }
}

这就是一整套的简单工厂模式了,这个模式的好处在,在添加新的功能的时候,你只需要在添加一个新的类,实现抽象类,然后实现其中的方法,在工厂类中添加对应的分支,这样在功能添加的时候又不会改动其他算法类的代码。

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,更具客户端的选择条件动态实例化相关的类,对于客户端来
说,去除了与具体产品的依赖。

简单工厂模式结束,华丽分割线


工厂方法模式

简单工厂模式和工厂方法模式的区别在于工厂类的不同,简单工厂模式中,工厂类在添加算法类的时候,需要添加case分支,这样违背了开放封闭原则,而在工厂方法模式中,每一个算法类多有单一的工厂类,这个是单一职责原则

  1. 我们定义工厂方法创建的对象的接口或者抽象类
  2. 具体的产品实现对象的接口或者抽象类
  3. 定义一个工厂接口或抽象类,其中包含返回对象的方法。
  4. 实现工厂接口,实现方法。
package factory.methodfactory.mode_one;

/**
 * @ClassName Car
 * @Description 抽象类
 * @Author 萌白
 * @Date 2019/7/12 10:50
 * @Version 1.0
 */
public abstract class Car {
    //车的名字
    public String name;
    //车的颜色
    public String color;

    //生产车的抽象方法
    public abstract void car();
}

车的具体实现类

package factory.methodfactory.mode_one;

/**
 * @ClassName Lamborghini
 * @Description 制造兰博基尼具体实现类
 * @Author 萌白
 * @Date 2019/7/12 10:52
 * @Version 1.0
 */
public class Lamborghini extends Car {
    @Override
    public void car() {
        System.out.println("车的名字叫做 >>> " + name + "颜色是 >>> " + color);
    }
}
package factory.methodfactory.mode_one;

/**
 * @ClassName Maserati
 * @Description 制造玛莎拉蒂的具体实现类
 * @Author 萌白
 * @Date 2019/7/12 10:53
 * @Version 1.0
 */
public class Maserati extends Car {
    @Override
    public void car() {
        System.out.println("车的名字叫做 >>> " + name + "颜色是 >>> " + color);
    }
}

定义一个工厂接口,所有的工厂类来实现它。

package factory.methodfactory.mode_one;

/**
 * @ClassName CreateCarFactory
 * @Description 工厂类的接口,所有的工厂类多实现它
 * @Author 萌白
 * @Date 2019/7/12 10:54
 * @Version 1.0
 */
public interface CreateCarFactory {

    public Car createCar();
}

工厂类实现类

package factory.methodfactory.mode_one;

/**
 * @ClassName CreateLamborghiniFactory
 * @Description 生产兰博基尼的工厂类
 * @Author 萌白
 * @Date 2019/7/12 10:55
 * @Version 1.0
 */
public class CreateLamborghiniFactory implements CreateCarFactory {
    @Override
    public Car createCar() {
        return new Lamborghini();
    }
}
package factory.methodfactory.mode_one;

/**
 * @ClassName CreateMaseratiFactory
 * @Description 生成玛莎拉蒂的工厂类
 * @Author 肖杰斌
 * @Date 2019/7/12 10:56
 * @Version 1.0
 */
public class CreateMaseratiFactory implements CreateCarFactory {
    @Override
    public Car createCar() {
        return new Maserati();
    }
}

测试类

package factory.methodfactory.mode_one;

/**
 * @ClassName CarTest
 * @Description 类的描述
 * @Author 萌白
 * @Date 2019/7/12 10:57
 * @Version 1.0
 */
public class CarTest {
    public static void main(String[] args) {
        CreateMaseratiFactory createMaseratiFactory = new CreateMaseratiFactory();
        Car car = createMaseratiFactory.createCar();
        car.color="绿色";
        car.name="玛莎拉蒂";
        car.car();
    }
}

工厂方法模式结束,华丽分割线


抽象工厂模式

抽象工厂模式的优点
好处就是易于叫换产品,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就是的改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。他让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现锋利,不会出现在客户端代码中。
抽象工厂模式的创建:
1. 定义抽象产品(Apple Banana)
2. 对抽象产品进行实现
3. 定义抽象工厂接口,其中包含所有产品创建的抽象方法。(FruitFactory)
4. 具体的工厂,创建具有特定实现的产品对象。

1.定义抽象产品:

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName Apple
 * @Description 定义苹果
 * @Author 肖杰斌
 * @Date 2019/7/15 15:55
 * @Version 1.0
 */
public interface Apple {
    public void apple();
}
package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName Banana
 * @Description 接口的描述
 * @Author 肖杰斌
 * @Date 2019/7/15 15:56
 * @Version 1.0
 */
public interface Banana {
    public void banana();
}

2.定义抽象产品实现

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName NorthApple
 * @Description 苹果实现类
 * @Author 萌白
 * @Date 2019/7/15 15:46
 * @Version 1.0
        */
public class NorthApple implements Apple {
    @Override
    public void apple() {
        System.out.println("这是北方的苹果...");
    }
}
package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName SouthApple
 * @Description 苹果实现类
 * @Author 萌白
 * @Date 2019/7/15 15:46
 * @Version 1.0
 */
public class SouthApple implements Apple {
    @Override
    public void apple() {
        System.out.println("这是南方的苹果...");
    }
}

香蕉实现类

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName DomesticBanana
 * @Description 香蕉的实现类
 * @Author 萌白
 * @Date 2019/7/15 15:48
 * @Version 1.0
 */
public class DomesticBanana implements Banana {
    @Override
    public void banana() {
        System.out.println("这是国内的香蕉...");
    }
}
package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName ImportedBanana
 * @Description 香蕉的实现类
 * @Author 萌白
 * @Date 2019/7/15 15:48
 * @Version 1.0
 */
public class ImportedBanana implements Banana {
    @Override
    public void banana() {
        System.out.println("进口的香蕉...");
    }
}

3.定义抽象工厂接口

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName FruitFactory
 * @Description 创建水果的工厂
 * @Author 萌白
 * @Date 2019/7/15 15:45
 * @Version 1.0
 */
public interface FruitFactory {
    public Banana createBanana();

    public Apple createApple();
}

4.具体的工厂

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName CreateNorthFactory
 * @Description 类的描述
 * @Author 萌白
 * @Date 2019/7/15 16:03
 * @Version 1.0
 */
public class CreateNorthFactory implements FruitFactory {
    @Override
    public Banana createBanana() {
        return new DomesticBanana();
    }

    @Override
    public Apple createApple() {
        return new NorthApple();
    }
}
package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName CreateSouthFactory
 * @Description 类的描述
 * @Author 萌白
 * @Date 2019/7/15 16:00
 * @Version 1.0
 */
public class CreateSouthFactory implements FruitFactory {
    @Override
    public Banana createBanana() {
        return new ImportedBanana();
    }

    @Override
    public Apple createApple() {
        return new SouthApple();
    }
}

5.客户端

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName FruitClient
 * @Description 类的描述
 * @Author 萌白
 * @Date 2019/7/15 16:05
 * @Version 1.0
 */
public class FruitClient {
    public static void main(String[] args) {
        CreateNorthFactory createNorthFactory = new CreateNorthFactory();
        Apple appleFactory = createNorthFactory.createApple();
        Banana bananaFactory = createNorthFactory.createBanana();
        appleFactory.apple();
        bananaFactory.banana();
    }
}

我们还可以使用简单工厂来对抽象工厂进行改进。可以去除FruitFactory、CreateNorthFactory、CreateSouthFactory三大工厂。

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName CreateFruit
 * @Description 简单工厂
 * @Author 萌白
 * @Date 2019/7/15 16:49
 * @Version 1.0
 */
public class CreateFruit {
    private static final String FRUIT = "north";

    //    private static final String fruit="south";
    public static Apple createApple() {
        Apple result = null;
        switch (FRUIT) {
            case "north":
                result = new NorthApple();
                break;
            case "south":
                result = new SouthApple();
        }
        return result;
    }

    public static Banana createBanana() {
        Banana result = null;
        switch (FRUIT) {
            case "north":
                result = new ImportedBanana();
                break;
            case "south":
                result = new DomesticBanana();
                break;
        }
        return result;
    }
}

客户端

package factory.abstractfactory.abstractfactory_two;

/**
 * @ClassName FruitClient
 * @Description 类的描述
 * @Author 萌白
 * @Date 2019/7/15 16:05
 * @Version 1.0
 */
public class FruitClient {
    public static void main(String[] args) {
        //使用简单工厂优化
        Apple apple = CreateFruit.createApple();
        apple.apple();
        Banana banana = CreateFruit.createBanana();
        banana.banana();
    }
}

拓展:在抽象工厂类中,还可以使用反射+配置文件的方式进行来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值