聊聊 Java 新特性与设计模式

共 5902字,需浏览 12分钟

 ·

2023-01-06 18:41

点击上方“Java技术江湖”,选择“设为星标

回复”666“获取全网最热的Java核心知识点整理


Java 平台与 OpenJDK

让我们从 Java 虚拟机开始。

  • 编译器负责生成字节码;
  • JIT 编译器负责优化成本地代码;
  • JVM 解释器负责输出期望结果。
  • 字节码优化技术:内联 inlining、消除 elimination、标量化 scalarization。


下面是一个优化后的结果示例:


static factory_method.Car produce(java.lang.String);   descriptor: (Ljava/lang/String;)Lfactory_method/Car;  flags: (0x0008) ACC_STATIC  Code:    stack=7, locals=5, args_size=1      0: new #7  // class factory_method/FactoryMethodEvent      3: dup      ...      19: aload_3      20: invokevirtual #17 // Method java/lang/String.hashCode:()I      23: lookupswitch { // 2        313558048        355649863        default75      }      48: aload_3      49: ldc #23  // String fast      51: invokevirtual #25  // Method java/lang/String.equals:(Ljava/lang/Object;)Z


用 SOLID 思想看设计模式


概述 SOLID 原则以及与现在开发需要考虑的一些设计原则:


  • SOLID 原则:单一功能、开闭原则、里氏替换、接口隔离以及依赖反转;

  • 不要重复自己,关注点分离,CAP 原则;

  • 编程语言和技术不可知;

  • 微服务架构、分布式系统领域驱动设计、数据流;

  • 可扩展性、可维护性与安全性。


设计模式分创建型、结构型、行为型,其中行为型设计模式需要考虑服务、运行时的并发

一些重要项目

  • Valhalla 项目:利用通用 API、基础类型和值类型,提升机器学习和大数据应用程序性能
    • 隐藏类(JEP-371)、对值类型 class 进行警告 (JEP-390) 等
  • Panama 项目为 JVM 和非 Java API 提供桥梁,可以更容易地实现 App 之间的 I/O
    • 外部函数和内存 API (JEP-424)、Vector API (JEP-426)等
  • Amber 项目:通过 Java 语言自身演进提升生产率
    • 局部变量类型推断 (JEP-286)、switch 表达式改进 (JEP-361)
    • TextBlocks (JEP-378)、Records (JEP-395), instanceof 的模式匹配 (JEP-394)
    • 密封类 (JEP-409)、默认支持 UTF-8 (JEP-400)、Record 模式 (JEP-405)等
  • Loom 项目: 易于使用,高吞吐量、轻量级并发和编程方法
    • 虚拟线程 (JEP-425)、结构化并发 (JEP-428)等

简化创建对象

  • 备选方案:Factory 或 Builder。二者有何区别?
    • 前者是封装,后者是逐步构建直到最后生产
    • 其它区别包括,如何补充信息、实现可测试性等
  • 其它选择:
    • 抽象工厂、原型模式、单例模式、 对象池延迟初始化、依赖注入

JDK 中使用 Builder:使用 StringBuilder 或者像下面这样:


public class Thread implements Runnable { //JDK19(Preview)    public sealed interface Builder permits Builder.OfPlatform,        Builder.OfVirtual, ThreadBuilders.BaseThreadBuilder {        ..    }}


JDK 中的工厂:使用 Java Collection framework,例如 List、Set 或者 Map。


static <E> List <E> of (E e1, E e2, E e3) {    return ImmutableCollections.listFromTrustedArray(e1, e2, e3);}static <K, V> Map <K, V> of (K k1, V v) {    return new ImmutableCollections.Map1 < > (k1, v1);}


下面是 CarFactory 示例及运行效果:


record FastCar(String type) implements Car { ...sealed interface Factory permits CarFactory { ...final class CarFactory {    static Vehicle produce(String type) {        var result =            switch (type) {                case "fast" - > {                    ...                    yield new FastCar(“super”);                }                case String s                when s.length() > 10 - > new SlowCar()                ...



如何结构化思考


如何围绕实例化对象组织代码(指令)


