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

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

说明

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

工厂模式

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

改造

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

  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()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 3.封装:  封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。 5、String是最基本的数据类型吗?  基本数据类型包括byte、int、char、long、float、double、boolean和short。  java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 6、int 和 Integer 有什么区别  Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型 封装类 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double  引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。 7、String 和StringBuffer的区别  JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。 8、运行时异常与一般异常有何异同?  异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 10、说出ArrayList,Vector, LinkedList的存储性能和特性  ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Ses
Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程中运行,并在特定的同步位置交互 (3)简化异步事件的处理:服务器应用程序在接受来自多个远程客户端的请求时,如果为每个连接都分配一个线程并且使用同步IO,就会降低开发难度 (4)用户界面具备更短的响应时间:现代GUI框架中大都使用一个事件分发线程(类似于中断响应函数)来替代主事件循环,当用户界面用有事件发生时,在事件线程中将调用对应的事件处理函数(类似于中断处理函数) 线程的风险 线程安全性:永远不发生糟糕的事情 活跃性问题:某件正确的事情迟早会发生 问题:希望正确的事情尽快发生 服务时间过长 响应不灵敏 吞吐率过低 资源消耗过高 可伸缩性较低 线程的应用场景 Timer 确保TimerTask访问的对象本身是线程安全的 Servlet和JSP Servlet本身要是线程安全的 正确协同一个Servlet访问多个Servlet共享的信息 远程方法调用(RMI) 正确协同多个对象中的共享状态 正确协同远程对象本身状态的访问 Swing和AWT 事件处理器与访问共享状态的其他代码都要采取线程安全的方式实现 框架通过在框架线程中调用应用程序代码将并发性引入应用程序,因此对线程安全的需求在整个应用程序中都需要考虑 基础知识 线程安全性 定义 当多个线程访问某个类时,这个类始终能表现出正确的行为,那么就称这个类是线程安全的 无状态对象一定是线程安全的,大多数Servlet都是无状态的 原子性 一组不可分割的操作 竞态条件 基于一种可能失效的观察结果来做出判断或执行某个计算 复合操作:执行复合操作期间,要持有锁 锁的作用 加锁机制、用锁保护状态、实现共享访问 锁的不恰当使用可能会引起程序性能下降 对象的共享使用策略 线程封闭:线程封闭的对象只能由一个线程拥有并修改 Ad-hoc线程封闭 栈封闭 ThreadLocal类 只读共享:不变对象一定是线程安全的 尽量将域声明为final类型,除非它们必须是可变的 分类 不可变对象 事实不可变对象 线程安全共享 封装有助于管理复杂度 线程安全的对象在其内部实现同步,因此多个接口可以通过公有接口来进行访问 保护对象:被保护的对象只能通过特定的锁来访问 将对象封装到线程安全对象中 由特定锁保护 保护对象的方法 对象的组合 设计线程安全的类 实例封闭 线程安全的委托 委托是创建线程安全类的最有效策略,只需要让现有的线程安全类管理所有的状态 在现有线程安全类中添加功能 将同步策略文档化 基础构建模块 同步容器类 分类 Vector Hashtable 实现线程安全的方式 将状态封装起来,对每个公有方法都进行同步 存在的问题 复合操作 修正方式 客户端加锁 迭代器 并发容器 ConcurrentHashMap 用于替代同步且基于散列的Map CopyOnWriteArrayList 用于在遍历操作为主要操作的情况下替代同步的List Queue ConcurrentLinkedQueue *BlockingQueue 提供了可阻塞的put和take方法 生产者-消费者模式 中断的处理策略 传递InterruptedException 恢复中断,让更高层的代码处理 PriorityQueue(非并发) ConcurrentSkipListMap 替代同步的SortedMap ConcurrentSkipListSet 替代同步的SortedSet Java 5 Java 6 同步工具类 闭锁 *应用场景 (1)确保某个计算在其需要的所有资源都被初始化后才能继续执行 (2)确保某个服务在其所依赖的所有其他服务都已经启动之后才启动 (3)等待知道某个操作的所有参与者都就绪再继续执行 CountDownLatch:可以使一个或多个线程等待一组事件发生 FutureTask *应用场景 (1)用作异步任务使用,且可以使用get方法获取任务的结果 (2)用于表示一些时间较长的计算 状态 等待运行 正在运行 运行完成 使用Callable对象实例化FutureTask类 信号量(Semaphore) 用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量 管理者一组虚拟的许可。acquire获得许可(相当于P操作),release释放许可(相当于V操作) 应用场景 (1)二值信号量可用作互斥体(mutex) (2)实现资源池,例如数据库连接池 (3)使用信号量将任何一种容器变成有界阻塞容器 栅栏 能够阻塞一组线程直到某个事件发生 栅栏和闭锁的区别 所有线程必须同时到达栅栏位置,才能继续执行 闭锁用于等待事件,而栅栏用于等待线程 栅栏可以重用 形式 CyclicBarrier 可以让一定数量的参与线程反复地在栅栏位置汇集 应用场景在并行迭代算法中非常有用 Exchanger 这是一种两方栅栏,各方在栅栏位置上交换数据。 应用场景:当两方执行不对称的操作(读和取) 线程池 任务与执行策略之间的隐形耦合 线程饥饿死锁 运行时间较长的任务 设置线程池的大小 配置ThreadPoolExecutor 构造参数 corePoolSize 核心线程数大小,当线程数= corePoolSize的时候,会把runnable放入workQueue中 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了” keepAliveTime 保持存活时间,当线程数大于corePoolSize的空闲线程能保持的最大时间。 workQueue 保存任务的阻塞队列 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务 threadFactory 创建线程的工厂 handler 拒绝策略 unit 是一个枚,表示 keepAliveTime 的单位(有NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS,7个可选值 线程的创建与销毁 管理队列任务 饱和策略 AbortPolicy DiscardPolicy DiscardOldestPolicy CallerRunsPolicy 线程工厂 在调用构造函数后再定制ThreadPoolExecutor 扩展 ThreadPoolExecutor afterExecute(Runnable r, Throwable t) beforeExecute(Thread t, Runnable r) terminated 递归算法的并行化 构建并发应用程序 任务执行 在线程中执行任务 清晰的任务边界以及明确的任务执行策略 任务边界 大多数服务器以独立的客户请求为界 在每个请求中还可以发现可并行的部分 任务执行策略 在什么(What)线程中执行任务? 任务按照什么(What)顺序执行(FIFO、LIFO、优先级)? 有多少个(How Many)任务能并发执行? 在队列中有多少个(How Many)任务在等待执行? 如果系统由于过载而需要拒绝一个任务,那么应该选择哪一个(Which)任务?另外,如何(How)通知应用程序有任务被拒绝? 在执行一个任务之前或之后,应该进行什么(What)动作? 使用Exector框架 线程池 newFixedThreadPool(固定长度的线程池) newCachedThreadPool(不限规模的线程池) newSingleThreadPool(单线程线程池) newScheduledThreadPool(带延迟/定时的固定长度线程池) 具体如何使用可以查看JDK文档 找出可利用的并行性 某些应用程序中存在比较明显的任务边界,而在其他一些程序中则需要进一步分析才能揭示出粒度更细的并行性 任务的取消和关闭 任务取消 停止基于线程的服务 处理非正常的线程终止 JVM关闭 线程池的定制化使用 任务和执行策略之间的隐性耦合 线程池的大小 配置ThreadPoolExecutor(自定义的线程池) 此处需要注意系统默认提供的线程池是如何配置的 扩展ThreadPoolExector GUI应用程序探讨 活跃度(Liveness)、性能、测试 避免活跃性危险 死锁 锁顺序死锁 资源死锁 动态的锁顺序死锁 开放调用 在协作对象之间发生的死锁 死锁的避免与诊断 支持定时的显示锁 通过线程转储信息来分析死锁 其他活跃性危险 饥饿 要避免使用线程优先级,因为这会增加平台依赖性,并可能导致活跃性问题。在大多数并发应用程序中,都可以使用默认的线程优先级。 糟糕的响应性 如果由其他线程完成的工作都是后台任务,那么应该降低它们的优先级,从而提高前台程序的响应性。 活锁 要解决这种活锁问题,需要在重试机制中引入随机性(randomness)。为了避免这种情况发生,需要让它们分别等待一段随机的时间 性能与可伸缩性 概念 运行速度(服务时间、延时) 处理能力(吞吐量、计算容量) 可伸缩性:当增加计算资源时,程序的处理能力变强 如何提升可伸缩性 Java并发程序中的串行,主要来自独占的资源锁 优化策略
无论是工作学习,不断的总结是必不可少的。只有不断的总结,发现问题,弥补不足,才能长久的进步!!Java学习更是如此,知识点总结目录如下: 目录 一、 Java概述 3 二、 Java语法基础 5 数据类型 5 运算符号 14 语句 15 函数 15 方法重载(Overloadjing)与重写(Overriding) 16 数组 17 总结 18 三、 常见关键字 20 四、 面向对象★★★★★ 21 五、 封装(面向对象特征之一)★★★★ 23 六、 继承(面向对象特征之一)★★★★ 25 七、 接口(面向对象特征之一)★★★★ 28 八、 多态(面向对象特征之一)★★★★ 30 九、 java.lang.Object 31 十、 异常★★★★ 34 十一、 包(package) 37 十二、 多线程★★★★ 39 为什么要使用多线程 39 创建线程和启动 39 线程的生命周期 44 线程管理 45 线程同步 49 线程通信 52 线程池 58 死锁 64 线程相关类 65 十三、 同步★★★★★ 67 十四、 Lock接口 70 十五、 API 71 String字符串:★★★☆ 71 StringBuffer字符串缓冲区:★★★☆ 73 StringBuilder字符串缓冲区:★★★☆ 74 基本数据类型对象包装类★★★☆ 75 集合框架:★★★★★,用于存储数据的容器。 76 Collection接口 77 Iterator接口 78 List接口 78 Set接口 80 Map接口 81 把map集合转成set的方法 82 使用集合的技巧 83 Collections--集合工具类 83 Arrays—数组对象工具类 84 增强for循环 85 可变参数(...) 86 枚:关键字 enum 86 自动拆装箱 86 泛型 87 System 89 Runtime 90 Math 90 .Date:日期类,月份从0—11 92 Calendar:日历类 93 十六、 IO流:用于处理设备上数据 ★★★★★ 94 IO流的概念 95 字符流与字节流 98 流对象 101 File类 102 Java.util.Properties 103 介绍IO包中扩展功能的流对象 103 十七、 网络编程 110 网络基础之网络协议篇 111 UDP传输 124 TCP传输 126 十八、 反射技术 127 十九、 Ajax原理及实现步骤★★★★★ 130 Ajax概述 130 Ajax工作原理 130 Ajax实现步骤 130 详解区分请求类型: GET或POST 131 $.ajax标准写法 134 二十、 正则表达式:其实是用来操作字符串的一些规则★★★☆ 135 二十一、 设计模式★★★★★ 136 设计模式简介 136 单例设计模式:★★★★★ 156 工厂模式★★★★★ 159 抽象工厂模式★★★★★ 163 建造者模式 170 原型模式 177 适配器模式 182 桥接模式 188 过滤器模式 192 组合模式 193 装饰器模式★★★★★ 196 外观模式 201 享元模式 204 代理模式★★★★★ 208 责任链模式 212 命令模式 216 解释器模式 219 迭代器模式 222 中介者模式 224 备忘录模式 226 观察者模式 230 状态模式 233 空对象模式 236 策略模式★★★★★ 238 模板模式 240 访问者模式 244 设计模式总结★★★★★ 247 二十二、 Java其他总结 248 Java JVM知识点总结 248 equals()方法和hashCode()方法 270 数据结构 273 Array方法类汇总 304 Java数组与集合小结 305 递归 309 对象的序列化 310 Java两种线程类:Thread和Runnable 315 Java锁小结 321 java.util.concurrent.locks包下常用的类 326 NIO(New IO) 327 volatile详解 337 Java 8新特性 347 Java 性能优化 362
Java面向对象 1 1 学习方法与要求 1 2 面向对象语言与面向过程语言的区别 7 3 面向对象?什么对象? 8 4 什么是类? 9 5 如何创建一个类Class? 10 6 如何使用类创建对象 10 7 引用与实例 11 8 实例属性与实例方法 11 9 实例属性与实例方法的使用 12 10 实例属性属于实例本身,与其他实例没有关系 13 11 javaBean编码规范 14 12 练习: 15 13 什么构造方法 16 14 构造方法的作用? 17 15 this关键字 17 16 方法调用时的引用传递还是值传递 19 17 面向对象语言的三大特性:封装,继承,多态 20 18 什么是封装?封装在哪? 20 18.1 封装的好处? 20 19 访问修饰符 20 20 面向对象的特性-继承 21 20.1 继承的关键字:extends 21 20.2 继承的语法格式: 21 20.3 继承的好处 21 20.4 Object类 21 20.5 继承是以什么方法实现的? 22 20.6 两个子类的实例,super会指向同一个父类实例吗? 23 20.7 在创建子类实例时,会创建父类实例,先创建哪个? 23 20.8 在子类构造方法中如何调用父类构造方法? 23 20.9 super关键字 24 20.10 父类中私有属性和私有方法可以继承吗? 24 20.11 在代码开发时先开发父类还是先开发子类? 24 20.12 父类是怎么来的? 25 20.13 父类中放的所有子类的共性。子类可以有自己的特性。 26 20.14 方法重写(核心@Override) 28 20.15 练习: 29 20.16 作业题: 31 21 类与类之间的关系 32 22 GC:垃圾回收机制 33 23 Object类 33 23.1 常用方法:boolean equals(Object) 33 23.2 常用方法:String toString() 34 24 继承整理 34 25 面向对象三大特性:多态(核心) 34 25.1 多态的前提? 35 25.2 什么是多态? 35 25.3 父类的引用指向子类实例时,父类引用可以调用哪些方法? 35 26 引用类型的自动类型与强制类型转换 36 27 多态的应用 37 27.1 在使用多态时的一般格式: 37 27.2 练习:创建一个薪资专员(Persionnel),能计算员工工资,负责汇总当月所有员工的总工资数 38 27.3 练习:NewBasePlusSalesEmployee:针对BasePlusSalesEmployee有固定底薪的销售人员,有任务额度10K,满足任务额度正常发放,不满足任务额度发放底薪的80%,提成正常发放。 38 27.4 练习:设计一个形状类Shape 39 28 abstract关键字 41 28.1 abstract可以修饰的对象 41 28.2 抽象方法 41 28.3 抽象类 41 28.4 抽象方法与抽象类的关系 42 28.5 抽象方法与抽象类的使用 42 28.6 abstract的使用场合 42 29 练习:写一个“愤怒的小鸟”: 43 30 final关键字 43 30.1 final可以修饰到3个地方 43 30.2 引用类型加final修饰表示引用不可变 44 31 static关键字 44 31.1 static关键字可以修饰4个地方 44 31.2 静态属性 44 31.3 静态的与实例的 45 31.4 静态代码块 45 31.5 静态方法 45 31.6 静态方法是不能被继承 46 31.7 如何区分静态方法和实例方法的应用 46 31.8 静态导入(1.5新特性) 46 32 单例模式 47 32.1 饿汉模式 47 32.2 懒汉模式 47 33 接口(interface) 48 33.1 如何创建一个接口。 48 33.2 如何使用接口 48 33.3 如何使用类实现一个接口 49 33.4 接口的细节 49 34 接口的应用(面向对象分析) 49 34.1 案例(第一版,使用接口) 50 34.2 案例(第二版) 52 35面向对象设计原则 54 1、找出应用中可能需求变化的代码,把它们独立出来,不要和那些需求不变化的的代码混在一起 54 2、针对接口编程,而不要针对实现类编程 54 3、多用组合,少用继承(包含实现) 54 4、为了交互对象之间的松耦合设计而努力 54 5、类应该对扩展开放,对修改关闭 54 6、依赖倒置,要依赖抽象,不要依赖具体类 54 36 练习:超市收银 54 37 练习:接口表示一种能力,也可以是一种规范 56 38 策略模式 57 38.1 动作冒险游戏 57 38.2 类图 57 38.3 编写使用武器行为接口和实现类 58 38.4 编写角色类和子类 58 38.5 测试类 58 38.6 动作冒险游戏补丁:增加新的角色和新的技能 59 38.7 编写新的打斗行为 59 38.8 编写新的治疗行为和实现类 59 38.9 修改角色父类 60 38.10 修改King类 60 39 披萨工厂 61 39.1 编写披萨父类 61 39.2 编写各种披萨 61 39.3 编写披萨商品类 62 39.4 简单工厂 63 39.5 使用简单工厂修改商店类 63 39.6 使用简单工厂将创建对象代码单独的封装的好处? 64 39.7 使用常量优化工厂类 64 39.8 测试类 65 40 枚(enum) 65 40.1 创建一个枚 66 40.2 为枚创建实例 66 40.3 如何使用枚的实例 66 40.4 使用枚优化披萨工厂 67 40.5 枚类型也可以有构造方法 68 40.6 枚类型也可以有属性 68 40.7 枚类型也支持带参数的构造方法。 68 40.8 枚类型也可以有实例方法 68 40.9 枚类型也可以支持抽象方法 69 41 内部类 70 41.1 内部类的分类 70 41.2 匿名内部类 70 41.3 成员内部类 71 41.4 静态内部类 72 41.5 局部内部类 73 42 作业 :商超案例,以OOP重构 73

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值