首页 > 其他分享 >详解51种企业应用架构模式

详解51种企业应用架构模式

时间:2024-06-05 12:30:47浏览次数:22  
标签:Java 51 模式 企业应用 详解 使用 运行机制 时机

导读:企业应用包括哪些?它们又分别有哪些架构模式?世界著名软件开发大师Martin Fowler给你答案

一、什么是企业应用

我的职业生涯专注于企业应用,因此,这里所谈及的模式也都是关于企业应用的。(企业应用还有一些其他的说法,如“信息系统”或更早期的“数据处理”。)那么,这里的“企业应用”具体指的是什么呢?我无法给出一个精确的定义,但是我可以罗列一些个人的理解。

先举几个例子。企业应用包括工资单、患者记录、发货跟踪、成本分析、信用评分、保险、供应链、会计、客户服务以及外汇交易等。企业应用不包括汽车燃油喷射、文字处理、电梯控制、化工厂控制器、电话交换机、操作系统、编译器以及电子游戏等。

企业应用一般都涉及持久化数据。 数据必须持久化是因为程序的多次运行都需要用到它们——实际上,有些数据需要持久化若干年。在此期间,操作这些数据的程序往往会有很多变化。这些数据的生命周期往往比最初生成它们的那些硬件、操作系统和编译器还要长。在此期间,为了存储新的信息而不干扰旧的信息,数据的结构经常会发生许多变化。即使是有根本性的变化发生,或公司安装了一套全新的软件来处理某项任务,这些数据也必须被“迁移”到新的应用上。

企业应用一般都涉及大量数据——一个中等规模的系统往往都包含1GB以上的数据,这些数据是以数千万条记录的方式存在的。巨大的数据量导致数据的管理成为系统的主要工作。早期的系统使用的是索引文件结构,如IBM的VSAM和ISAM。现代的系统往往采用数据库,绝大多数是关系型数据库。设计和填充这些数据库已经成为一个独立的专业领域。

企业应用一般还涉及很多人并发访问数据。对于很多系统来说,人数可能在100人以下,但是对于一些通过互联网进行通信的基于Web的系统,人数则会呈指数级增长。要确保这些人都能够正确地访问数据,就一定会存在这样或那样的问题。即使人数没有那么多,要确保两个人在同时操作同一数据项时不出现错误,也是存在问题的。事务管理工具可以处理其中的一些负担,但是它通常无法做到对应用开发者隐藏。

企业应用还涉及大量操作数据的用户界面屏幕。有几百个用户界面屏幕是不足为奇的。企业应用的用户从偶尔使用到定期使用都有,他们也经常没什么技术背景。因此,出于不同的使用目的,数据需要很多种表现形式。系统一般都有很多批处理过程,但当专注于强调用户交互的用例时,这些批处理过程很容易被忽视。

企业应用很少独立存在,通常需要与散布在企业周围的其他企业应用集成。这些各式各样的系统是在不同时期采用不同技术构建的,甚至连协作机制都不同:COBOL数据文件、CORBA系统或是消息系统。企业经常希望能用一种统一的通信技术来集成所有系统。当然,每次这样的集成工作几乎都很难真正实现,所以会有几个不同的统一集成方案同时存在。当业务组织需要同其业务伙伴进行应用集成时,情况就更糟糕。

即使是某家公司统一了集成技术,它们也还是会遇到业务流程中的差异以及数据中概念的不一致性。一个部门可能认为客户是当前签有协议的人,而另外一个部门可能还要将那些以前有合同但现在已经没有了的人计算在内。再有,一个部门可能只关心产品销售而不关心服务销售。粗看起来,这些问题似乎容易解决,但是,一旦几百条记录中的每个字段都有可能存在着细微差别,问题的规模就会形成不小的挑战——就算唯一知道这些字段真正含义的员工还在公司任职(当然,所有这些都会毫无预警地发生变化)。这样,数据就必须被不停地以各种不同的语法和语义格式读取、转换和写入。

