栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

策略枚举的用法四:枚举工厂

Java 更新时间:发布时间: 百科书网 趣学号

策略枚举的用法四:枚举工厂
  • 说明
  • 工厂模式
      • 改造
      • 优点
      • 缺点
      • 优化
      • 使用
      • 结果

说明

本文只对策略枚举可以使用的场景进行说明,不做其他介绍。提供额外的实现思路。

工厂模式

普通的工厂模式,都有一个基本的抽象类或接口,然后具体的实现类。并且由一个工厂类来进行返回实现类。
参考:工厂模式

改造

这里对参考的代码进行改造:

  1. Shape.java、Rectangle.java、Square.java、Circle.java,这四个类不变。
  2. 在ShapeFactory.java类中,存在一个类型:“shapeType”。这个就能够使用枚举进行替换。所以我们就新建一个枚举ShapeTypeEnum.java。如下:
  3. 删除将ShapeFactory.java中的getShape方法,使用ShapeTypeEnum.java的valueOf和getShape方法代替。就可以实现工厂模式到策略工厂的转换。
public enum ShapeTypeEnum {

    CIRCLE(new Circle()),
    RECTANGLE(new Rectangle()),
    SQUARE(new Square()),
    ;

    private Shape shape;

    ShapeTypeEnum(Shape shape) {
        this.shape = shape;
    }

    public Shape getShape() {
        return shape;
    }

}
  1. 在使用的地方,代码修改为:
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      //调用 Circle 的 draw 方法
      shape1.draw();
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
      //调用 Square 的 draw 方法
      shape3.draw();
      System.out.println("***************************************************");
      // 可能存在空指针异常,可以进一步优化 ShapeTypeEnum 类
      ShapeTypeEnum.valueOf("CIRCLE").getShape().draw();
      ShapeTypeEnum.valueOf("RECTANGLE").getShape().draw();
      ShapeTypeEnum.valueOf("SQUARE").getShape().draw();
   }
}

最终结果与原来的一致。

优点
  1. 如果shapeType增加了,我们可以通过修改枚举的时候,马上就能够发现,需要添加一个对应的实现。
  2. 天然的单例实现。如果想要实现多利,也能够通过改造ShapeTypeEnum实现。
缺点

前期代码量会有点大,但是基本属于框架性代码

优化
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public enum ShapeTypeEnum {

    DEFAULT("", new Default()) {
        @Override
        public Shape getShapeImpl() {
            return new Default();
        }
    },
    CIRCLE("CIRCLE", new Circle()) {
        @Override
        public Shape getShapeImpl() {
            return new Circle();
        }
    },
    RECTANGLE("RECTANGLE", new Rectangle()) {
        @Override
        public Shape getShapeImpl() {
            return new Rectangle();
        }
    },
    SQUARE("SQUARE", new Square()) {
        @Override
        public Shape getShapeImpl() {
            return new Square();
        }
    },
    ;

    
    public abstract Shape getShapeImpl();

    
    public static Shape getSingletonShape(String type) {
        return indexOf(type).getShape();
    }

    
    public static Shape getNonSingletonShape(String type) {
        return indexOf(type).getShapeImpl();
    }

    private final static Map map = Stream.of(values()).collect(Collectors.toMap(ShapeTypeEnum::getType, e -> e));

    public static ShapeTypeEnum indexOf(String type) {
        // 避免出现空指针
        return Optional.ofNullable(map.get(type)).orElse(DEFAULT);
    }

    private final String type;
    private final Shape shape;

    ShapeTypeEnum(String type, Shape shape) {
        this.type = type;
        this.shape = shape;
    }

    public String getType() {
        return type;
    }

    public Shape getShape() {
        return shape;
    }

}

每个draw实现的输出,都加上输出当前对象this

   @Override
   public void draw() {
      System.out.println("Inside Default::draw() method." + this);
   }
使用
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      //调用 Circle 的 draw 方法
      shape1.draw();
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
      //调用 Square 的 draw 方法
      shape3.draw();
      System.out.println("*************************单例****************************");
      ShapeTypeEnum.getSingletonShape("CIRCLE").draw();
      ShapeTypeEnum.getSingletonShape("CIRCLE").draw();
      ShapeTypeEnum.getSingletonShape("RECTANGLE").draw();
      ShapeTypeEnum.getSingletonShape("RECTANGLE").draw();
      ShapeTypeEnum.getSingletonShape("SQUARE").draw();
      ShapeTypeEnum.getSingletonShape("SQUARE").draw();
      System.out.println("**********************非单例*****************************");
      ShapeTypeEnum.getNonSingletonShape("CIRCLE").draw();
      ShapeTypeEnum.getNonSingletonShape("CIRCLE").draw();
      ShapeTypeEnum.getNonSingletonShape("RECTANGLE").draw();
      ShapeTypeEnum.getNonSingletonShape("RECTANGLE").draw();
      ShapeTypeEnum.getNonSingletonShape("SQUARE").draw();
      ShapeTypeEnum.getNonSingletonShape("SQUARE").draw();
   }
}
结果
Inside Circle::draw() method.com.csdn.enums4.Circle@677327b6
Inside Rectangle::draw() method.com.csdn.enums4.Rectangle@14ae5a5
Inside Square::draw() method.com.csdn.enums4.Square@7f31245a
*************************单例****************************
Inside Circle::draw() method.com.csdn.enums4.Circle@5b480cf9
Inside Circle::draw() method.com.csdn.enums4.Circle@5b480cf9
Inside Rectangle::draw() method.com.csdn.enums4.Rectangle@6f496d9f
Inside Rectangle::draw() method.com.csdn.enums4.Rectangle@6f496d9f
Inside Square::draw() method.com.csdn.enums4.Square@723279cf
Inside Square::draw() method.com.csdn.enums4.Square@723279cf
**********************非单例*****************************
Inside Circle::draw() method.com.csdn.enums4.Circle@10f87f48
Inside Circle::draw() method.com.csdn.enums4.Circle@b4c966a
Inside Rectangle::draw() method.com.csdn.enums4.Rectangle@2f4d3709
Inside Rectangle::draw() method.com.csdn.enums4.Rectangle@4e50df2e
Inside Square::draw() method.com.csdn.enums4.Square@1d81eb93
Inside Square::draw() method.com.csdn.enums4.Square@7291c18f
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/294999.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号