* Remove unused member which was also causing a false positive sonar issue. Fixes sonar issue https://sonarcloud.io/project/issues?open=AY3gHwu5DIZTZkppqVEG&id=iluwatar_java-design-patterns * Fixes sonar issue https://sonarcloud.io/project/issues?open=AXK0OzDA-CiGJS70dLki&id=iluwatar_java-design-patterns related to "Refactor the code of the lambda to not have multiple invocations throwing the same checked exception." Also, updated the code to use Instant and Duration to deal with time instead of int. Added the awaitility library to perform assertions in test which is more reliable than using Thread.sleep directly to wait for events to happen. * checkstyle fix * Add sneaky throws to fix sonar lint issue. This is fine as the newFile method is not being tested but instead the new SimpleFileWriter(...) is. * The first booking needs to happen outside the assertions. Fixed other warnings * Use records to pass around related objects instead of using a large number of individual params, which sonar did not like. * Checkstyle fixes * checkstyle fixes * Remove complexity to keep sonar happy. * Split into different methods to reduce complexity. Could be broken down even further but currently Sonar is happy. * Move files to correct package * Add valid assertions to tests * rename constants to avoid confusion * Sonar warning related to cognitive complexity can be suppressed as the methods are quite generic and not functional enough to be separated out. * Use constants to keep Sonar happy * Use correct constant naming conventions * Use correct constant naming conventions * Use lombok to define noargsconstructor * Use a single method to do the logging * Remove unused constructor and redundant method * Use a reusable method for logging
title, category, language, tag
| title | category | language | tag | ||||
|---|---|---|---|---|---|---|---|
| Embedded Value | Behavioral | en |
|
Also known as
- Aggregate Mapping
- Composer
- Inline Value
- Integrated Value
Intent
The Embedded Value design pattern aims to enhance performance and reduce memory overhead by storing frequently accessed immutable data directly within the object that uses it, rather than separately.
Explanation
Real-world example
In a library, the reference desk embeds commonly used resources like dictionaries and encyclopedias directly at the desk for quick and easy access, similar to how the Embedded Value design pattern integrates frequently used data directly within an object for efficiency.
In plain words
Embedded value pattern let's you map an object into several fields of another object’s table.
Programmatic Example
Consider an online ordering example where we have details of item ordered and shipping address. We have Shipping address embedded in Order object. But in database we map shipping address values in Order record instead of creating a separate table for Shipping address and using foreign key to reference the order object.
First, we have POJOs Order and ShippingAddress
public class Order {
private int id;
private String item;
private String orderedBy;
private ShippingAddress ShippingAddress;
public Order(String item, String orderedBy, ShippingAddress ShippingAddress) {
this.item = item;
this.orderedBy = orderedBy;
this.ShippingAddress = ShippingAddress;
}
}
public class ShippingAddress {
private String city;
private String state;
private String pincode;
public ShippingAddress(String city, String state, String pincode) {
this.city = city;
this.state = state;
this.pincode = pincode;
}
}
Now, we have to create only one table for Order along with fields for shipping address attributes.
CREATE TABLE Orders
(
Id INT AUTO_INCREMENT,
item VARCHAR(50) NOT NULL,
orderedBy VARCHAR(50) city VARCHAR (50),
state VARCHAR(50),
pincode CHAR(6) NOT NULL,
PRIMARY KEY (Id)
)
While performing the database queries and inserts, we box and unbox shipping address details.
final String INSERT_ORDER="INSERT INTO Orders (item, orderedBy, city, state, pincode) VALUES (?, ?, ?, ?, ?)";
public boolean insertOrder(Order order)throws Exception{
var insertOrder=new PreparedStatement(INSERT_ORDER);
var address=order.getShippingAddress();
conn.setAutoCommit(false);
insertIntoOrders.setString(1,order.getItem());
insertIntoOrders.setString(2,order.getOrderedBy());
insertIntoOrders.setString(3,address.getCity());
insertIntoOrders.setString(4,address.getState());
insertIntoOrders.setString(5,address.getPincode());
var affectedRows=insertIntoOrders.executeUpdate();
if(affectedRows==1) {
Logger.info("Inserted successfully");
} else {
Logger.info("Couldn't insert "+order);
}
}
Class diagram
Applicability
Use the Embedded value pattern when:
- An application requires high performance and the data involved is immutable.
- Memory footprint reduction is critical, especially in environments with limited resources.
- Objects frequently access a particular piece of immutable data.
Tutorials
Consequences
Benefits:
- Reduces the memory overhead by avoiding separate allocations for immutable data.
- Improves performance by minimizing memory accesses and reducing cache misses.
Trade-offs:
- Increases complexity in object design and can lead to tightly coupled systems.
- Modifying the embedded value necessitates changes across all objects that embed this value, which can complicate maintenance.
Related Patterns
Flyweight: Shares objects to support large quantities using a minimal amount of memory, somewhat similar in intent but different in implementation. Singleton: Ensures a class has only one instance and provides a global point of access to it, can be used to manage a shared embedded value.