再接下来的问题是由“业务逻辑”带来的。我认为“业务逻辑”这个词很滑稽,因为很难再找出什么东西比“业务逻辑”更加没有逻辑。当我们构建一个操作系统时,总是尽可能地使得系统中的各种事物符合逻辑。而业务规则是人家给你的,没有相当的行政努力,不要想改变它,当然,它们都有自己的理由。你必须面对很多奇怪的条件,而且这些条件相互作用的方式也非常怪异。比如,某个销售人员为了签下其客户几百万美元的一张单,可能会在商务谈判中与对方达成协议,将该项目的年度到账时间推迟两天,因为这样才能够与该客户的账务周期相吻合。成千上万的这类“一次性特殊情况”最终导致了复杂的业务“无逻辑”,使得商业软件开发那么困难。在这种情况下,必须尽量将这些业务逻辑组织成有效的方式,因为我们可以确定的是,这些“逻辑”一定会随着时间不断变化。

图片

▲对不同的领域逻辑组织方式,领域逻辑的复杂度和工作量之间的关系示意

对于一些人来说,“企业应用”这个术语指的是大型系统。但是记住这一点很重要:并不是所有的企业应用都是大型的,尽管它们可能都为企业提供巨大的价值。很多人认为,由于小型系统的规模不大,所以不值得为之操心,在某种程度上,这是合理的。如果一个小型系统失败了,它通常不会像大型系统那样引起广泛关注。但是,我认为这种思想没有对小型项目的累积效应给予足够的重视。试想,如果在小型项目上能够进行某些改善措施,那么这种累积效应对企业的影响是非常显著的,特别是因为小型项目通常具有不成比例的价值。实际上,你可以做的最好的事情之一是通过简化架构和过程,将一个大型项目变成小型项目。

二、企业应用的种类

在我们讨论如何设计企业应用以及使用哪些模式之前,认识到这一点很重要:企业应用是多种多样的,不同的问题将导致不同的处理方法。如果有人说,“总是这样做”的时候,就应当敲响警钟了。我认为,设计中最具挑战性(也是我最感兴趣)的地方就是了解有哪些候选的设计方案以及各种不同设计方案之间的优劣比较。进行选择的空间很大,但我在这里只选三个方面。

考虑一个B2C(Business to Customer)的在线零售商:人们浏览和——运气好,还有购物车——购买。这样一个系统必须能够应付大量的用户,因此,其解决方案不但要考虑到资源利用的高效,还要考虑到系统的可伸缩性,以便在用户规模增大时能够通过增加硬件的办法加以解决。这样的应用的领域逻辑可能非常直接:获取订单,进行简单的价格计算和发货计算,给出发货通知。我们希望任何人都能够轻松访问该系统,因此用户界面可以选用通用的Web表现方式,以支持各种不同的浏览器。数据源包括用来存放订单的数据库,还可能包括某种与库存系统的通信交流,以便获得商品的可用性信息和发货信息。

再考虑一个租约自动处理系统。在某些方面,这样的系统比起前面介绍的B2C零售商系统要简单得多,因为它的用户数很少(在特定时间内不会超过100个),但是它的业务逻辑却比较复杂。计算每个租约的月供,处理诸如提早解约和逾期付款这样的事件,签订合同时验证各种数据,这些都是复杂的任务,因为租约行业的许多竞争都是以过去的交易为基础稍加变化而出现的。正是因为规则的随意性很大,才使得像这样一个复杂的业务领域具有挑战性。

这样的系统在用户界面(UI)上也更加复杂。这就要求HTML界面要能提供更丰富的功能和更复杂的屏幕,而这些要求往往是HTML前端目前无法达到的,需要更传统的富客户界面。用户交互的复杂性还会带来事务行为的复杂性:签订租约可能要耗时1~2小时,这期间用户要处于一个逻辑事务中。一个复杂的数据库设计方案中可能也会涉及200多个表以及一些有关资产评估和计价的软件包。

