Object‑Oriented Modeling: Concepts, Attributes, Composition, and Code Examples
This article explains the philosophical basis of object‑oriented thinking, distinguishes attributes and operations, compares data‑model and object‑model designs with Java and SQL examples, discusses composition versus aggregation through a digestion model, and illustrates application‑service patterns in account credit scenarios.
Object‑oriented (OO) thinking is presented as a way to understand and abstract the world: an object represents an abstraction of a thing , which consists of events (behaviors) and objects (states).
Attributes and Operations
The core of OO is that an object is composed of attributes (state) and methods (behavior). When designing, one should always consider the combination of both; an object that contains only attributes or only methods is incomplete.
Object Modeling
To illustrate the difference between a data model and an object model, a simple financial Account is used. The data model is expressed as a relational table:
create table account
(
id integer,
balance integer,
status integer
);The corresponding Java class generated from the table (a data model) looks like:
@Getter
@Setter
public class Account {
private int id;
private int balance;
private AccountStatus status;
}When thinking in terms of an object model, the interface defines the full contract:
public interface Account {
int getId();
int getBalance();
AccountStatus getStatus();
void open();
void close();
void credit(int amount);
void debit(int amount);
}A concrete implementation then provides the behavior:
@Getter
@Setter
public class Account {
private int id;
private int balance;
private AccountStatus status;
public void open() { this.status = AccountStatus.OPENED; }
public void close() { this.status = AccountStatus.CLOSED; }
public void credit(int amount) { this.balance += amount; }
public void debit(int amount) { this.balance -= amount; }
}Account Credit
Using the data‑model approach, business logic resides in a service (often called a transaction script):
public class AccountService {
private final AccountRepository accountRepository;
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
public Account creditAccount(int accountId, int amount) {
var account = this.accountRepository.findById(accountId)
.orElseThrow(() -> new AccountException("The Account was not found"));
if (AccountStatus.OPENED != account.getStatus()) {
throw new AccountException("The Account is not open");
}
account.setBalance(account.getBalance() + amount);
return this.accountRepository.save(account);
}
}In an object‑model design the service becomes an application service that merely coordinates calls, leaving the business rules inside the domain object:
public class AccountService {
private final AccountRepository accountRepository;
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
public Account creditAccount(int accountId, int amount) {
var account = this.accountRepository.findById(accountId)
.orElseThrow(() -> new AccountException("The Account was not found"));
account.debit(amount); // business rule inside Account
return this.accountRepository.save(account);
}
}This demonstrates the shift from procedural code to true OO design.
Composition and Aggregation
The article explains the stronger relationship of composition (whole‑depends‑on‑part) versus the weaker aggregation (part can exist independently). A human digestion process is modeled to show composition:
// Mouth
public class Mouth {
public Object chew(Object food) { return food; }
}
// Esophagus
public class Esophagus {
public Object transfer(Object paste) { return paste; }
}
// Stomach
public class Stomach {
public Object fill(Object paste) { return paste; }
}
// Intestine
public class Intestine {
public void absorb(Object chyme) { /* absorbing... */ }
}
public class Person {
private final Mouth mouth;
private final Esophagus esophagus;
private final Stomach stomach;
private final Intestine intestine;
public Person() {
this.mouth = new Mouth();
this.esophagus = new Esophagus();
this.stomach = new Stomach();
this.intestine = new Intestine();
}
public void eat(Object food) {
var paste = this.mouth.chew(food);
paste = this.esophagus.transfer(paste);
var chyme = this.stomach.fill(paste);
this.intestine.absorb(chyme);
// ...
}
}
public class PersonTests {
public static void main(String[] args) {
new Person().eat("chips");
}
}Here Person is the whole, while Mouth , Esophagus , Stomach , and Intestine are parts that are created and destroyed together with the person (composition). By contrast, a car and its tires illustrate aggregation because tires can be replaced independently.
Open‑Source E‑Commerce
The article briefly mentions Mallfoundry , an open‑source multi‑tenant e‑commerce platform built with Spring Boot, employing Domain‑Driven Design (DDD) and OO principles.
Summary
Object modeling emphasizes a mindset that abstracts both attributes and behaviors of things.
Using an account example, the difference between data‑model (tables) and object‑model (interfaces/classes) is clarified.
Composition vs. aggregation is illustrated through a digestion model, highlighting whole‑part relationships.
Application services coordinate workflow while domain objects encapsulate business rules, achieving true OO design.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.