工厂和抽象工厂有些类似,有的人将工厂模式划为抽象工厂模式的一个特例

简单工厂模式

背景:输入两个数进行计算

需要的类

  • 一个基础的运算类(Operation):
    分别有两个运算参数和一个运算的方法(getResult)
  • 具体的运算类(+ - /):
    *继承基础的运算类
    ,然后重写运算的方法进行计算。
  • 简单工厂的类(OperationFactory):
    在工厂类里面建一个方法,用方法的参数来判断,具体实例化哪个具体的运算类。
  • Main方法:

运算类

  1. public class Operation {
  2. // 方便于子类使用
  3. protected double number_a;
  4. protected double number_b;
  5. // @Description: 在子类重写该方法用于计算结果
  6. public double getResult() throws Exception {
  7. double result = 0;
  8. return result;
  9. }
  10. }

具体的运算类

加减乘除,我这只提供除法类的

  1. public class OperationDiv extends Operation{
  2. //重写计算的方法
  3. @Override
  4. public double getResult() throws Exception {
  5. if(number_b == 0){
  6. throw new Exception("除数不能为:0");
  7. }
  8. return number_a/number_b + number_a%number_b;
  9. }
  10. }

计算器工厂

  1. public class OperationFactory {
  2. //静态方法方便调用
  3. public static Operation createOpection(String operate) throws Exception {
  4. // 预设一个计算器类的父类对象:这样做可以让他少创建几个对象
  5. Operation oper = null;
  6. //不使用if语句,可以少做几次判断
  7. switch (operate){
  8. case "+":
  9. oper = new OperationAdd();
  10. break;
  11. case "-":
  12. oper = new OperationSub();
  13. break;
  14. case "*":
  15. oper = new OperationMul();
  16. break;
  17. case "/":
  18. oper = new OperationDiv();
  19. break;
  20. default:
  21. throw new Exception("请输入正确的运算符:" + operate);
  22. }
  23. return oper;
  24. }
  25. }

使用

  1. 先创建相应的对象,
  2. 给参数赋值
  3. 调用他们父类的方法(都会重写的方法来计算)
  4. 新增一个运算方法只需要,只需要新增一个子类,再只修改简单工厂类就行了
  1. public static void main(String[] args) throws Exception {
  2. Operation oper;
  3. oper = OperationFactory.createOpection("/");
  4. oper.number_a = 1.3;
  5. oper.number_b = 0;
  6. double result = oper.getResult();
  7. System.out.println(result);
  8. }

工厂模式

工厂模式,对于每一个点都要去创建一个工厂类。客户在使用的时候就直接去选择相应的工厂,而不需要在代码上判断选择哪个工厂。

克服了简单工厂违反开放封闭的原则的缺点,利用了多态性,保持简单工厂的优点,但是每次创建一个工厂,增加了开发量。

背景:学雷锋做好事;

  • 一个雷锋工厂的接口
    包含一个创建的方法,用于实例化对象。
  • 一个雷锋的产品类:
    包含了相应的一些方法,方法块可以为空,也可以有默认的方法块。
  • 具体的产品类继承雷锋的产品类:
    重写雷锋产品类的方法块,不重写的话就调用父类的方法。
  • 具体的产品工厂类,实现工厂接口类:
    实现父类方法:实例化相应的产品类。
  • Main:

雷锋工厂接口

  1. public interface IFactory {
  2. public LeiFeng CreateLiFeng();
  3. }

雷锋产品类(父类)

  1. public class LeiFeng {
  2. //方法的代码块可以为空
  3. public void Sweep(){}
  4. public void Wash(){
  5. System.out.println("洗衣");
  6. }
  7. public void BuyRice(){
  8. System.out.println("买菜");
  9. }
  10. }

具体类

  1. public class Undergraduate extends LeiFeng{
  2. @Override
  3. public void Sweep(){
  4. System.out.println("学雷锋的大学生::扫地");
  5. }
  6. @Override
  7. public void Wash(){
  8. System.out.println("学雷锋的大学生::洗衣");
  9. }
  10. @Override
  11. public void BuyRice(){
  12. System.out.println("学雷锋的大学生::买菜");
  13. }
  14. }

具体工厂类

  1. public class UndergraduateFactory implements IFactory {
  2. @Override
  3. public LeiFeng CreateLiFeng() {
  4. return new Undergraduate();
  5. }
  6. }

Main

我们在使用的时候,不需要考虑调用的是哪个类。先实例化一个工厂接口,然后调用创建的方法。因为返回的都是父类所以,不在父类的方法是使用不了的。

  1. public class FactoryMain {
  2. public static void main(String[] args){
  3. IFactory factory = new UndergraduateFactory();
  4. LeiFeng student = factory.CreateLiFeng();
  5. student.Sweep();
  6. student.BuyRice();
  7. student.Wash();
  8. }
  9. }

抽象工厂模式

抽象工厂和工厂模式有些类似,抽象工厂的工厂接口和方法以及相应的产品父类都是抽象。

工厂模式是接口,抽象工厂是抽象类

  • 抽象工厂类:
    包含一个抽象的返回值为抽象产品的方法(没有实现方法内容),作为子工厂类实例化相应的产品类。
  • 抽象产品类:
    包含一个抽象的方法,同样没有代码实现块。
  • 具体产品类:
    继承抽象产品类并且重写抽象方法。
  • 具体的工厂:
    继承抽象工厂类,重写实例化产品类的方法。可以继续写其他的类
  • Main方法调用:
    调用其实和工厂模式一样。

抽象产品类

  1. public abstract class Product {
  2. public abstract void show();
  3. }

抽象工厂类

  1. public abstract class Factory {
  2. public abstract Product Manufacture();
  3. }

具体产品类

  1. public class ProductA extends Product{
  2. @Override
  3. public void show() {
  4. System.out.println("生产产品A");
  5. }
  6. }

具体工厂类

  1. public class FactoryA extends Factory{
  2. @Override
  3. public Product Manufacture() {
  4. return new ProductA();
  5. }
  6. }

调用

  1. public class AbstarctFactoryA {
  2. public static void main(String[] args) {
  3. //一般是通过抽象父类而不是具体的工厂类
  4. //这种调用就和没使用设计模式一样的
  5. FactoryA factoryA =new FactoryA();
  6. factoryA.Manufacture().show();
  7. factoryA.Men();
  8. System.out.println("---------------------------------------");
  9. FactoryB factoryB = new FactoryB();
  10. factoryB.Manufacture().show();
  11. //正常的抽象模式调用方法
  12. Factory factoryAA = new FactoryA();
  13. Product product = factoryAA.Manufacture();
  14. product.show();
  15. //偷懒的调用
  16. factoryAA.Manufacture().show();
  17. }
  18. }