第三个例子是一家小型公司使用的简单的“开支跟踪系统”。这个系统的用户很少,逻辑简单,并且可以通过HTML表示轻松地在整个公司访问,唯一的数据源是数据库中的几个表。尽管如此,开发这样的系统也不是没有挑战。一方面你必须快速地开发出它,另一方面你又必须为它以后可能的发展考虑:也许以后会为它增加计算报销支票的功能,也许它会被集成到工资系统中,也许还要增加关于税务的功能,也许要为公司的CFO生成汇总报表,也许会被集成到一个航空订票Web Service中,等等。如果在这个系统的开发中,也试图使用前面两个例子中的一些架构,可能会影响开发进度。如果一个系统会带来业务效益(如所有的企业应用应该的那样),则系统进度延误同样也是开销。你不希望现在做出的决策会阻碍未来的发展。但是,如果现在就考虑了这些灵活性但是考虑不得当,额外的复杂性又可能会让系统在未来变得更难演化,进一步延误系统部署,减少系统的效益。虽然这类系统很小,但是一个企业中往往有很多这样的系统,这些系统的架构不良性累积起来,后果将会非常可怕。

这三个企业应用的例子都有难点,而且难点各不相同。当然,也不可能有一个适合于三者的通用架构。选择架构时,必须很清楚地理解系统的特定问题,在理解的基础上再来选择合适的设计。

三、企业架构模式

模式的概念早就有了。我在这里不想把这段历史重新演绎一遍。只是想简单谈谈我对模式和它们为什么是描述设计的重要手段的一些看法。

模式没有统一的定义,可能最好的起点是Christopher Alexander给出的定义(这也是许多模式狂热者的灵感来源):

“每一个模式描述了一个在我们周围不断重复发生的问题以及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”[Alexanderet al.]。

尽管Alexander是建筑家,他谈论的是建筑模式,但其定义也能很好地适用于软件业。模式的核心就是特定的解决方案,它有效而且有足够的通用性,能解决重复出现的问题。模式的另一种视角是把它看成一组建议,而创造模式的艺术则是将很多建议分解开来,形成相互独立的组,在此基础上可以相对独立地讨论它们。

模式的关键点是它们源于实践。必须观察人们的工作过程,发现其中好的设计,并找出“这些解决方案的核心”。这并不是一个简单的过程,但是一旦发现了某个模式,它将是非常有价值的。

一旦需要使用模式,就必须知道如何将它运用于当前的问题。使用模式的关键之一是不能盲目使用,这也是模式工具为什么都那么惨。我认为模式是一种“半生不熟品”,为了用好它,还必须在自己的项目中把剩下的那一半“火候”补上。我本人每次在使用模式时,都会东改一点西改一点。因此你会多次看到同一个解决方案,但没有一次是完全相同的。

每个模式相对独立,但又不彼此孤立。有时候它们相互影响,如影随形。

常见的企业系统架构模式包括三层架构、微服务架构和事件驱动架构。下面,我们介绍这些架构模式的特点,并通过代码示例来具体说明。

三层架构

三层架构是一种常见的企业系统架构模式,它将整个系统分为三个层次:表示层、业务逻辑层和数据访问层。表示层负责用户界面的展示,业务逻辑层负责处理具体的业务逻辑,数据访问层负责与数据库进行交互。这种架构模式能够提供灵活性和可维护性,便于系统的扩展和升级。

代码示例:

// 表示层
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/list")
    public String listUsers(Model model) {
        List<User> users = userService.getAllUsers();
        model.addAttribute("users", users);
        return "user/list";
    }
}

// 业务逻辑层
@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public List<User> getAllUsers() {
        return userDao.getAllUsers();
    }
}

