Observer Pattern in Java When one object changes and many other objects need to react, you should not call them one by one. You need a clean way to notify all listeners. The Observer Pattern solves this. One object is the source. Many observers subscribe to updates. Simple example interface Observer { void update(String message); } interface Subject { void registerObserver(Observer observer); void notifyObservers(String message); } class NotificationService implements Subject { private List<Observer> observers = new ArrayList<>(); public void registerObserver(Observer observer) { observers.add(observer); } public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } class User implements Observer { private String name; public User(String name) { this.name = name; } public void update(String message) { System.out.println(name + " received: " + message); } } Usage NotificationService service = new NotificationService(); service.registerObserver(new User("Umar")); service.registerObserver(new User("Ali")); service.notifyObservers("New update available"); Key points • Subject sends updates • Observers react • Loose coupling • Easy to extend Where it is used • Event systems • Messaging • UI frameworks Takeaway Observer Pattern builds a clean broadcast system. No direct dependency between sender and receivers. #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
Java Observer Pattern: A Clean Broadcast System
More Relevant Posts
-
Decorator Pattern in Java Sometimes you want to add features to an object. You do not want to modify the original class. You do not want to create many subclasses. The Decorator Pattern solves this. Use it when you want to extend behavior at runtime. Example interface Notifier { void send(String message); } class BasicNotifier implements Notifier { public void send(String message) { System.out.println("Sending notification: " + message); } } class EmailDecorator implements Notifier { private Notifier notifier; public EmailDecorator(Notifier notifier) { this.notifier = notifier; } public void send(String message) { notifier.send(message); System.out.println("Email sent"); } } class SmsDecorator implements Notifier { private Notifier notifier; public SmsDecorator(Notifier notifier) { this.notifier = notifier; } public void send(String message) { notifier.send(message); System.out.println("SMS sent"); } } Use it like this Notifier notifier = new SmsDecorator(new EmailDecorator(new BasicNotifier())); notifier.send("User registered"); Result • Sends base notification • Sends email • Sends SMS Clear benefits • Add features without touching the original class • No subclass explosion • Flexible and simple When to use • When you need optional features • When you want to avoid large inheritance hierarchies Takeaway The Decorator Pattern gives you flexibility. You attach new behavior without breaking existing code. #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
-
Factory Pattern in Java: Creating Objects the Smart Way Let’s be honest. new is one of the most overused keywords in Java. Every time you create an object directly, you tie your code to a specific implementation. The Factory Pattern fixes that. It lets you delegate object creation so your code stays flexible and clean. The idea: Instead of calling constructors everywhere, you ask a “factory” to give you the right object based on your need. Example: interface Shape { void draw(); } class Circle implements Shape { public void draw() { System.out.println("Drawing Circle"); } } class Rectangle implements Shape { public void draw() { System.out.println("Drawing Rectangle"); } } class ShapeFactory { public Shape getShape(String type) { if (type.equalsIgnoreCase("CIRCLE")) return new Circle(); if (type.equalsIgnoreCase("RECTANGLE")) return new Rectangle(); return null; } } How you use it: ShapeFactory factory = new ShapeFactory(); Shape shape = factory.getShape("CIRCLE"); shape.draw(); Why it matters You separate creation from logic. Your code becomes easy to maintain and extend. Adding a new shape? Just create a new class — no need to touch existing logic. Where you’ll see it Spring Beans (IoC container acts like a factory) Database connections Notification or message services The Factory Pattern is your first step toward writing loosely coupled, testable code. It’s simple but forms the foundation of scalable systems. Which factory-like pattern have you seen most in production — Factory, Abstract Factory, or Builder? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
-
Factory Pattern in Java: Creating Objects the Smart Way Let’s be honest. new is one of the most overused keywords in Java. Every time you create an object directly, you tie your code to a specific implementation. The Factory Pattern fixes that. It lets you delegate object creation so your code stays flexible and clean. The idea: Instead of calling constructors everywhere, you ask a “factory” to give you the right object based on your need. Example: interface Shape { void draw(); } class Circle implements Shape { public void draw() { System.out.println("Drawing Circle"); } } class Rectangle implements Shape { public void draw() { System.out.println("Drawing Rectangle"); } } class ShapeFactory { public Shape getShape(String type) { if (type.equalsIgnoreCase("CIRCLE")) return new Circle(); if (type.equalsIgnoreCase("RECTANGLE")) return new Rectangle(); return null; } } How you use it: ShapeFactory factory = new ShapeFactory(); Shape shape = factory.getShape("CIRCLE"); shape.draw(); Why it matters You separate creation from logic. Your code becomes easy to maintain and extend. Adding a new shape? Just create a new class — no need to touch existing logic. Where you’ll see it Spring Beans (IoC container acts like a factory) Database connections Notification or message services The Factory Pattern is your first step toward writing loosely coupled, testable code. It’s simple but forms the foundation of scalable systems. Which factory-like pattern have you seen most in production — Factory, Abstract Factory, or Builder? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
-
Your Java app is using 10GB of RAM. My app is using 1GB. The difference? One "hidden" method. Early in my career, I was on a project processing millions of text records from an external feed. The app would run fine for an hour, then inevitably crash with an OutOfMemoryError. We profiled the heap. It was full of... String objects. The problem? The feed contained millions of duplicate strings. Think "Status: COMPLETED", "Type: SALE", or "Location: USA". Every time our app read "USA", it created a new String object. 1,000,000 "USA" strings = 1,000,000 separate objects on the heap. The "Hidden" Content: String.intern() The fix was a 'magic' method I'd never been taught in school: String.intern(). When you call myString.intern(), the JVM checks a special memory area (the String pool): 1. If "USA" is already in the pool, it returns a reference to that one. 2. If not, it adds "USA" to the pool and returns the new reference. The Fix: A one-line change. // Before String location = record.getLocation(); // After String location = record.getLocation().intern(); The Takeaway (My 8-Year Experience): The result? Our memory usage dropped by 90%. We went from 1,000,000 "USA" objects to just one. After 8 years in development, this is still my favorite "war story." It's a reminder that understanding the JVM is just as important as understanding the Java language. We don't just write code; we manage resources. (Note: intern() has its own performance trade-offs, but in this specific "high-duplicate" scenario, it was a lifesaver!) Do you still use String.intern()? Or have modern GCs and String Deduplication made it obsolete? Let's discuss in the comments! #Java #JVM #PerformanceTuning #SoftwareArchitecture #DevStory #BigData
To view or add a comment, sign in
-
-
💡 The No-Args Constructor When we talk about Java classes, we often focus on methods, encapsulation, or inheritance — but one of the most subtle yet powerful elements is the No-Argument Constructor (also called the default constructor). 🧩 Why is it Important? It ensures that an object can be created without explicitly passing any parameters. Frameworks like Hibernate, Spring, and Jackson rely on it heavily for object instantiation via reflection. If you define any constructor with parameters, Java won’t automatically provide a no-args one — you must define it manually. It’s especially useful in serialization/deserialization, ORM mapping, and dependency injection. Let’s look at an example 👇 class Employee { private String name; private int id; // No-args constructor public Employee() { System.out.println("No-Args Constructor Called"); this.name = "Unknown"; this.id = 0; } // Parameterized constructor public Employee(String name, int id) { this.name = name; this.id = id; } void display() { System.out.println("Employee: " + name + ", ID: " + id); } } public class EmployeeDriver { public static void main(String[] args) { Employee e1 = new Employee(); // uses no-args constructor Employee e2 = new Employee("Rahul", 101); // uses parameterized constructor e1.display(); e2.display(); } } 🧠 Key takeaway: Even if it seems trivial, the no-args constructor is vital for flexibility, framework compatibility, and maintaining clean object-oriented design. Ignoring it can lead to subtle runtime issues — especially when working with frameworks! #Java #Programming #SpringBoot #Hibernate #Developers #CodeBetter #OOP #SoftwareDevelopment #TechLearning
To view or add a comment, sign in
-
Adapter Pattern in Java Problem You have code that works with one type of interface. You get a new class that does similar work but exposes a different method. Your existing code cannot use it directly. Adapter Pattern solves this. It lets you connect two incompatible classes without touching existing code. Example You already have this interface: interface PaymentProcessor { void pay(int amount); } A new payment service arrives but uses a different method: class NewPaymentService { void makePayment(int amount) { System.out.println("Payment processed"); } } Create an adapter that matches your existing interface: class PaymentAdapter implements PaymentProcessor { private NewPaymentService service; public PaymentAdapter(NewPaymentService service) { this.service = service; } public void pay(int amount) { service.makePayment(amount); } } Use it like this: PaymentProcessor processor = new PaymentAdapter(new NewPaymentService()); processor.pay(500); Key points • Adapter converts one interface into another. • It avoids modifying existing working code. • It helps integrate new systems smoothly. When to use • When a new class does not match existing method signatures. • When you integrate legacy code with new APIs. Takeaway The Adapter Pattern protects your codebase. You add new functionality without breaking anything. #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
-
💭 Ever wondered why your Java string operations feel slow sometimes? String vs StringBuilder vs StringBuffer — same syntax, different game. 1️⃣ STRING – Immutable & Simple Once created → it can’t be changed. Every modification creates a new object. Example: String s = "Java"; s = s + " Rocks!"; 👉 Two objects created — one discarded. ✅ Best for fixed text (like constants, messages, config values) ⚠️ Avoid in loops or repeated concatenations — it’s memory heavy 🔍 Why immutable? Thread-safe Used in String Pool for performance Prevents accidental modification 2️⃣ STRINGBUILDER – Mutable & Fast Edits the same object instead of creating new ones. Perfect for building large strings efficiently. Example: StringBuilder sb = new StringBuilder("Hello"); sb.append(" World"); ✅ Fast & memory-efficient ✅ Ideal for loops and dynamic string operations ⚠️ Not thread-safe — avoid in multi-threaded code 3️⃣ STRINGBUFFER – Mutable & Thread-Safe Same as StringBuilder but synchronized. That means only one thread can modify it at a time. Example: StringBuffer sb = new StringBuffer("Sync"); sb.append(" Safe"); ✅ Safe for multi-threaded applications ⚠️ Slower than StringBuilder due to synchronization
To view or add a comment, sign in
-
𝗝𝗮𝘃𝗮 𝟮𝟱: 𝗝𝗮𝘃𝗮 𝗙𝗹𝗶𝗴𝗵𝘁 𝗥𝗲𝗰𝗼𝗿𝗱𝗲𝗿 (𝗝𝗙𝗥) - 𝗝𝗘𝗣 𝟰𝟳𝟯 𝗣𝗿𝗼𝗺𝗲𝘁𝗵𝗲𝘂𝘀 𝗘𝗻𝗱𝗽𝗼𝗶𝗻𝘁 - 𝗣𝗮𝗿𝘁 𝟮 Starting with Java 25, the 𝚓𝚍𝚔.𝚓𝚏𝚛.𝚙𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜 module is part of the official JDK distribution and when you enable the feature with: -𝚇𝚇:+𝙴𝚗𝚊𝚋𝚕𝚎𝙹𝙵𝚁𝙿𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜𝙴𝚡𝚙𝚘𝚛𝚝𝚎𝚛 𝗧𝗵𝗲 𝗝𝗩𝗠: • Starts JFR internally • Creates a small embedded HTTP server running inside the JVM process • Connects this server to the JFR event stream • And exposes everything through a local HTTP endpoint The local server listens on the default port 𝟳𝟬𝟵𝟭: 𝚑𝚝𝚝𝚙://𝚕𝚘𝚌𝚊𝚕𝚑𝚘𝚜𝚝:𝟽𝟶𝟿𝟷/𝚖𝚎𝚝𝚛𝚒𝚌𝚜 🚫 𝗡𝗼 𝗲𝘅𝘁𝗿𝗮 𝗱𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝗶𝗲𝘀 • No Java code needed in your application • No libraries required (𝚒𝚘.𝚖𝚒𝚌𝚛𝚘𝚖𝚎𝚝𝚎𝚛, 𝚓𝚍𝚔.𝚓𝚏𝚛.𝚌𝚘𝚗𝚜𝚞𝚖𝚎𝚛, etc.) • And no sidecar process needed It is entirely internal to the JVM process, implemented in 𝗻𝗮𝘁𝗶𝘃𝗲 𝗖++ 𝗰𝗼𝗱𝗲, running inside the runtime itself. 💡 𝗪𝗵𝗮𝘁 𝘁𝗵𝗲 𝗲𝘅𝗽𝗼𝗿𝘁𝗲𝗿 𝗮𝗰𝘁𝘂𝗮𝗹𝗹𝘆 𝗱𝗼𝗲𝘀 Inside the JVM, the exporter behaves like an 𝗼𝗯𝘀𝗲𝗿𝘃𝗲𝗿 of the JFR event stream, with a very lightweight polling loop: • JFR collects events (such as GC, CPU, Threads, Safepoints, etc.) in a 𝗰𝗶𝗿𝗰𝘂𝗹𝗮𝗿 𝗯𝘂𝗳𝗳𝗲𝗿 • The exporter reads these events periodically • It converts them into 𝗰𝘂𝗺𝘂𝗹𝗮𝘁𝗶𝘃𝗲 𝗺𝗲𝘁𝗿𝗶𝗰𝘀 (in OpenMetrics/Prometheus format) • It publishes them via HTTP — 𝘄𝗶𝘁𝗵𝗼𝘂𝘁 𝘄𝗿𝗶𝘁𝗶𝗻𝗴 𝗮𝗻𝘆𝘁𝗵𝗶𝗻𝗴 𝘁𝗼 𝗱𝗶𝘀𝗸 Metrics are exposed in real time, without any file I/O overhead. ⚙️ 𝗖𝗼𝗻𝘁𝗿𝗼𝗹 𝗮𝗻𝗱 𝗰𝗼𝗻𝗳𝗶𝗴𝘂𝗿𝗮𝘁𝗶𝗼𝗻 Everything is controlled through 𝗝𝗩𝗠 𝗼𝗽𝘁𝗶𝗼𝗻𝘀, for example: 𝚓𝚊𝚟𝚊 \ -𝚇𝚇:𝚂𝚝𝚊𝚛𝚝𝙵𝚕𝚒𝚐𝚑𝚝𝚁𝚎𝚌𝚘𝚛𝚍𝚒𝚗𝚐=𝚗𝚊𝚖𝚎=𝚙𝚛𝚘𝚍, 𝚜𝚎𝚝𝚝𝚒𝚗𝚐𝚜=𝚙𝚛𝚘𝚏𝚒𝚕𝚎, 𝚖𝚊𝚡𝚊𝚐𝚎=𝟸𝚑, 𝚖𝚊𝚡𝚜𝚒𝚣𝚎=𝟻𝟶𝟶𝙼, 𝚍𝚞𝚖𝚙𝚘𝚗𝚎𝚡𝚒𝚝=𝚏𝚊𝚕𝚜𝚎 \ -𝚇𝚇:+𝙴𝚗𝚊𝚋𝚕𝚎𝙹𝙵𝚁𝙿𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜𝙴𝚡𝚙𝚘𝚛𝚝𝚎𝚛 \ -𝙳𝚓𝚍𝚔.𝚓𝚏𝚛.𝚙𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜.𝚙𝚘𝚛𝚝=𝟽𝟶𝟿𝟷 \ -𝙳𝚓𝚍𝚔.𝚓𝚏𝚛.𝚙𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜.𝚙𝚊𝚝𝚑=/𝚖𝚎𝚝𝚛𝚒𝚌𝚜 \ -𝙳𝚓𝚍𝚔.𝚓𝚏𝚛.𝚙𝚛𝚘𝚖𝚎𝚝𝚑𝚎𝚞𝚜.𝚙𝚎𝚛𝚒𝚘𝚍=𝟹𝟶𝚜 ⚡ 𝗖𝗣𝗨 𝗮𝗻𝗱 𝗺𝗲𝗺𝗼𝗿𝘆 𝗼𝘃𝗲𝗿𝗵𝗲𝗮𝗱 Unfortunately, I haven't had the opportunity to test it in production yet, so we don't know the real overhead of this new feature.... But, in practice, you should not need to disable JFR and it’s common to keep it always active and only 𝗮𝗱𝗷𝘂𝘀𝘁 𝘁𝗵𝗲 𝗹𝗲𝘃𝗲𝗹 𝗼𝗳 𝗱𝗲𝘁𝗮𝗶𝗹 when an incident occurs (via 𝚓𝚌𝚖𝚍). #Java #Java25 #JFR #𝗝𝗮𝘃𝗮𝗙𝗹𝗶𝗴𝗵𝘁𝗥𝗲𝗰𝗼𝗿𝗱𝗲𝗿 #Profiling #Performance #Observability
To view or add a comment, sign in
-
Primitives vs Wrappers in Java: A Practical Balance for Performance and API Design 💡 In Java, choosing between primitive types (int, boolean, long) and their wrapper counterparts (Integer, Boolean, Long) isn’t just a speed race—it shapes how you model nullability, API contracts, and data flows. 🚀 Primitives win on performance and memory: fewer objects, no nulls, and straightforward arithmetic. They’re the default for local variables and tight loops. 🧭 Wrappers unlock object‑oriented conveniences: nullability, easy use in generics, and compatibility with reflection or frameworks. But boxing/unboxing and higher memory usage can sneak into hot paths. Key takeaways: - Use primitives in performance‑sensitive code and internal math. - Use wrappers in DTOs, API surfaces, or data stores where nulls or optional values matter. - Prefer primitive streams (IntStream, LongStream) to avoid boxing in data pipelines. - If you need to express absence with primitives, consider OptionalInt/OptionalLong rather than nulls. - When working with large, memory‑sensitive collections, consider primitive‑specific collections from third‑party libraries. - Be mindful of NPEs when a wrapper value is null. Bottom line: balance is design‑driven, not dogmatic. Align your choice with API guarantees and performance budgets. What’s your take? Have you faced a scenario where the primitive vs wrapper choice changed performance or design outcomes? What specific suggestions would you add to improve this post (e.g., with a short code snippet)? #Java #JavaPerformance #PrimitivesVsWrappers #SoftwareEngineering #Programming
To view or add a comment, sign in
-
Prototype Pattern in Java: Cloning Objects the Smart Way Imagine this. You’ve created a heavy object. It takes time to load data, read files, or fetch configurations. Now you need 10 more copies of it. Would you rebuild each one from scratch? Of course not. That’s where the Prototype Pattern comes in. It lets you clone an existing object instead of creating a new one. It saves time and memory when object creation is expensive. Example: class Document implements Cloneable { private String name; private String content; public Document(String name, String content) { this.name = name; this.content = content; } public Document clone() throws CloneNotSupportedException { return (Document) super.clone(); } public String toString() { return name + ": " + content; } } public class Main { public static void main(String[] args) throws Exception { Document doc1 = new Document("Report", "Quarterly sales data"); Document doc2 = doc1.clone(); System.out.println(doc1); System.out.println(doc2); } } Output: Report: Quarterly sales data Report: Quarterly sales data Both objects are identical, but stored separately in memory. Why it matters Saves resources when creating large objects. Helps copy complex states or configurations easily. Works well in frameworks where objects are created in bulk. Where you’ll see it Game development (cloning entities). UI templates. Caching and object pooling systems. Simple rule: When object creation is costly, cloning is your friend. Have you used cloning in any of your projects? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development