山一程--EAI--各粒度的架构要点
目的:整理在学习实践中的架构核心,从语言特性到系统集成,各个粒度层次。
1.总览
2.记录
2.1 (java feature) 有界队列防止高负荷的应用程序耗尽内存,线程池简化了线程的管理工作。
2.2 调度任务,使用 DelayQueue, 实现了 BlockingQueue, 为 ScheduledThreadPoolExecutor 提供调度任务,
每个Delay 对象都有一个相应的延迟时间:在DelayQueue 中, 只有某个元素逾期后,DelayQueue take, 从DelayQueue返回的对象根据它们的延迟时间进行排序.
2.3 当需要限定请求时,使用 Semaphore 来限流。
1 public class BoundedHashSet<T> { 2 3 private final Set<T> set; 4 private final Semaphore semaphore; 5 6 public BoundedHashSet(int bound){ 7 this.set = Collections.synchronizedSet(new HashSet<>()); 8 this.semaphore = new Semaphore(bound); 9 } 10 11 public boolean add(T o) throws InterruptedException{ 12 semaphore.acquire(); 13 boolean wasAdded = false; 14 try{ 15 wasAdded = this.set.add(o); 16 return wasAdded; 17 }finally{ 18 if(!wasAdded){ 19 semaphore.release(); 20 } 21 } 22 } 23 24 public boolean remove(T o){ 25 boolean wasRemoved = this.set.remove(o); 26 if(wasRemoved){ 27 semaphore.release(); 28 } 29 return wasRemoved; 30 } 31 }
企业中的报表生成功能,
遍历大量的数据结构并产生报表,采用 Visitor 模式, 使得数据结构中不含有任何产生报表的代码.
如果想增加新报表,只需增加新的访问者,而不需要更改数据结构中的代码。
报表可以放置在不同的组件中,且仅被那些需要它们的客户单独使用.
《敏捷软件开发 模式 原则 和实践》 p347
2023-02-09
背景:项目重构架构时 模块设计困惑。扩展性,重用性, 复习 <Java应用架构设计 模块化与 OSGi> 几个相关的模式.
尽管严重依赖包含大量具体类的模块会更简单. 但这要尽量避免.因为一个变化可能会给所有依赖的模块带来严重的连带影响.
chapter 11 扩展性模式,抽象化模式:
objectFactory: 工厂是唯一引用具体类的地方.封装了创建对象的规则,当修改的时候范围可控。
动态创建:dynamic creation. Class 类反射创建. 例如 Web app, 想在服务器启动时候创建一些特定的类.
抽象工厂模式时,对于指定如何创建具体的工厂,将其指定在属性文件中。
OSGI uService。
客户端依赖于抽象. 挑战是怎样在运行时创建对象间的关系.最常用的是 依赖注入 和 查找。
工厂是抽象了创建过程的一个类。工厂会用不同的配置以多种方式创建实现并将所创建的实例装配起来.
实现工厂通常会与抽象化模块和分离抽象模式一起使用. 这两个模式的目的就是创建高度可扩展的模块化系统.
工厂放在什么地方.
创建过程必须要封装在自己的类中. 当要把类放到模块中的时候,必须要确定工厂类放在哪里。
一般来说,工厂类必须要在单独的模块中,不能位于要创建的类所属的模块中,也不能位于实例要注入进去的那个模块中。
如果工厂是一个类,应该在一个独立的模块中。但是使用依赖注入框架,就不再需要创建自己的工厂类了.
灵活性:类不是通过类数据类型直接引用的,而是基于全限定的类名动态得到的。避免了要规避的紧耦合。
配置文件或类 可以放在其中的一个模块中,
当使用不同实现的新模块时,它们可以包含自己的配置文件或类。
作为一个替代方案。可将配置放在单独的模块中,并在必要的时候只替换这些模块就够了。

2023-02-10
分离抽象 模式
将抽象与实现分离,可以创建新的实现并将其放在自己的模块中, 就能在不修改已有系统的情况下移除既有的实现.
两个关键决策:1.将抽象体放在哪里。2.将实现放在哪里.
关键在于描绘出模块间的依赖,包含实现的模块要依赖包含抽象体的模块.
抽象体要靠近依赖它的类, 并要远离扩展或实现它的类.
通用的指导原则有助于目标的达成:
1. 如果依赖抽象体的所有类都在同一个模块中, 那么将这些类与抽象体放在同一个模块中.
2.如果依赖抽象体的所有类位于多个模块中,那么将抽象体放在一个单独的模块中,这个模块与依赖抽象体的类实现了分离.
如果是 2 的情况,两个在其他方面相互独立的模块共享一个通用的状态, 可能会希望每个模块都独立初始化并管理这个状态, 复杂且不可靠,低性能。
如果每个模块都依赖的状态是简单的数据,模块都需要这个数据进行一些处理,那么每个模块都将其定义为一个 bean 并将这个 bean 传递给需要数据的类.

2023-03-08
架构要点 process, constraint.
同一的 process result, 配合同一的 valiation 结果。
同一的 Factory 总控流程,每个环节的 validation.
将信息范围控制在最小范围,内聚,不要外溢。 此处要求在项目初期,设计要做好.
interface + enum。

浙公网安备 33010602011771号