// 数据访问层
@Repository
public class UserDao {
    public List<User> getAllUsers() {
        // 从数据库中获取所有用户数据
        // ...
    }
}

微服务架构

微服务架构是一种将系统拆分为多个小型、独立的服务的架构模式。每个微服务都是一个独立运行和部署的服务单元,它们通过轻量级的通信机制进行交互。微服务架构提供了高度可伸缩性和可扩展性,便于团队协作和系统维护。

代码示例:

// 用户服务微服务
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{userId}")
    public User getUser(@PathVariable String userId) {
        return userService.getUser(userId);
    }
}

// 订单服务微服务
@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/{orderId}")
    public Order getOrder(@PathVariable String orderId) {
        return orderService.getOrder(orderId);
    }
}

// 用户服务
@Service
public class UserService {
    public User getUser(String userId) {
        // 调用用户服务的数据库查询接口获取用户数据
        // ...
    }
}

// 订单服务
@Service
public class OrderService {
    public Order getOrder(String orderId) {
        // 调用订单服务的数据库查询接口获取订单数据
        // ...
    }
}

事件驱动架构

事件驱动架构是一种将系统设计为由事件驱动的架构模式。系统中的各个组件通过发布和订阅事件的方式进行通信,每个组件只需关注自己感兴趣的事件,从而提高系统的灵活性和可扩展性。事件驱动架构可以用于构建高度可伸缩的分布式系统。

代码示例:

// 事件发布者
@Component
public class EventPublisher {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void publishEvent(Event event) {
        eventPublisher.publishEvent(event);
    }
}

// 事件订阅者
@Component
public class EventSubscriber implements ApplicationListener<Event> {
    @Override
    public void onApplicationEvent(Event event) {
        // 处理事件
        // ...
    }
}

// 事件
public class Event {
    // ...
}


四、好书推荐

《企业应用架构模式》一书中总结出的51种模式:

在这里插入图片描述

如果你是一个有经验的企业应用设计师,也许会对大多数模式都很熟悉。模式不是什么新鲜概念。因此,撰写模式书籍的作者也不会声称我们“发明”了某某模式,而是说我们“发现”了某某模式。我们的职责是记录通用的解决方案,找出其核心,并把最终的模式记录下来。对于一个高级设计师,模式的价值并不在于它给予你一些新东西,而在于它能帮助你更好地交流。如果你和你的同事都明白什么是远程外观,你就可以这样非常简捷地交流大量信息:“这个类是一个远程外观模式。”也可以对新人说:“用数据传输对象模式来解决这个问题。”模式为设计提供了一套词汇,这也是模式的名字如此重要的原因。

当你使用模式时请记住:它们只是开始,而不是结束。任何作者去囊括项目开发中的所有变化和技术是不可能的。我编写《企业应用架构模式》一书的目的也只是作为一个开始,希望它能够把我自己的和我所了解的经验和教训传递给读者,你们可以在此基础上继续努力。请大家记住:所有模式都是不完备的,你们都有责任在自己的系统中完善它们,你们也会在这个过程中得到乐趣。

在这里插入图片描述

关于作者:

马丁·福勒(Martin Fowler),世界著名软件开发大师,Thoughtworks首席科学家,从事软件开发相关工作30余年,是全球软件架构、敏捷开发、极限编程、设计模式等多个领域的领袖人物。此外,他在面向对象分析与设计、UML、数据库、领域特定语言等领域也有深厚的积累和卓越的贡献。

购书链接→:点此进入

文章目录