  • 备选方案:适配器或享元模式;

  • 其它方案:组合模式、装饰器模式、外观模式(也称门面模式)、过滤器模式、模块模式、控制器模式、标记型接口、代理模式、双胞胎模式。


JDK 中的适配器:


public final class Spliterators { ...    public static <T> Iterator <T> iterator(Spliterator <<?extends T> spliterator) {        Objects.requireNonNull(spliterator);        class Adapter implements Iterator <T> , Consumer <T{            ...        }    }}
public Collections { ...    public static <T> ArrayList <T> list(Enumeration <T> e) { ... }


JDK 中的友元:


Integer、Byte、Character 等包装类,以及 valueOf(...)  方法使用到的缓存:


return IntegerCache.cache[i + (-IntegerCache.low)];


下面是 Engine 密封接口示例及运行效果:

var engine = counter++ % 2 == 0 ? new DieselEngine() : new ElectricEngine();var fastCar = new FastCar(engine);
class FastCar { ... FastCar(Engine engine) { ... } public void drive() { ... if (engine instanceof ElectricEngine ee) { ee.checkBatteries(); } engine.run();...sealed interface Engine { void run();}


运行时设置行为

运行时如何维护对象之间的信息传递?

由 JVM 和代码库提供灵活性和可维护性。

  • 备选方案:责任链模式、命令模式、缓存;
  • 其它方案状态模式、策略模式、解释器模式、迭代器模式、中介者模式、 备忘录模式、Null 对象、观察者模式、管道、模板方法、访问者模式等。

JDK 中的责任链:


public class Logger {    public void log(Level level, Supplier < String > msgSupplier)    //overloaded method, Levels: OFF, SEVERE, WARNING ...


JDK 中的命令:


java.lang.Runnablejava.lang.Callable


JDK 中的缓存:


java.util.Localeprivate static class Cache extends LocaleObjectCache < Object, Locale > {    private static final Cache LOCALECACHE = new Cache();


并发相关


那么并行执行的代码该如何考虑呢?


根据问题的多线程性质选择适合的设计模式组合。


  • 备选方案线程池模式;

  • 其它方案主动对象模式、异步方法调用、Balking 模式、双重检查锁定、读写锁、调度器等。


下图中可以看到并发相关 package 在 JDK 中的依赖关系(由 Java Mission Control 8.3 生成)


下面是一个使用虚拟线程的示例:


var threadPerTaskExecutor = Executors.newThreadPerTaskExecutor(threadFactory);var executor = Executors.newVirtualThreadPerTaskExecutor();threadPerTaskExecutor.execute(() - > {    while (active.get()) {        executor.submit(new ComputableTask(counter));    }})


总结


设计模式和 JDK 功能带来了以下好处:


  • 密封类、模式匹配让代码变得更清晰;
  • switch 语法改进、引入 Record 减少了冗余代码
  • Amber 项目、Loom 项目增强了项目可维护性
  • 虚拟线程、结构化并发、switch、局部变量类型推断让组合变得更简单
  • 带来更好的可观测性、性能分析、调试功能。

参考资料

  • Amber项目: https://openjdk.org/projects/amber/
  • Valhalla项目: https://openjdk.org/projects/valhalla/
  • Panama项目: https://openjdk.org/projects/panama/
  • JFR项目: https://github.com/openjdk/jmc
  • OpenJDK: https://openjdk.org/
  • foojay.io: https://foojay.io/today/author/miro-wengner/
  • OpenValue博客: https://openvalue.blog/
  • Practical Design Patterns for Java Developers [PACKT]


转自:Miroslav Wengner 与 Benedikt Neumayr,

链接:slideshare.net/miragemiko/new-java-features-simplified-design-patternslit3826


- EOF -

蚂蚁金服一面:十道经典面试题解析


Java 反射慢?它到底慢在哪?


13 款炫酷的 MySQL 可视化管理工具!好用到爆!!


关注公众号【Java技术江湖】后回复“PDF”即可领取200+页的《Java工程师面试指南》

强烈推荐,几乎涵盖所有Java工程师必知必会的知识点,不管是复习还是面试,都很实用。



浏览 46
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报