Advance Java ProgrammingUnit 318 min read
JavaBeans & Design Patterns: Components, Properties & Architectural Patterns
Unit 3 of Advanced Java Programming introduces JavaBeans (reusable components with properties, events, and persistence) and design patterns (proven solutions to common software design problems), with hands-on examples, comparisons, and real-world applications in enterprise Java development.
TAKEAWAYS:
- JavaBeans are serializable, reusable components with properties, events, and customizable behavior, enabling modularity in GUI and web apps.
- Properties (bound, constrained, indexed) allow dynamic data binding and validation, while introspection enables runtime reflection.
- Design patterns (Singleton, Factory, Observer, etc.) solve recurring problems like object creation, state management, and loose coupling.
- Patterns like MVC (Model-View-Controller) and Strategy are widely used in frameworks (Spring, Jakarta EE) and apps (eSewa’s transaction handling).
- Persistence in JavaBeans is achieved via serialization or external storage (XML/JSON), critical for saving state in distributed systems.
- Exam focus: Define terms, compare patterns, and explain how JavaBeans integrate with GUI/database systems (e.g., NTC’s ticketing system).
1. JavaBeans: The Building Blocks of Reusable Components
JavaBeans are lightweight, reusable software components that follow specific conventions to enable introspection (runtime inspection of properties/methods) and event handling. They are widely used in GUI development (Swing/JSP), enterprise applications, and configuration systems.
Key Characteristics of JavaBeans
A valid JavaBean must adhere to:
- Public no-arg constructor (for instantiation).
- Properties (getter/setter methods for private fields).
- Serializable (to save/restore state).
- Event support (optional, for listener-based interactions).
classDiagram
class JavaBean {
+String name
+int age
+void setName(String name)
+String getName()
+void setAge(int age)
+int getAge()
}
JavaBean : "1. Public no-arg constructor (omitted but implied)"
JavaBean : "2. Properties with getters/setters"
JavaBean : "3. Serializable (interface, not shown)"
JavaBean : "4. Event support (optional, not depicted)"
note for JavaBean
This diagram omits the no-arg constructor (assumed) and event support (not standard).
Serializable is an interface, not a method.Properties in JavaBeans
Properties define the state of a JavaBean. They are categorized into:
| Type | Definition | Example | Use Case |
|---|---|---|---|
| Bound | Notifies listeners when the value changes (e.g., PropertyChangeListener). |
name property in a UserBean. |
Dynamic UI updates (e.g., eSewa balance display). |
| Constrained | Validates changes before applying (e.g., VetoableChangeListener). |
age must be ≥18. |
Form validation (e.g., Daraz checkout). |
| Indexed | Array-like properties (e.g., getItem(int index)). |
products[] in an InventoryBean. |
Managing collections (e.g., NTC ticket queues). |
Example: A BankAccountBean with Bound Property
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class BankAccountBean {
private double balance;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public double getBalance() {
return balance;
}
public void setBalance(double newBalance) {
double oldBalance = balance;
balance = newBalance;
pcs.firePropertyChange("balance", oldBalance, newBalance);
}
public void addListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
}
Trace: Balance Update with Listener
| Step | Action | State Change | Listener Notification |
|---|---|---|---|
| 1 | account.addListener(listener) |
Listener registered. | — |
| 2 | account.setBalance(1000) |
balance → 1000 |
Fires PropertyChangeEvent with old=0, new=1000. |
Visualization: Bound Property in Action
[Listener] <--> [BankAccountBean]
(onPropertyChange) (fireEvent)
When balance changes, listeners (e.g., a GUI panel) update automatically.
Persistence in JavaBeans
JavaBeans persist state via:
- Serialization (built-in Java mechanism to save/load objects).
- External Storage (XML/JSON for human-readable data).
Example: Serializing a UserBean
import java.io.*;
public class UserBean implements Serializable {
private String username;
private transient String password; // Not serialized
// Getters/setters...
}
public class PersistenceDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
UserBean user = new UserBean();
user.setUsername("admin");
// Serialize
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
oos.writeObject(user);
}
// Deserialize
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
UserBean loadedUser = (UserBean) ois.readObject();
System.out.println("Loaded username: " + loadedUser.getUsername());
}
}
}
Output:
Loaded username: admin
Advantages of JavaBeans
| Advantage | Explanation |
|---|---|
| Reusability | Components can be reused across projects (e.g., PaymentBean in eSewa/Khalti). |
| Introspection | Tools (e.g., IDEs) can inspect properties/methods at runtime. |
| Event-Driven | Supports listener patterns for dynamic interactions. |
| Serialization | State can be saved/loaded easily (e.g., NTC’s user preferences). |
| Loose Coupling | Beans interact via interfaces, not direct dependencies. |
Disadvantages
- Verbose code (boilerplate getters/setters).
- Performance overhead (introspection adds runtime checks).
2. Design Patterns: Solving Recurring Problems
Design patterns are template solutions to common software design challenges. They promote code reuse, maintainability, and scalability. Below are key patterns with real-world ties.
Creational Patterns: Object Instantiation
| Pattern | Problem | Solution | Example in Nepal |
|---|---|---|---|
| Singleton | Ensure only one instance exists. | Private constructor + static instance. | DatabaseConnection (shared across NTC apps). |
| Factory | Delegate instantiation to a factory. | Factory method or abstract factory. | PaymentGatewayFactory (eSewa/Khalti switch). |
| Builder | Construct complex objects step-by-step. | Separate builder class from product. | OrderBuilder in Daraz (customize product options). |
Example: Singleton Pattern (Database Connection)
public class DatabaseConnection {
private static DatabaseConnection instance;
private DatabaseConnection() {} // Private constructor
public static synchronized DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
}
Trace: Thread-Safe Singleton
| Thread 1 | Thread 2 |
|---|---|
getInstance() called |
getInstance() called |
Checks instance == null → true |
Checks instance == null → true |
| Creates new instance | Race condition: Both threads create instances! |
Fix: Use synchronized or double-checked locking:
public static DatabaseConnection getInstance() {
if (instance == null) { // First check (non-synchronized)
synchronized (DatabaseConnection.class) {
if (instance == null) { // Second check (synchronized)
instance = new DatabaseConnection();
}
}
}
return instance;
}
Structural Patterns: Class/Object Composition
| Pattern | Problem | Solution | Example in Nepal |
|---|---|---|---|
| Adapter | Make incompatible interfaces work. | Wrapper class converts interface A to B. | LegacyPaymentGatewayAdapter for old NTC systems. |
| Decorator | Add responsibilities dynamically. | Wrap object in decorator classes. | PremiumUserDecorator in Pathao (extra features). |
| Facade | Simplify complex subsystem access. | Single interface hides complexity. | NTCTicketFacade (hides queue/booking logic). |
Example: Decorator Pattern (Pathao Premium Features)
classDiagram
class Ride {
<<abstract>>
+double calculateCost()
}
class BasicRide {
+calculateCost(): double
}
class PremiumRide {
+Ride ride
+calculateCost(): double
}
PremiumRide : "extends Ride"
PremiumRide --> Ride : "decorates"interface Ride {
double calculateCost();
}
class BasicRide implements Ride {
@Override
public double calculateCost() { return 100; }
}
class PremiumRideDecorator implements Ride {
private final Ride ride;
public PremiumRideDecorator(Ride ride) {
this.ride = ride;
}
@Override
public double calculateCost() {
return ride.calculateCost() * 1.2; // 20% premium
}
}
Trace: Cost Calculation
| Step | Action | Cost Calculation |
|---|---|---|
| 1 | Ride basicRide = new BasicRide() |
basicRide.calculateCost() → 100 |
| 2 | Ride premiumRide = new PremiumRideDecorator(basicRide) |
— |
| 3 | premiumRide.calculateCost() |
100 * 1.2 → 120 |
Behavioral Patterns: Object Interaction
| Pattern | Problem | Solution | Example in Nepal |
|---|---|---|---|
| Observer | Notify multiple objects of changes. | Subject maintains list of observers. | StockPriceObserver (NEPSE updates). |
| Strategy | Swap algorithms at runtime. | Encapsulate algorithms in separate classes. | PaymentStrategy (eSewa/Khalti/Debit Card). |
| MVC | Separate UI, logic, and data. | Model (data), View (UI), Controller (logic). | UserDashboard in NTC’s mobile app. |
Example: Observer Pattern (NEPSE Stock Updates)
interface Observer {
void update(String stockName, double price);
}
class StockMarket {
private List<Observer> observers = new ArrayList<>();
private String stockName;
private double price;
public void addObserver(Observer observer) {
observers.add(observer);
}
public void setPrice(double price) {
this.price = price;
notifyObservers();
}
private void notifyObservers() {
for (Observer observer : observers) {
observer.update(stockName, price);
}
}
}
class StockApp implements Observer {
@Override
public void update(String stockName, double price) {
System.out.println(stockName + ": ₹" + price);
}
}
Trace: NEPSE Update Notification
| Step | Action | Output |
|---|---|---|
| 1 | StockMarket market = new StockMarket(); |
— |
| 2 | market.addObserver(new StockApp()); |
Observer registered. |
| 3 | market.setPrice(150.50); |
NEPSE: ₹150.50 (printed to console). |
3. JavaBeans + Design Patterns: A Real-World Integration
Scenario: NTC’s Ticket Booking System
- JavaBean:
TicketBean(properties:route,price,seatsAvailable). - Design Pattern: Observer (notify users when seats are available).
- Persistence: Serialize
TicketBeanto save booking data.
classDiagram
class TicketBean {
+String route
+double price
+int seatsAvailable
+addObserver(Observer)
+setSeatsAvailable(int)
}
class NTCBookingSystem {
+TicketBean ticket
+Observer user1
+Observer user2
}
NTCBookingSystem --> TicketBean : "contains"
TicketBean --> Observer : "notifies"Code Example: NTC Ticket Observer
class NTCBookingSystem {
private TicketBean ticket = new TicketBean("Kathmandu-Pokhara", 500, 100);
public void addUser(Observer user) {
ticket.addObserver(user);
}
public void bookTicket(int seats) {
int newSeats = ticket.getSeatsAvailable() - seats;
ticket.setSeatsAvailable(newSeats);
}
}
public class Main {
public static void main(String[] args) {
NTCBookingSystem system = new NTCBookingSystem();
system.addUser(new Observer() {
@Override
public void update(String route, int availableSeats) {
System.out.println("Available seats for " + route + ": " + availableSeats);
}
});
system.bookTicket(10); // Notifies observers
}
}
Output:
Available seats for Kathmandu-Pokhara: 90
In the Real World
eSewa/Khalti: Factory Pattern for Payment Gateways
- Idea: The Factory Pattern dynamically selects the payment method (eSewa, Khalti, Credit Card) based on user choice.
- How: A
PaymentGatewayFactorycreates the appropriatePaymentProcessor(e.g.,eSewaProcessororKhaltiProcessor) without exposing instantiation logic. - Example: When a user selects "Pay with eSewa," the factory returns an
eSewaProcessorinstance, which handles the transaction.
Daraz: Observer Pattern for Order Status
- Idea: The Observer Pattern keeps customers updated on their order status (processing, shipped, delivered).
- How: The
Orderclass (subject) maintains a list ofOrderStatusListeners (observers). When the order state changes (e.g., "shipped"), theOrdernotifies all listeners. - Example: A customer’s app receives a push notification: "Your Daraz order #12345 is out for delivery!"
NTC Ticketing System: Singleton + Decorator
- Idea: The Singleton Pattern ensures only one
TicketDatabaseinstance exists (shared across all NTC apps). The Decorator Pattern adds premium features (e.g., priority seating) dynamically. - How: A
BasicTicketis wrapped in aPremiumTicketDecorator, which adds extra charges and priority handling. - Worked Example:
- A user books a Basic Ticket (₹500).
- The system wraps it in a
PremiumDecorator, increasing the price to ₹600 and guaranteeing a seat near the front.
- Idea: The Singleton Pattern ensures only one
Exam Tip: How to Score Full Marks
Define Terms Clearly
- For JavaBeans: Always mention properties, introspection, serialization, and event support.
- For patterns: Name the problem, solution, and real-world analogy (e.g., "Singleton ensures one database connection like NTC’s shared server").
Draw Diagrams for Patterns
- UML Class Diagrams for creational/structural patterns (e.g., Factory, Decorator).
- Sequence Diagrams for behavioral patterns (e.g., Observer, MVC).
- Example:
sequenceDiagram participant User participant NTCApp participant TicketBean participant Observer User->>NTCApp: Book Ticket NTCApp->>TicketBean: setSeatsAvailable(90) TicketBean->>Observer: notify("Kathmandu-Pokhara: 90 seats left")
Compare Patterns in Tables
- Use a comparison table for 2–3 patterns (e.g., Singleton vs. Factory vs. Builder). Highlight:
- When to use each.
- Pros/cons (e.g., Singleton is simple but hard to test; Factory is flexible but complex).
- Use a comparison table for 2–3 patterns (e.g., Singleton vs. Factory vs. Builder). Highlight:
Show Code + Trace
- For JavaBeans: Include a serialization example and trace property changes.
- For patterns: Provide a short code snippet (5–7 lines) and a step-by-step trace table.
Link to Real Scenarios
- Always tie answers to Nepalese apps (eSewa, NTC, Daraz) or global examples (Google Maps uses Singleton for maps; WhatsApp uses Observer for message updates).
- Example answer structure:
"In NTC’s ticketing system, the Observer Pattern is used to notify users when seats become available. The
TicketBeanacts as the subject, while user apps are observers. When seats are booked,TicketBeanfires an event, and observers (e.g., a waiting list app) update dynamically."
Avoid Common Mistakes
- ❌ Forgetting "serializable" in JavaBean definitions.
- ❌ Mixing up bound/constrained properties (bound = notify; constrained = validate).
- ❌ Describing patterns without code (examiners expect pseudocode or Java snippets).
Final Checklist Before Exam
- Can I define JavaBean + list its 4 key traits?
- Can I draw a UML diagram for Singleton/Observer/Decorator?
- Can I write 5 lines of code for a Factory or Observer pattern?
- Can I trace a JavaBean property change with listeners?
- Can I compare 2 design patterns in a table?
- Can I explain how eSewa/Khalti uses Factory or NTC uses Observer?
Based on the TU BCA syllabus for Advance Java Programming (CACS354), unit 3.
Discussion
Loading…