Ctrl+Z. You've used it a hundred times today. Ever wonder how it actually works? Every action you take — typing a word, deleting a line, changing a font — gets wrapped in a small object. That object knows two things: how to do the action, and how to undo it. Your editor keeps a stack of these objects. Ctrl+Z pops the last one and executes the undo operation. Ctrl+Y pushes it back and calls redo. The editor doesn't remember what you did. The objects do. That's the Command pattern. Instead of calling a function and forgetting about it, you turn the call into an object. Now you can store, queue replay it, or reverse it. Where you've already seen this: → Git commits — a diff that can be applied or reverted → Redux actions — `{ type: 'ADD_ITEM', payload }` dispatched to a store → Database transactions — statements that can be committed or rolled back → Task queues — jobs that sit in a queue until a worker picks them up and executes When NOT to use it: if your actions are simple and never need to be undone, queued, or logged. Wrapping every function call in an object when you'll never look at it again is a ceremony for nothing. #SoftwareEngineering #Programming #DesignPatterns #Architecture
Understanding the Command Pattern in Software Engineering
More Relevant Posts
-
I've finally started a deep dive into C++ templates. It's no news how incredibly powerful templates are; I've just not been able to fully master them. To be fair, templates have a steep learning curve and can certainly become complicated very quickly. On the bright side, the trade-off in flexibility and performance is often worth the effort. If you're asking how complicated it is? There's literally a 2500+ page book on C++ templates alone and several cppcon talks on it. You get the gist. For starters, a template in C++ is essentially a blueprint to tell the compiler how a function or a class should be defined (or created) at compile time. We basically tell the compiler to generate a family of functions or a family of classes during compile-time based on the parameterized type used during instantiation. Templates are similar to generics in other languages, albeit infinitely more powerful, flexible, and elegant than generics. Templates in C++ are a powerful mechanism for meta-programming since we get the compiler to generate code (or programs) based on the program we already wrote. One way I trivialize templates in my head is to assume that the compiler is running a subprogram during compilation. The output of this subprogram is executed as a part of the original program. So when you encounter a template definition in your code, pause and think of it as some process that runs during compilation. A key thing to note about templates: Templates are compiled using a two-phase compilation process: 1st phase: The compiler performs a static analysis of everything independent of the template parameters, static type checking, syntax, and grammar validation, non-templated signature validation, etc. 2nd Phase: The type is instantiated when the templated function or class is invoked. The compiler assesses the validity of the template parameters and the operations on these parameters. ref: https://lnkd.in/eZD-V3kE
To view or add a comment, sign in
-
#𝗕𝘂𝗶𝗹𝗱𝗲𝗿𝗣𝗮𝘁𝘁𝗲𝗿𝗻 Tell me what this code means: new User("Alice", "alice@mail.com", 30, "London", true, false, "PREMIUM") What is the 5th parameter? What is the 6th? Exactly. You have to check the constructor definition just to understand what you wrote. 𝘛𝘩𝘦 𝘗𝘳𝘰𝘣𝘭𝘦𝘮: 𝙃𝙖𝙧𝙙 𝙩𝙤 𝙧𝙚𝙖𝙙: A string of booleans and strings is a riddle, not a feature. 𝙀𝙖𝙨𝙮 𝙩𝙤 𝙢𝙞𝙨𝙪𝙨𝙚: Swapping two compatible types (like two booleans) creates silent bugs. 𝙈𝙖𝙞𝙣𝙩𝙚𝙣𝙖𝙣𝙘𝙚 𝙣𝙞𝙜𝙝𝙩𝙢𝙖𝙧𝙚: Adding a new field requires updating every single instantiation point. Many developers switch to setters to solve this, but that creates new issues. Setters lead to mutable objects that can be modified anywhere in the application, and they allow objects to exist in a "half-baked" state before they are fully initialized. 𝗧𝗵𝗲 𝗕𝘂𝗶𝗹𝗱𝗲𝗿 𝗣𝗮𝘁𝘁𝗲𝗿𝗻 𝗳𝗶𝘅𝗲𝘀 𝗯𝗼𝘁𝗵: Readable code: Each value is preceded by a descriptive method call. Immutable objects: The object is built in a separate step and then locked. Validation: You can enforce required fields and handle optional ones cleanly. 𝗧𝗵𝗲 𝗥𝗲𝗮𝗹 𝗜𝗻𝘀𝗶𝗴𝗵𝘁: The Builder Pattern is not just about cleaner syntax. It is a safety mechanism. It prevents invalid objects from ever reaching your production environment. This is why the Spring Framework uses it everywhere, from ResponseEntity and MockMvc to URI builders. It ensures that complex configurations are both human-readable and structurally sound. Full real-world explanation: [https://lnkd.in/gabG7yPF]
To view or add a comment, sign in
-
You don't need a wrapper component for your wrapper component. I spent all of yesterday debugging a button that wouldn't fire an onClick event. Why? Because the event had to bubble through six layers of 'clean' abstraction. We have 'Button', which wraps 'BaseButton', which wraps 'Touchable', which wraps 'InteractiveElement'. This isn't architecture. This is component abstraction theater. Clean code in a tutorial looks like tiny, single-purpose components. Clean code in production looks like code you can actually read without Cmd+Clicking through 8 files to find the actual HTML tag. Stop optimizing for how neat the import statements look and start optimizing for the poor developer who has to fix a bug at 2 AM. Keep it flat. Keep it readable.
To view or add a comment, sign in
-
GraphCompose v1.1.0 is live. It started as a way to generate PDFs in Java without descending into the usual coordinate-based chaos where one small layout change somehow becomes a personal attack. With v1.1.0, GraphCompose moves further away from low-level PDF drawing and closer to something more useful in real projects: a document layout engine that actually helps you build documents, not just manually suffer through them. What’s new: • compose-first built-in templates • QR codes, barcodes, watermarks, headers/footers, bookmarks, metadata, and page breaks • layout snapshot testing for pagination and geometry regressions • runnable examples for CVs, cover letters, invoices, proposals, and weekly schedules • benchmark and diff tooling • an experimental live preview workflow for faster template iteration The goal is simple: Describe the document structure, and let the engine handle layout, wrapping, pagination, and rendering. That sounds obvious, but anyone who has worked with PDF generation long enough knows it usually is not. Too often, “document generation” really means “draw everything manually and hope page 2 behaves.” This release pushes GraphCompose further toward being a practical platform for real applications, not just a thin wrapper over PDF drawing primitives. Repository: https://lnkd.in/eyJ2DK5b Release: https://lnkd.in/eEASVcVJ Feedback is very welcome. #Java #OpenSource #PDF #DocumentGeneration #SoftwareEngineering
To view or add a comment, sign in
-
-
Difference between var, dynamic, and object in C#? (INTERVIEW) 1) var (compile time) The compiler figures out the type from the value you assign and cannot change the type (compile error) - Cannot be null - Must be initialized when declared -> because compiler needs the value to know what type to use -Not recommended for function calls where return type is unclear -> because the type is not obvious to someone reading the code - Only works for local variables (not class fields) -> because it only works for local variables inside methods Best for: local variables where type is clear 2) dynamic (runtime) The type is resolved at runtime using the DLR (Dynamic Language Runtime) without the compiler checking - Can change type freely - Can be null - No compile-time errors (they become runtime crashes) - No IntelliSense - No type safety When you write int result = dyn + 10? the compiler does not check whether dyn supports the + operator, If dyn is an int at runtime it works but If dyn is a string then the code crashes Best for: COM, scripting languages, JSON without schema Never use in public APIs -> because no type safety 3) object (boxing & unboxing) The universal type of everything in C#, both value types and reference types inherit from object - Can change what it holds - Requires explicit casting to use original type - Cast can fail at runtime - Value types get boxed (performance cost) Creating many objects in a loop causes boxing each time which causes slower performance Best for: when you have no other choice -> old APIs 1. var → type obvious, cannot change 2. dynamic → runtime resolution, dangerous 3. object → need casting, boxing cost #INTERVIEW #var #object #dynamic #CSharp
To view or add a comment, sign in
-
🔷 Abstract class vs Interface in modern C# — when does it actually matter? This is one of those questions that comes up in every code review, yet the answer is rarely nuanced enough. Here's my breakdown 👇 ───────────────────────────── ✅ Choose an Abstract Class when: → You have shared logic to reuse across subclasses (concrete methods, fields, constructors) → You need to maintain shared state — interfaces can't hold backing fields → You want to enforce constructor chaining with base(args) → You're modeling a true "is-a" relationship (Dog IS-A Animal) ───────────────────────────── ✅ Choose an Interface when: → You need multiple contracts — C# has no multiple inheritance, but you can implement many interfaces → You're defining a capability, not an identity (IDisposable, ISerializable, ICloneable) → You want maximum testability — interfaces are far easier to mock → You're building a public API for external implementors ───────────────────────────── 💬 Rule of thumb I always come back to: • Shared code/state → Abstract class • Capability across unrelated types → Interface • Constructor enforcement → Abstract class • Multiple "contracts" → Interface • Public API for external implementors → Interface ───────────────────────────── Which pattern do you reach for first? Drop it in the comments 👇 #csharp #dotnet #softwareengineering #cleancode #programming
To view or add a comment, sign in
-
𝗦𝗧𝗢𝗣 𝗪𝗥𝗜𝗧𝗜𝗡𝗚 𝟮𝟬-𝗣𝗔𝗥𝗔𝗠𝗘𝗧𝗘𝗥 𝗖𝗢𝗡𝗦𝗧𝗥𝗨𝗖𝗧𝗢𝗥𝗦. 🛑 If you’re still building massive constructors just to ensure your objects aren't "hollow" or invalid, you’re stuck in a boilerplate nightmare. It's time to move to modern C#. Let’s talk about a feature that finally fixed the "Incomplete Object" problem: 𝗿𝗲𝗾𝘂𝗶𝗿𝗲𝗱 members. 𝗧𝗛𝗘 𝗣𝗥𝗢𝗕𝗟𝗘𝗠: 𝗧𝗛𝗘 𝗖𝗢𝗡𝗦𝗧𝗥𝗨𝗖𝗧𝗢𝗥 𝗧𝗥𝗔𝗣 In the old days, you had two bad choices: Constructors: Great for safety, but they become a mess of parameters that are hard to read and maintain. Object Initializers: Look beautiful (new User { Name = "K" }), but they don't force the developer to set anything. You end up with NullReferenceExceptions because someone forgot a field. You were choosing between safety and syntax. 𝗧𝗛𝗘 𝗦𝗢𝗟𝗨𝗧𝗜𝗢𝗡: 𝗧𝗛𝗘 𝗿𝗲𝗾𝘂𝗶𝗿𝗲𝗱 𝗞𝗘𝗬𝗪𝗢𝗥𝗗 Introduced in C# 11, the required modifier gives you the best of both worlds. You get the clean look of object initializers with the "iron-clad" safety of a constructor. 𝗧𝗛𝗘 𝗖𝗢𝗗𝗘: public class User { // The compiler will THROW an error if this isn't set during initialization public required string Email { get; init; } public required string Username { get; init; } public DateTime JoinedDate { get; init; } = DateTime.UtcNow; } // ✅ This works perfectly var user1 = new User { Email = "hello@example.com", Username = "DevGuru" }; // ❌ This won't even COMPILE var user2 = new User { Email = "missing_username@example.com" }; 𝗪𝗛𝗬 𝗧𝗛𝗜𝗦 𝗜𝗦 𝗔 𝗪𝗜𝗡: Compile-Time Safety: If a dev adds a new "required" property to a class, every piece of code that creates that object will break immediately—preventing runtime bugs before they happen. Zero Boilerplate: No more mapping 15 parameters from a constructor to private fields. Readability: Object initializers are much easier to scan than a long list of constructor arguments where you can't tell which string is "FirstName" and which is "LastName." 𝗧𝗛𝗜𝗡𝗞𝗜𝗡𝗚 𝗢𝗨𝗧𝗦𝗜𝗗𝗘 𝗧𝗛𝗘 𝗕𝗢𝗫 📦 Combine required with init properties. This creates Immutable, Mandatory Data Structures. You ensure the data is there when created, and you guarantee it can't be changed accidentally later. It’s the ultimate "defensive programming" move. 𝗧𝗛𝗘 𝗧𝗔𝗞𝗘𝗔𝗪𝗔𝗬: Stop doing the manual labor of checking for nulls or writing endless constructor overloads. Use required to let the compiler be your bodyguard. #CSharp #DotNet #CleanCode #ProgrammingTips #SoftwareArchitecture #CodingLife #Innovation
To view or add a comment, sign in
-
Too Many Constructor Dependencies? That’s Not a Spring Problem — That’s a Design Problem** I often hear this: > “Constructor injection becomes confusing when there are too many dependencies… so let’s use @Autowired or field injection.” Let’s pause there. 🚨 The Real Issue If your constructor looks like this: ```java public OrderService( PaymentService paymentService, InventoryService inventoryService, NotificationService notificationService, AuditService auditService, PricingService pricingService, DiscountService discountService ) { ... } ``` 👉 This is NOT an injection problem 👉 This is a **class doing too much** 🧠 What It Actually Means * Violating **Single Responsibility Principle** * High coupling * Hard to test * Hard to maintain * Low readability ❌ Common Misconception “Let’s switch to field injection using @Autowired to make it cleaner” ```java @Autowired private PaymentService paymentService; @Autowired private InventoryService inventoryService; ... ``` 👉 This only **hides the problem**, doesn’t solve it ✅ Better Approach * Break the class into smaller responsibilities * Introduce **facades or domain services** * Group related dependencies into cohesive units Example: ```java public OrderService(OrderProcessingFacade facade) { this.facade = facade; } ``` 🔍 About @Autowired * Not needed for constructor injection (Spring handles it automatically) * Not a solution for ambiguity * If multiple beans exist → use: * `@Qualifier` * `@Primary` 🔥 Engineering Insight > “When constructor injection feels heavy, > it’s your design asking for refactoring.” 🚀 Final Takeaway Don’t switch injection style to fix complexity. Fix the **design**. #SpringBoot #CleanCode #SoftwareArchitecture #Java #BackendEngineering #SystemDesign
To view or add a comment, sign in
-
One design pattern that is very useful when object creation is expensive or repetitive is the 𝙋𝙧𝙤𝙩𝙤𝙩𝙮𝙥𝙚 𝙋𝙖𝙩𝙩𝙚𝙧𝙣. Its idea is simple: 𝒊𝒏𝒔𝒕𝒆𝒂𝒅 𝒐𝒇 𝒄𝒓𝒆𝒂𝒕𝒊𝒏𝒈 𝒂 𝒏𝒆𝒘 𝒐𝒃𝒋𝒆𝒄𝒕 𝒇𝒓𝒐𝒎 𝒔𝒄𝒓𝒂𝒕𝒄𝒉, 𝒚𝒐𝒖 𝒄𝒍𝒐𝒏𝒆 𝒂𝒏 𝒆𝒙𝒊𝒔𝒕𝒊𝒏𝒈 𝒐𝒏𝒆. This is helpful when an object contains many fields, complex configuration, or costly initialization logic. Rather than rebuilding the same structure again and again, you create a prototype once, then duplicate it when needed. Why it is useful: • it improves performance when creation is costly • it reduces repetitive initialization code • it helps create similar objects quickly • it is useful when object setup is complex A simple Java example: imagine a DocumentTemplate object with title, layout, theme, permissions, and metadata already configured. Instead of rebuilding every new document manually, you clone the template and then adjust only what is different. That means: • the prototype keeps the base configuration • the clone copies the existing state • the client modifies only the needed values This is the real value of the 𝙋𝙧𝙤𝙩𝙤𝙩𝙮𝙥𝙚 𝙋𝙖𝙩𝙩𝙚𝙧𝙣: reuse fully configured objects instead of recreating them from zero. It is especially useful in: • document templates • UI components • game objects • configuration-heavy models The 𝙋𝙧𝙤𝙩𝙤𝙩𝙮𝙥𝙚 𝙋𝙖𝙩𝙩𝙚𝙧𝙣 is a good reminder that sometimes the best way to create an object is not to build it, but to copy it intelligently. #Java #DesignPatterns #PrototypePattern #SoftwareEngineering #BackendDevelopment #OOP #CleanCode #Architecture
To view or add a comment, sign in
-
-
GraphCompose v1.4 is live. https://lnkd.in/eyJ2DK5b The last time I properly posted about GraphCompose here, it was v1.1.0. Since then, I did what every developer promises not to do: “I’ll just improve a few things.” A few things later, GraphCompose is no longer just a Java PDF generation project. It has moved much closer to a declarative document layout engine. The idea is simple: Instead of manually fighting PDF coordinates, margins, page breaks, and layout edge cases, you describe the document structure: sections, modules, paragraphs, tables, rows, layers, themes. GraphCompose handles layout, pagination, snapshots, and PDFBox rendering behind the scenes. The new v1.4 line adds: table column spans layer stacks for overlay-style layouts page and section backgrounds fluent rich text DSL reusable BusinessTheme design tokens visual regression scaffolding for generated PDFs stronger documentation and release guardrails Basically, I wanted PDF documents to feel less like drawing on a cave wall with coordinates and more like building UI layouts with components. Still Java. Still PDFBox underneath. But now with a much stronger layout engine on top. This release is a big step for the project: from “generate a PDF” toward “compose a designed document.” Repo: GraphCompose by DemchaAV hashtag #Java #OpenSource #PDFGeneration #SoftwareEngineering #BackendDevelopment #JavaDeveloper #PDFBox
To view or add a comment, sign in
-
Explore related topics
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