面向对象编程/生命周期管理
对象生命周期管理是指控制配置服务实例数量及其生存期的概念。换句话说,它允许您确定如何缓存返回的实例。
在现实世界中,工厂用于制造东西(例如汽车)。在面向对象编程中,工厂也制造东西;具体来说,面向对象工厂“制造”(实例化)对象。
至少在 Java 中,构造函数无法返回对现有对象的引用——它必须返回一个全新的对象。这会导致两个问题——对象实例太多,以及相同的对象是重复的——不是同一个对象。
工厂通常实现为一个公共静态方法,该方法位于一个只有私有构造函数的类中。这样,只有工厂才能创建“保证[1]”所有对象实例都由工厂创建的实例。
工厂通常有一个内部的“缓存”对象。每当用户向工厂请求一个新对象时,它会先检查缓存,如果缓存中存在相同的对象,则返回缓存中的对象;否则,它会创建一个新的实例,将其添加到缓存并返回。
工厂还可以用于将用户代码注入到“不可修改”的库中。可以保存和恢复实现库对象某些重要功能的用户对象。然后库使用该工厂获取用户对象的实例,甚至不知道用户用全新的代码替换了核心组件。
举个例子…假设库在很多地方使用 Library 对象。库用户可以创建一个类(我们称之为 User),该类扩展了 Library。然后用户调用 LibraryFactory.set(User.class),工厂将其存储起来。在库内部,每当库想要使用 Library 对象时,它都会调用 LibraryFactory.Factory() 函数来获取一个新实例。无需修改任何代码,用户现在就可以通过重写 User 类中的一个或多个方法来完全改变库的功能。
这在 Java SDK 内部用于允许您更改 SDK 部分的工作方式,而无需重写任何代码。
- ↑ 在 Java 中,仅仅拥有私有构造函数并不能真正保证所有对象都来自工厂。序列化和反射仍然可以创建新的实例,而无需经过构造函数。
引用计数是一种编程技术,它存储对资源的引用、指针或句柄的数量,例如对象、内存块、磁盘空间等等。
垃圾回收是指释放堆分配的内存。堆内存最终必须被释放。要么程序员的代码必须显式地释放它,要么需要一些自动系统机制。
最常见的机制是标记清除。这是指系统知道某些顶层类(主要是线程和窗口)。它跟踪从这些“已知”类到所有可达类的所有引用,并标记每个类。完成后,它会“清除”(删除)所有未标记的类。
垃圾回收是面向对象开发的强大推动力——它完全改变了您的设计方式。在使用基于代码的内存管理时,必须有一种方法来跟踪对象。如果它是在堆栈上创建的,那么它将在方法退出时被删除(因此传递到方法外部的实例将变为无效)。如果它是在堆上创建的,则一些对象必须手动删除它——因此,如果您的方法将创建一个对象并将其传递给另外两个都保留该对象的另一个对象,那么您就会遇到问题。谁删除了对象?原始方法不能,因为它将在两个对象完成操作之前退出,而两个对象不应该互相了解。
这类问题通常使用“引用计数”来解决,引用计数是垃圾回收的另一种形式,但它是手动形式。它还会导致创建的长期存在的、自由漫游的类更少,因为它们必须被跟踪。
GC 解决所有权问题。如果您使用的是支持垃圾回收的语言进行编程,您可以在运行时创建类,将它们传递出去,保留副本或忘记它……您实际上不会出错。当所有实例都被“忘记”时,该类就会消失。
缺点是 GC 往往需要大量时间。近年来,情况有所改善,至少 Java 已经拥有了线程化的 GC 以及限制 GC 运行时间的能力。实际上,存在数十种调整和报告选项,以及从多个 GC 系统中选择以满足您的需求的能力。
GC 实现从微不足道的(实例计数)到非常复杂的都有。当前的默认 Java VM 使用多层系统,对新对象、中年对象和老对象使用不同的机制。例如,由于几乎所有新对象都几乎立即死亡,所以第一个部分(伊甸园)被分成两半。当一半满了时,当前引用的对象会被复制到另一边。系统切换到使用“新”边,完全忘记旧边。不会调用任何显式代码来删除已经消失的对象。
这意味着 GC 实际上可能比传统的分配/释放更有效,因为对于几乎所有对象来说,都没有释放操作。
垃圾回收应该被视为面向对象设计的必要条件。
持久化只是使对象在您的程序调用之间“保留”的行为。
这可以很简单(在退出时序列化对象,在加载时将其序列化回来),也可以是完整的面向对象数据库实现。
Hibernate 是一个很好的程序,它位于您的应用程序和数据库之间,确保您的对象被正确持久化。
序列化是将对象转换为字节流的过程,然后可以将其保存到文件或通过网络传输。