給物體加水意味著什麼?
一、簡介
在本教程中,我們將討論程式設計環境中的「水合」一詞,並深入探討「水合」Java 物件的含義。
2. 物體水合
2.1.延遲初始化
物件的延遲載入或延遲初始化是軟體應用程式中使用的常見模式。 Java 中的物件是使用new
關鍵字建立的類別的實例。物件是程式的建構塊,物件與其他物件互動以實現所需的功能。
物件通常意味著在物件導向的程式設計範式中表示現實世界的實體,因此,物件具有多個關聯的屬性。物件初始化是指用真實資料填充物件屬性的過程。這通常是透過呼叫類別建構函數並將資料作為參數傳遞來完成的。初始化也可以從資料來源(例如網路、資料庫或檔案系統)完成。
有時,物件初始化可能是一項資源密集型操作,尤其是當資料從不同的資料來源饋送時。此外,物件並不總是在創建後立即被程式使用。
在這種情況下,最好將物件初始化盡可能推遲到需要的時候。這種模式稱為延遲初始化,因為我們一次使用空資料創建對象,並在將來使用相關資料延遲填充該對象。有意識地延遲資料初始化有助於提高程式碼效能和記憶體利用率。
讓我們建立一個具有幾個屬性的User
類別:
public class User {
private String uId;
private String firstName;
private String lastName;
private String alias;
// constructor, getter-setters
}
我們可以建立一個User
物件並將其保存在記憶體中,而無需用有意義的資料填充其屬性:
User iamUser = new User();
2.2.什麼是保濕?
透過延遲初始化,我們故意延遲已經創建並存在於記憶體中的物件的初始化過程。將資料填入現有空物件的過程稱為水化。
我們建立的 User 實例是一個虛擬實例。該物件沒有任何相關的資料屬性,因為直到此時才需要它。為了使對像有用,我們應該用相關領域資料填充對象,這可以透過用來自網路、資料庫或檔案系統等來源的資料填充來完成。
我們依照以下步驟執行使用者實例的水化。我們首先將水合邏輯編寫為類別級方法,它使用類別設定器來設定相關資料。在我們的範例中,我們將使用我們的資料。但是,我們也可以從文件或類似來源取得資料:
public void generateMyUser() {
this.setAlias("007");
this.setFirstName("James");
this.setLastName("Bond");
this.setuId("JB");
}
現在我們建立一個空的User,
並在需要時透過呼叫generateMyUser()
方法來水合約一實例:
User jamesBond = new User();
// performing hydration
jamesBond.generateMyUser();
我們可以透過斷言其屬性的狀態來驗證水合的結果:
User jamesBond = new User();
Assert.assertNull(jamesBond.getAlias());
jamesBond.generateMyUser();
Assert.assertEquals("007", jamesBond.getAlias());
3. 水化與反序列化
水合和反序列化不是同義詞,我們不應該互換使用它們。反序列化是編程中用於從序列化形式恢復或重新創建物件的過程。我們經常透過網路儲存或傳輸物件。在此過程中,序列化(將物件轉換為位元組流)和反序列化(恢復物件的逆過程)非常有用。
我們可以將User
實例序列化到文件或等效文件中:
try {
FileOutputStream fileOut = new FileOutputStream(outputName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(user);
out.close();
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
同樣,當需要時,我們可以從序列化形式重新建立User
實例:
try {
FileInputStream fileIn = new FileInputStream(serialisedFile);
ObjectInputStream in = new ObjectInputStream(fileIn);
deserializedUser = (User) in.readObject();
in.close();
fileIn.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
很明顯,水合和反序列化都涉及處理對象並用數據填充它。然而,兩者之間的重要區別在於,反序列化主要是創建實例和填充屬性的單步驟過程。
另一方面,水合只涉及將資料添加到預先形成的物件的屬性中。因此,反序列化是在同一步驟中進行物件實例化和物件水化。
4. ORM 框架中的水合
ORM(物件關聯映射)框架是一種軟體開發範例,使我們能夠將物件導向程式設計與關聯式資料庫結合。 ORM 框架促進了應用程式程式碼中的物件與關聯式資料庫中的表之間的映射,並允許開發人員將資料庫實體作為本機物件進行互動。
物件水合的想法在 ORM 框架中更為普遍,例如 Hibernate 或 JPA。
讓我們考慮一個 JPA Entity
類 Book 及其對應的Repository
類,如下所示:
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
// other columns and methods
}
public interface BookRepository extends JpaRepository<Book, Long> {
}
基於 ORM 原則,實體Book
代表關聯式資料庫中的一張表。實體與資料庫的互動以我們上面定義的BookRepository
介面的形式抽象化。該類別的一個實例代表表中的一行。
當我們使用眾多內建find()
方法之一或使用自訂查詢從資料庫載入Book
實例時,ORM 框架會執行以下步驟:
Book aTaleOfTwoCities = bookRepository.findOne(1L);
框架通常透過呼叫類別的預設建構函式來初始化一個空物件。**一旦物件準備就緒,框架就會嘗試從快取儲存中載入屬性資料。**如果此時存在快取未命中,框架將與資料庫建立連線並查詢表以取得行。
一旦獲得 ResultSet,框架就會將上述物件aTaleOfTwoCities
與結果集物件混合在一起,並最終傳回實例。
5. 結論
在本文中,我們討論了程式設計環境中術語「水合」的含義。我們看到了水合與反序列化的差異。最後,我們探討了 ORM 框架和普通物件模型中物件水合的範例。
與往常一樣,本文的程式碼可在 GitHub 上取得。