Skip to main content

Overview

Batch describes a set of ProductInstances of a specific ProductType that are tracked together, usually for quality control purposes. Package: com.softwarearchetypes.product Source: /product/src/main/java/com/softwarearchetypes/product/Batch.java:21

When to Use

Batch tracking is appropriate when:
  • Individual instance identity is unimportant, but batch origin matters
  • Need to track manufacturing/quality control information
  • Common with foodstuffs, chemicals, and manufactured goods
Examples: Food batches with expiry dates, manufactured parts from same production run

Constructor

private Batch(BatchId id,
              BatchName name,
              ProductType productType,
              Quantity quantityInBatch,
              Instant dateProduced,
              Instant sellBy,
              Instant useBy,
              Instant bestBefore,
              SerialNumber startSerialNumber,
              SerialNumber endSerialNumber,
              String comments)
Use Batch.builder() to create instances.
id
BatchId
required
Unique identifier for this batch
name
BatchName
required
Human-readable batch name
productType
ProductType
required
The ProductType this batch belongs to
quantityInBatch
Quantity
required
Total quantity in this batch. Unit must match ProductType’s preferred unit.
dateProduced
Instant
When the batch was produced (optional)
sellBy
Instant
Sell-by date (optional)
useBy
Instant
Use-by date (optional)
bestBefore
Instant
Best-before date (optional)
startSerialNumber
SerialNumber
Starting serial number in range (optional)
endSerialNumber
SerialNumber
Ending serial number in range (optional)
comments
String
Additional comments about the batch (optional)

Builder Pattern

builder

static Builder builder()
Creates a new builder for constructing Batch instances.
return
Builder
A new Builder instance
Example:
Batch batch = Batch.builder()
    .id(BatchId.random())
    .name(BatchName.of("BATCH-2024-001"))
    .batchOf(productType)
    .quantityInBatch(Quantity.of(1000, Unit.kilograms()))
    .dateProduced(Instant.now())
    .bestBefore(Instant.now().plus(Duration.ofDays(90)))
    .comments("High quality harvest from Farm A")
    .build();

Accessor Methods

id

BatchId id()
Returns the batch identifier.
return
BatchId
The batch identifier

name

BatchName name()
Returns the batch name.
return
BatchName
The batch name

batchOf

ProductIdentifier batchOf()
Returns the ProductType identifier this batch belongs to.
return
ProductIdentifier
The product identifier

quantityInBatch

Quantity quantityInBatch()
Returns the total quantity in this batch.
return
Quantity
The batch quantity

dateProduced

Optional<Instant> dateProduced()
Returns the production date if set.
return
Optional<Instant>
The production date, or empty if not set

sellBy

Optional<Instant> sellBy()
Returns the sell-by date if set.
return
Optional<Instant>
The sell-by date, or empty if not set

useBy

Optional<Instant> useBy()
Returns the use-by date if set.
return
Optional<Instant>
The use-by date, or empty if not set

bestBefore

Optional<Instant> bestBefore()
Returns the best-before date if set.
return
Optional<Instant>
The best-before date, or empty if not set

startSerialNumber

Optional<SerialNumber> startSerialNumber()
Returns the starting serial number if set.
return
Optional<SerialNumber>
The start serial number, or empty if not set

endSerialNumber

Optional<SerialNumber> endSerialNumber()
Returns the ending serial number if set.
return
Optional<SerialNumber>
The end serial number, or empty if not set

comments

Optional<String> comments()
Returns any comments about the batch.
return
Optional<String>
The comments, or empty if not set

Builder Methods

The Builder class provides a fluent interface for constructing Batch instances.

id

Builder id(BatchId id)
Sets the batch ID.
id
BatchId
required
The batch identifier
return
Builder
This builder for chaining

name

Builder name(BatchName name)
Sets the batch name.
name
BatchName
required
The batch name
return
Builder
This builder for chaining

batchOf

Builder batchOf(ProductType productType)
Sets the ProductType this batch belongs to.
productType
ProductType
required
The product type
return
Builder
This builder for chaining

quantityInBatch

Builder quantityInBatch(Quantity quantityInBatch)
Sets the quantity in this batch. The unit must match the ProductType’s preferred unit.
quantityInBatch
Quantity
required
The batch quantity
return
Builder
This builder for chaining

dateProduced

Builder dateProduced(Instant dateProduced)
Sets the production date.
dateProduced
Instant
The production date
return
Builder
This builder for chaining

sellBy

Builder sellBy(Instant sellBy)
Sets the sell-by date.
sellBy
Instant
The sell-by date
return
Builder
This builder for chaining

useBy

Builder useBy(Instant useBy)
Sets the use-by date.
useBy
Instant
The use-by date
return
Builder
This builder for chaining

bestBefore

Builder bestBefore(Instant bestBefore)
Sets the best-before date.
bestBefore
Instant
The best-before date
return
Builder
This builder for chaining

startSerialNumber

Builder startSerialNumber(SerialNumber startSerialNumber)
Sets the starting serial number.
startSerialNumber
SerialNumber
The start serial number
return
Builder
This builder for chaining

endSerialNumber

Builder endSerialNumber(SerialNumber endSerialNumber)
Sets the ending serial number.
endSerialNumber
SerialNumber
The end serial number
return
Builder
This builder for chaining

comments

Builder comments(String comments)
Sets comments about the batch.
comments
String
Additional comments
return
Builder
This builder for chaining

build

Batch build()
Builds the Batch instance.
return
Batch
The constructed Batch
Throws: IllegalArgumentException if:
  • Required fields are missing
  • Quantity unit doesn’t match ProductType’s preferred unit

Validation

The Batch constructor validates that:
  • The quantity unit matches the ProductType’s preferred unit
  • All required fields are provided
This ensures batches can only contain quantities that make sense for the product type. Example:
// Valid: quantity unit matches product's preferred unit
ProductType flour = ProductType.builder()
    .preferredUnit(Unit.kilograms())
    .build();

Batch batch = Batch.builder()
    .batchOf(flour)
    .quantityInBatch(Quantity.of(1000, Unit.kilograms())) // OK
    .build();

// Invalid: would throw IllegalArgumentException
Batch invalid = Batch.builder()
    .batchOf(flour)
    .quantityInBatch(Quantity.of(1000, Unit.liters())) // ERROR
    .build();

Build docs developers (and LLMs) love