目  录Contents 译者序 前言 模式列表 引言 1
0.1 架构 1
0.2 企业应用 2
0.3 企业应用的种类 4
0.4 关于性能的考虑 5
0.5 模式 7
0.5.1 模式的结构 8
0.5.2 模式的局限性 9 第一部分 表  述 第1章 分层 12
1.1 企业应用中层次的演化 13
1.2 三个基本层次 14
1.3 为各层选择运行环境 16 第2章 组织领域逻辑 18
2.1 抉择 21
2.2 服务层 22 第3章 映射到关系数据库 24
3.1 架构模式 24
3.2 行为问题 28
3.3 读取数据 29
3.4 结构映射模式 30
3.4.1 关系的映射 30
3.4.2 继承 32
3.5 建立映射 34
3.6 使用元数据 35
3.7 数据库连接 36
3.8 其他问题 38
3.9 进一步阅读 38 第4章 Web表示层 39
4.1 视图模式 41
4.2 输入控制器模式 43
4.3 进一步阅读 44 第5章 并发 45
5.1 并发问题 46
5.2 执行语境 47
5.3 隔离与不变性 48
5.4 乐观并发控制和悲观并发控制 48
5.4.1 避免不一致读 49
5.4.2 死锁 50
5.5 事务 51
5.5.1 ACID 52
5.5.2 事务资源 52
5.5.3 减少事务隔离以提高灵活性 53
5.5.4 业务事务和系统事务 54
5.6 离线并发控制的模式 55
5.7 应用服务器并发 56
5.8 进一步阅读 57 第6章 会话状态 58
6.1 无状态的价值 58
6.2 会话状态 59
6.3 存储会话状态的方法 60 第7章 分布策略 63
7.1 分布对象的诱惑 63
7.2 远程接口和本地接口 64
7.3 必须使用分布的情况 65
7.4 关于分布边界 66
7.5 分布接口 67 第8章 通盘考虑 68
8.1 从领域层开始 69
8.2 深入到数据源层 70
8.2.1 事务脚本的数据源 70
8.2.2 表模块的数据源 70
8.2.3 领域模型的数据源 70
8.3 表示层 71
8.4 一些关于具体技术的建议 72
8.4.1 Java和J2EE 72
8.4.2 .NET 73
8.4.3 存储过程 73
8.4.4 Web Services 74
8.5 其他分层方式 74 第二部分 模  式 第9章 领域逻辑模式 78
9.1 事务脚本 78
9.1.1 运行机制 78
9.1.2 使用时机 79
9.1.3 收入确认问题 80
9.1.4 例:收入确认(Java) 81
9.2 领域模型 83
9.2.1 运行机制 84
9.2.2 使用时机 86
9.2.3 进一步阅读 86
9.2.4 例:收入确认(Java) 86
9.3 表模块 90
9.3.1 运行机制 91
9.3.2 使用时机 93
9.3.3 例:基于表模块的收入 确认(C#) 93
9.4 服务层 96
9.4.1 运行机制 97
9.4.2 使用时机 99
9.4.3 进一步阅读 100
9.4.4 例:收入确认(Java) 100 第10章 数据源架构模式 103
10.1 表数据入口 103
10.1.1 运行机制 103
10.1.2 使用时机 104
10.1.3 进一步阅读 105
10.1.4 例:人员入口(C#) 105
10.1.5 例:使用ADO.NET 数据集(C#) 107
10.2 行数据入口 109
10.2.1 运行机制 110
10.2.2 使用时机 110
10.2.3 例:人员记录(Java) 111
10.2.4 例:领域对象的数据 保持器(Java) 114
10.3 活动记录 115
10.3.1 运行机制 115
10.3.2 使用时机 116
10.3.3 例:一个简单的Person类 (Java) 116
10.4 数据映射器 118
10.4.1 运行机制 119
10.4.2 使用时机 122
10.4.3 例:一个简单的数据 映射器(Java) 123
10.4.4 例:分离查找器(Java) 127
10.4.5 例:创建一个空对象 (Java) 130 第11章 对象-关系行为模式 132
11.1 工作单元 132
11.1.1 运行机制 132
11.1.2 使用时机 136
11.1.3 例:使用对象注册的工作 单元(Java) 137
11.2 标识映射 140
11.2.1 运行机制 141
11.2.2 使用时机 143
11.2.3 例:标识映射中的方法 (Java) 143
11.3 延迟加载 144
11.3.1 运作机制 144
11.3.2 使用时机 146
11.3.3 例:延迟初始化(Java) 146
11.3.4 例:虚代理(Java) 147
11.3.5 例:使用值保持器(Java) 148
11.3.6 例:使用重影(C#) 149 第12章 对象-关系结构模式 156
12.1 标识字段 156
12.1.1 工作机制 156
12.1.2 使用时机 159
12.1.3 进一步阅读 160
12.1.4 例:整型键(C#) 160
12.1.5 例:使用键表(Java) 161
12.1.6 例:使用组合键(Java) 163
12.2 外键映射 172
12.2.1 运行机制 173
12.2.2 使用时机 175
12.2.3 例:单值引用(Java) 176
12.2.4 例:多表查询(Java) 178
12.2.5 例:引用集合(C#) 179
12.3 关联表映射 182
12.3.1 运行机制 182
12.3.2 使用时机 183
12.3.3 例:雇员和技能(C#) 183
12.3.4 例:使用直接的SQL (Java) 186
12.3.5 例:用一次查询查多个 雇员(Java) 189
12.4 依赖映射 193
12.4.1 运行机制 193
12.4.2 使用时机 194
12.4.3 例:唱片和曲目(Java) 195
12.5 嵌入值 197
12.5.1 运行机制 198
12.5.2 使用时机 198
12.5.3 进一步阅读 199
12.5.4 例:简单值对象(Java) 199
12.6 序列化LOB 200
12.6.1 运行机制 201
12.6.2 使用时机 201
12.6.3 例:在XML中序列化一个 部门层级(Java) 202
12.7 单表继承 204
12.7.1 运行机制 205
12.7.2 使用时机 205
12.7.3 例:运动员的单表(C#) 206
12.7.4 从数据库中加载对象 207
12.8 类表继承 210
12.8.1 运行机制 211
12.8.2 使用时机 211
12.8.3 进一步阅读 211
12.8.4 例:运动员和他们的 家属(C#) 212
12.9 具体表继承 216
12.9.1 运行机制 217
12.9.2 使用时机 218
12.9.3 例:具体运动员(C#) 219
12.10 继承映射器 223 ?12.10.1 运行机制 224 ?12.10.2 使用时机 225 第13章 对象-关系元数据映射 ?模式 226
13.1 元数据映射 226
13.1.1 运行机制 226
13.1.2 使用时机 228
13.1.3 例:使用元数据和反射 (Java) 228
13.2 查询对象 234
13.2.1 运行机制 234
13.2.2 使用时机 235
13.2.3 进一步阅读 236
13.2.4 例:简单的查询对象 (Java) 236
13.3 资源库 238
13.3.1 运行机制 239
13.3.2 使用时机 240
13.3.3 进一步阅读 241
13.3.4 例:查找一个人所在的 部门(Java) 241
13.3.5 例:资源库交换策略 (Java) 242 第14章 Web表现模式 243
14.1 模型-视图-控制器 243
14.1.1 运行机制 243
14.1.2 使用时机 245
14.2 页面控制器 245
14.2.1 运行机制 246
14.2.2 使用时机 247
14.2.3 例:Servlet控制器和JSP 视图的简单演示(Java) 247
14.2.4 例:使用JSP充当处理 程序(Java) 249
14.2.5 例:代码隐藏的页面 控制器(C#) 252
14.3 前端控制器 254
14.3.1 运行机制 255
14.3.2 使用时机 256
14.3.3 进一步阅读 257
14.3.4 例:简单的显示(Java) 257
14.4 模板视图 259
14.4.1 运行机制 260
14.4.2 使用时机 263
14.4.3 例:分离的控制器,使用 JSP充当视图(Java) 263
14.4.4 例:ASP.NET服务器 页面(C#) 265
14.5 转换视图 268
14.5.1 运行机制 268
14.5.2 使用时机 269
14.5.3 例:简单的转换(Java) 269
14.6 两步视图 271
14.6.1 运行机制 271
14.6.2 使用时机 272
14.6.3 例:两阶XSLT(XSLT) 276
14.6.4 例:JSP和定制标记 (Java) 278
14.7 应用控制器 282
14.7.1 运行机制 283
14.7.2 使用时机 284
14.7.3 进一步阅读 284
14.7.4 例:状态模型应用控制器 (Java) 284 第15章 分布模式 289
15.1 远程外观 289
15.1.1 运行机制 290
15.1.2 使用时机 292
15.1.3 例:使用Java语言的 会话bean来作为远程 外观(Java) 293
15.1.4 例:Web Service(C#) 295
15.2 数据传输对象 300
15.2.1 运行机制 300
15.2.2 使用时机 303
15.2.3 进一步阅读 304
15.2.4 例:传输唱片信息 (Java) 304
15.2.5 例:使用XML实现序列化 (Java) 308 第16章 离线并发模式 310
16.1 乐观离线锁 310
16.1.1 运行机制 310
16.1.2 使用时机 313
16.1.3 例:领域层与数据映射器 (Java) 314
16.2 悲观离线锁 317
16.2.1 运行机制 318
16.2.2 使用时机 321
16.2.3 例:简单锁管理对象 (Java) 321
16.3 粗粒度锁 326
16.3.1 运行机制 326
16.3.2 使用时机 328
16.3.3 例:共享的乐观离线锁 (Java) 328
16.3.4 例:共享的悲观离线锁 (Java) 333
16.3.5 例:根对象乐观离线锁 (Java) 333
16.4 隐含锁 334
16.4.1 运行机制 335
16.4.2 使用时机 335
16.4.3 例:隐含的悲观离线锁 (Java) 336 第17章 会话状态模式 338
17.1 客户会话状态 338
17.1.1 运行机制 338
17.1.2 使用时机 339
17.2 服务器会话状态 339
17.2.1 运行机制 340
17.2.2 使用时机 341
17.3 数据库会话状态 342
17.3.1 运行机制 342
17.3.2 使用时机 343 第18章 基本模式 344
18.1 入口 344
18.1.1 运行机制 345
18.1.2 使用时机 345
18.1.3 例:私有消息服务的入口 (Java) 346
18.2 映射器 349
18.2.1 运行机制 349
18.2.2 使用时机 350
18.3 层超类型 350
18.3.1 运行机制 350
18.3.2 使用时机 350
18.3.3 例:领域对象(Java) 350
18.4 分离接口 351
18.4.1 运行机制 352
18.4.2 使用时机 352
18.5 注册表 353
18.5.1 运行机制 353
18.5.2 使用时机 355
18.5.3 例:单例注册表(Java) 355
18.5.4 例:线程安全的注册表 (Java) 357
18.6 值对象 357
18.6.1 运行机制 358
18.6.2 使用时机 358
18.7 货币 359
18.7.1 运行机制 359
18.7.2 使用时机 361
18.7.3 例:货币类(Java) 361
18.8 特殊情况 365
18.8.1 运行机制 366
18.8.2 使用时机 366
18.8.3 进一步阅读 366
18.8.4 例:一个简单的空对象 (C#) 366
18.9 插件 367
18.9.1 运行机制 368
18.9.2 使用时机 369
18.9.3 例:ID生成器(Java) 369
18.10 服务桩 371 ?18.10.1 运行机制 372 ?18.10.2 使用时机 372 ?18.10.3 例:销售税服务(Java) 372
18.11 记录集 374 ?18.11.1 运行机制 375 ?18.11.2 使用时机 376 参考文献 377

标签:Java,51,模式,企业应用,详解,使用,运行机制,时机
From: https://blog.csdn.net/m0_63947499/article/details/139436136

相关文章

  • Wgpu图文详解(01)窗口与基本渲染
    写在前面如果对Rust与Wgpu比较关注的同学可能在网络上搜到过@sotrh国外大佬编写的《LearnWgpu》,以及国内大佬@jinleili的优秀翻译作品《学习Wgpu》。这些学习教程质量很高,在我学习Wgpu的过程中给了很大的帮助。那为什么还有我这个系列的文章呢?首先,大佬的系列目前winit使用0.29.......
  • 崖山数据库-监控运维平台-YCM 配置部署详解
    准备工作:操作系统版本:[root@node10~]#uname-aLinuxnode103.10.0-1160.el7.x86_64#1SMPMonOct1916:18:59UTC2020x86_64x86_64x86_64GNU/Linux[root@node10~]#cat/etc/redhat-releaseCentOSLinuxrelease7.9.2009(Core)前提是安装完yashandb数据库:注意:安装......
  • 51单片机学习记录-07-时钟芯片DS1302
    1DS1302介绍DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能RTC(RealTimeClock):实时时钟,是一种集成电路,通常称为时钟芯片2 引脚定义和应用电路3 内部结构框图4......
  • 单片机原理及技术(三)—— AT89S51单片机(二)(C51编程)
    一、AT89S51单片机的并行I/O端口1.1P0口AT89S51的P0口是一个通用的I/O口,可以用于输入和输出。每个引脚都可以通过软件控制为输入或输出模式。1.1.1P0口的工作原理P0口的工作原理是通过对P0寄存器的读写操作来控制P0口的引脚。输出模式:当P0口配置为输出模式时,可以通过对......
  • Midjourney绘画参数设置详解
    在数字艺术和设计领域,Midjourney是一款强大的绘画工具,它允许艺术家和设计师以数字方式创作出精美的图像。为了充分发挥Midjourney的潜力,正确设置其绘画参数至关重要。本文将深入探讨Midjourney的绘画参数设置,帮助用户更好地掌握这一工具。同时,给大家推荐Midjourney中文版绘画......
  • 【数据结构与算法 经典例题】链表的回文结构(图文详解)
                  ......
  • 基于51单片机数控直流数控电源的设计
    电源技术尤其是数控电源技术是一门实践性很强的工程技术,服务于各行各业。当今电源技术融合了电气、电子、系统集成、控制理论、材料等诸多学科领域。直流稳压电源是电子技术常用的仪器设备之一,广泛的应用于教学、科研等领域,是电子实验员、电子设计人员及电路开发部门进行实......
  • 286、基于51单片机的温度报警(8路,DS18B20,热电偶,LCD1602)
    完整资料或定制滴滴我(有偿)见文末。目录一、设计功能二、Proteus仿真三、原理图四、程序源码五、资料包括一、设计功能多路温度采集系统1、刺激4路DS18B20温度和4路热电偶温度2、自动循环显示每路温度值3、设置温度上下限,温度过限报警二、Proteus仿真......
  • 285、基于51单片机的脉宽测量(LCD1602,NE555)
    完整资料或定制滴滴我(有偿)见文末。目录一、设计功能二、Proteus仿真三、原理图四、程序源码五、资料包括一、设计功能脉宽测量仪设计与制作(1)设计并制作一个用于测量脉冲宽度的脉宽测量仪;(2)可测量脉冲宽度范围为lms-ls;(3)在LCD屏上显示脉冲的宽度。二、Pr......
  • 【SVG 生成系列论文(九)】如何通过文本生成 svg logo?IconShop 模型推理代码详解
    SVG生成系列论文(一)和SVG生成系列论文(二)分别介绍了StarVector的大致背景和详细的模型细节。SVG生成系列论文(三)和SVG生成系列论文(四)则分别介绍实验、数据集和数据增强细节。SVG生成系列论文(五)介绍了从光栅图像(如PNG、JPG格式)转换为矢量图形(如SVG、EPS格式)的关......