Best Programming Practices for Clean Code

Explore top LinkedIn content from expert professionals.

  • View profile for Nikki Siapno

    Founder | Eng Manager | ex-Canva | 400k+ audience | Helping you become a great engineer and leader

    205,646 followers

    SOLID principles are key in object-oriented programming. But what does each principle actually mean, and why are they significant? 𝗦𝗢𝗟𝗜𝗗 𝗿𝗲𝗽𝗿𝗲𝘀𝗲𝗻𝘁𝘀 𝗳𝗶𝘃𝗲 𝗽𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲𝘀 𝗼𝗳 𝗼𝗯𝗷𝗲𝗰𝘁-𝗼𝗿𝗶𝗲𝗻𝘁𝗲𝗱 𝗽𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴. Whether or not you use OOP, 𝗸𝗻𝗼𝘄𝗶𝗻𝗴 𝘁𝗵𝗲𝘀𝗲 𝗽𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲𝘀 𝗴𝗶𝘃𝗲𝘀 𝘆𝗼𝘂 𝗮 𝗹𝗲𝗻𝘀 𝗶𝗻𝘁𝗼 𝘁𝗵𝗲 𝗳𝗼𝘂𝗻𝗱𝗮𝘁𝗶𝗼𝗻𝘀 𝗼𝗳 𝗰𝗹𝗲𝗮𝗻 𝗰𝗼𝗱𝗲 which can be applied to many areas of programming. 𝗦 — Single Responsibility Principle 𝗢 — Open/Closed Principle 𝗟 — Liskov Substitution Principle 𝗜 — Interface Segregation Principle 𝗗 — Dependency Inversion Principle Let’s break down each principle ↓ 𝟭. 𝗦𝗶𝗻𝗴𝗹𝗲 𝗥𝗲𝘀𝗽𝗼𝗻𝘀𝗶𝗯𝗶𝗹𝗶𝘁𝘆 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲 (𝗦𝗥𝗣) Each unit of code should only have one job or responsibility. A unit can be a class, module, function, or component. This keeps code modular and removes the risk of tight coupling. 𝟮. 𝗢𝗽𝗲𝗻-𝗖𝗹𝗼𝘀𝗲𝗱 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲 (𝗢𝗖𝗣) Units of code should be open for extension but closed for modification. You should be able to extend functionality with additional code rather than modifying existing ones. This principle can be applied to component-based systems such as a React frontend. 𝟯. 𝗟𝗶𝘀𝗸𝗼𝘃 𝗦𝘂𝗯𝘀𝘁𝗶𝘁𝘂𝘁𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲 (𝗟𝗦𝗣) You should be able to substitute a subclass with its base class. In other words, all functionality in the base class should be utilized by all of its subclasses. If it can’t, it shouldn’t be in the base class. An example of this is with a Bird base class. You might assume that it should have a fly method. But what about the birds that can’t fly? Like a Penguin. In this example, fly should not be in the base class as it does not apply to all subclasses. 𝟰. 𝗜𝗻𝘁𝗲𝗿𝗳𝗮𝗰𝗲 𝗦𝗲𝗴𝗿𝗲𝗴𝗮𝘁𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲 (𝗜𝗦𝗣) Provide multiple interfaces with specific responsibilities rather than a small set of general-purpose interfaces. Clients shouldn’t need to know about the methods & properties that don't relate to their use case. Complexity ↓ Code flexibility ↑ 𝟱. 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝘆 𝗜𝗻𝘃𝗲𝗿𝘀𝗶𝗼𝗻 𝗣𝗿𝗶𝗻𝗰𝗶𝗽𝗹𝗲 (𝗗𝗜𝗣) You should depend on abstractions, not on concrete classes. Use abstractions to decouple dependencies between different parts of the systems. Direct calls between units of code shouldn’t be done, instead interfaces or abstractions should be used. —— Want more engineering insights like this? Subscribe to our 𝗳𝗿𝗲𝗲 𝗻𝗲𝘄𝘀𝗹𝗲𝘁𝘁𝗲𝗿 for a 𝘄𝗲𝗲𝗸𝗹𝘆 𝗱𝗲𝗲𝗽-𝗱𝗶𝘃𝗲 and roundup of our best content: blog.levelupcoding.co #softwareengineering #webdevelopment #programming

  • View profile for Rajya Vardhan Mishra

    Engineering Leader @ Google | Mentored 300+ Software Engineers | Building high-performance teams | Tech Speaker | Led $1B+ programs | Cornell University | Lifelong learner driven by optimism & growth mindset

    107,126 followers

    A few years ago,, I had a junior engineer on my team who struggled so much during his first few months, he was about to be put on PIP and I was 80% sure he would lose his job. Mukesh was fresh out of college, full of energy, and genuinely excited to prove himself. But within just a few sprints, he started struggling. He wasn’t missing work or slacking off, he was putting in extra hours. But his pull requests were almost always late. The code was complex, over-engineered, and incredibly hard to debug. And by the time he’d arrive at a working solution, we were already behind on deadlines. He didn’t have a knowledge problem. He had a sequencing problem. Mukesh was trying to write the perfect, most performant solution from day one, jumping straight to “optimal” without first getting “correct.” So one day, I pulled him aside. I said: “Look, forget everything you know about perfection for a second. Try this instead: ‘Make it work. Make it right. Make it fast.” (this is from Kent Beck, btw, top tier advice) I broke it down for him like this: 1. Make it work – First, solve the problem. Doesn’t matter how messy the code is, just get it working end-to-end. Prove you understand the requirements. 2. Make it right – Now that it works, clean it up. Refactor for readability, structure, maintainability. Make it easy for others to understand. 3. Make it fast – If and only if performance is a blocker, then optimize. But never at the cost of clarity. Next sprint, Mukesh applied that exact approach. The result? On-time delivery. Readable code. Almost no comments in the code review. And for the first time, he ended a sprint feeling confident instead of defeated. It has been sometime, He’s now a senior engineer at Bytedance now, mentors new grads like he once was. I am quite happy at the pace he’s grown. You see, in engineering (and life), progress doesn’t require perfection from the start. Just the discipline to sequence your steps right. That’s what changes everything.

  • View profile for Dr Milan Milanović

    Chief Roadblock Remover and Learning Enabler | Helping 400K+ engineers and leaders grow through better software, teams & careers | Author | Speaker | Leadership & Career Coach

    264,913 followers

    The best engineers I know delete more code than they write Junior engineers add features. Senior engineers remove complexity Every line of code you write is a liability. It needs to be maintained. It can break. It adds cognitive load to anyone who reads it later The best pull requests I've seen in the last year? Half of them deleted more than they added. Someone refactored three classes into one. Someone replaced 200 lines of custom logic with a library function. Someone removed an entire abstraction layer that wasn't pulling its weight Deletion is a skill. You have to know what's safe to remove. You have to understand the system well enough to see what's redundant, over-engineered, or just wrong Next time you open a file, ask: What can I remove? The best code is the code you don't write

  • View profile for Akash Keshri

    Building | MTS @ByteXL | IIITian | Ex- HackerEarth, CodingNinjas, Teknnova | Top Marketing Voice | Top 1% Linkedin | Codeforces Expert

    74,170 followers

    Clean code is nice. But scalable architecture? That’s what makes you irreplaceable. Early in my journey, I thought “writing clean code” was enough… Until systems scaled. Teams grew. Bugs multiplied. That’s when I discovered Design Patterns, and things started making sense. Here’s a simple breakdown that can save you hundreds of hours of confusion. 🔷 Creational Patterns: Master Object Creation These patterns handle how objects are created. Perfect when you want flexibility, reusability, and less tight coupling. 💡 Use these when: You want only one instance (Singleton) You need blueprints to build complex objects step-by-step (Builder) You want to switch object types at runtime (Factory, Abstract Factory) You want to duplicate existing objects efficiently (Prototype) 🔷 Structural Patterns: Organise the Chaos Think of this as the architecture layer. These patterns help you compose and structure code efficiently. 💡 Use these when: You’re bridging mismatched interfaces (Adapter) You want to wrap and enhance existing objects (Decorator) You need to simplify a complex system into one entry point (Facade) You’re building object trees (Composite) You want memory optimization (Flyweight) You want to control access and protection (Proxy, Bridge) 🔷 Behavioural Patterns: Handle Interactions & Responsibilities These deal with how objects interact and share responsibilities. It’s about communication, delegation, and dynamic behavior. 💡 Use these when: You want to notify multiple observers of changes (Observer) You’re navigating through collections (Iterator) You want to encapsulate operations or algorithms (Command, Strategy) You need undo/redo functionality (Memento) You need to manage state transitions (State) You’re passing tasks down a chain (Chain of Responsibility) 📌 Whether you're preparing for interviews or trying to scale your application, understanding these 3 categories is a must: 🔹 Creational → Creating Objects 🔹 Structural → Assembling Objects 🔹 Behavioral → Object Interaction & Responsibilities Mastering these gives you a mental map to write scalable, reusable, and testable code. It’s not about memorising them, it's about knowing when and why to use them. #softwareengineering #systemdesign #linkedintech #sde #connections #networking LinkedIn LinkedIn News India

  • View profile for Brij kishore Pandey
    Brij kishore Pandey Brij kishore Pandey is an Influencer

    AI Architect | AI Engineer | Generative AI | Agentic AI

    693,692 followers

    Clean code isn't just about readability —it's about creating maintainable, scalable solutions that stand the test of time. When we prioritize readability, simplicity, and thoughtful architecture, we're not just making our lives easier; we're creating value for our teams and organizations. A few principles that have made the most significant difference in my work over years: • Meaningful naming that reveals intent • Functions that do one thing exceptionally well • Tests that serve as documentation and safety nets • Consistent formatting that reduces cognitive load The greatest insight I've gained is that clean code is fundamentally an act of communication—with future developers, our teammates, and even our future selves. The time invested upfront pays dividends during maintenance, debugging, and onboarding. What clean code practices have transformed your development experience? I'd love to hear about the principles that guide your work. Image Credit - Keivan Damirchi

  • View profile for Milan Jovanović
    Milan Jovanović Milan Jovanović is an Influencer

    Practical .NET and Software Architecture Tips | Microsoft MVP

    263,168 followers

    I've been using Clean Architecture for 6+ years. Here’s why I think it’s amazing. 👇 The biggest pain in enterprise systems? A lack of structure. Every project reinvents the wheel. Every team builds layers differently. And knowledge doesn’t transfer between systems. But there’s a proven way to fix this. It’s called Clean Architecture. It’s not about how many projects you create. It’s not about fancy patterns. ✅ It’s about the direction of dependencies. Inner layers (domain, app) define abstractions. Outer layers (infra, presentation) implement those abstractions. Never the other way around. That’s it. That’s the rule. You can package this as: - Layers (domain, app, infra, web) - Vertical slices (grouped per feature) - Components (layers + vertical slices) They all work — if you follow the rule. What are the benefits? - Modular code - Clear separation of concerns - Easy-to-test business logic - Faster onboarding - Loosely coupled components Clean Architecture has helped me ship excellent products. And I’ll keep using it because it works. Want to simplify your development process? Grab my free Clean Architecture template here: https://lnkd.in/eDgfyWKB

  • View profile for Alexandre Zajac

    SDE & AI @Amazon | Building Hungry Minds to 1M+ | Daily Posts on Software Engineering, System Design, and AI ⚡

    146,888 followers

    The 10 Rules NASA Swears By to Write Bulletproof Code: 0. Restrict to simple control flow ↳ No goto, setjmp, longjmp, or recursion. Keep it linear and predictable. This ensures your code is easily verifiable and avoids infinite loops or unpredictable behavior. 1. Fixed loop bounds ↳ Every loop must have a statically provable upper bound. No infinite loops unless explicitly required (e.g., schedulers). This prevents runaway code and ensures bounded execution. 2. No dynamic memory allocation after initilization ↳ Say goodbye to malloc and free. Use pre-allocated memory only. This eliminates memory leaks, fragmentation, and unpredictable behavior. 3. Keep functions short ↳ No function should exceed 60 lines. Each function should be a single, logical unit that’s easy to understand and verify. 4. Assertion density: 2 per function ↳ Use assertions to catch anomalous conditions. They must be side-effect-free and trigger explicit recovery actions. This is your safety net for unexpected errors. 5. Declare data at the smallest scope ↳ Minimize variable scope to prevent misuse and simplify debugging. This enforces data hiding and reduces the risk of corruption. 6. Check all function returns and parameters ↳ Never ignore return values or skip parameter validation. This ensures error propagation and prevents silent failures. 7. Limit the preprocessor ↳ Use the preprocessor only for includes and simple macros. Avoid token pasting, recursion, and excessive conditional compilation. Keep your code clear and analyzable. 8. Restrict pointer use ↳ No more than one level of dereferencing. No function pointers. This reduces complexity and makes your code easier to analyze. 9. Compile with all warnings enabled ↳ Your code must be compiled with zero warnings in the most pedantic settings. Use static analyzers daily to catch issues early. Some of these rules can be seen as hard to follow, but you can't allow room for error when lives are at stake. Which ones are you still applying? #softwareengineering #systemdesign ~~~ 👉🏻 Join 46,001+ software engineers getting curated system design deep dives, trends, and tools (it's free): ➔ https://lnkd.in/dCuS8YAt ~~~ If you found this valuable: 👨🏼💻 Follow Alexandre Zajac 🔖 Bookmark this post for later ♻️ Repost to help someone in your network

  • View profile for Allen Holub

    I help you build software better & build better software.

    32,255 followers

    Last night, I was chatting in the hotel bar with a bunch of conference speakers at Goto-CPH about how evil PR-driven code reviews are (we were all in agreement), and Martin Fowler brought up an interesting point. The best time to review your code is when you use it. That is, continuous review is better than what amounts to a waterfall review phase. For one thing, the reviewer has a vested interest in assuring that the code they're about to use is high quality. Furthermore, you are reviewing the code in a real-world context, not in isolation, so you are better able to see if the code is suitable for its intended purpose. Continuous review, of course, also leads to a culture of continuous refactoring. You review everything you look at, and when you find issues, you fix them. My experience is that PR-driven reviews rarely find real bugs. They don't improve quality in ways that matter. They DO create bottlenecks, dependencies, and context-swap overhead, however, and all that pushes out delivery time and increases the cost of development with no balancing benefit. I will grant that two or more sets of eyes on the code leads to better code, but in my experience, the best time to do that is when the code is being written, not after the fact. Work in a pair, or better yet, a mob/ensemble. One of the teams at Hunter Industries, which mob/ensemble programs 100% of the time on 100% of the code, went a year and a half with no bugs reported against their code, with zero productivity hit. (Quite the contrary—they work very fast.) Bugs are so rare across all the teams, in fact, that they don't bother to track them. When a bug comes up, they fix it. Right then and there. If you're working in a regulatory environment, the Driver signs the code, and then any Navigator can sign off on the review, all as part of the commit/push process, so that's a non-issue. There's also a myth that it's best if the reviewer is not familiar with the code. I *really* don't buy that. An isolated reviewer doesn't understand the context. They don't know why design decisions were made. They have to waste a vast amount of time coming up to speed. They are also often not in a position to know whether the code will actually work. Consequently, they usually focus on trivia like formatting. That benefits nobody.

  • View profile for Chandrasekar Srinivasan

    Engineering and AI Leader at Microsoft

    46,395 followers

    About five years ago, I had a junior engineer on my team who was brilliant but struggled so much he was about to have a low performance review. Let’s call him Anthony He was fresh out of college and eager to prove himself, but his code reviews often came back with extensive feedback. The root of the issue wasn’t his intelligence or effort it was his approach. Anthony had this habit of jumping straight into the deep end. He wanted his code to be optimized, elegant, and perfect from day one. But in that pursuit, he often got stuck either over-engineering a solution or ending up with something too complex to debug. Deadlines were slipping, and his confidence was taking a hit. One day, during a particularly rough code review, I pulled him aside and shared a principle that had profoundly shaped my own career: “Make it work, make it right, make it fast.” I explained it like this: 1. Make it work – First, solve the problem. Forget about how pretty or efficient your code is. Focus on meeting the acceptance criteria. If it doesn’t work, nothing else matters. 2. Make it right – Once it works, step back. Refactor the code, and make it clean, modular, and maintainable. Code is for humans who’ll work with it in the future. 3. Make it fast – Finally, if performance is critical, optimize. But don’t sacrifice clarity or maintainability for marginal speed gains. The next sprint, he followed this approach on a tricky API integration task. When we reviewed his work, the difference was night and day. Not only had he delivered on time, but the code was a joy to read. Even he admitted it was the least stressful sprint he’d had in months. Six months later, Anthony came to me and said, “That principle you shared, it’s changed everything. Thank you for pulling me aside that day.” Today, Anthony is a senior engineer leading his team, mentoring others, and applying the same principle that once helped him. We’re still on good terms though he moved to another org. Sometimes, the most impactful advice is the simplest. As engineers, we often get caught up in trying to do everything perfectly all at once But stepping back and breaking it into manageable steps can make all the difference.

  • View profile for Olinya C Paul

    MERN Stack Developer | Frontend Developer | ReactJS | Next.js | TypeScript | JavaScript | AI Automation Expert with N8N | FlutterFlow Developer

    4,776 followers

    Why Some Developers Stay “Junior” Forever (And How to Break Out Fast) I’ve seen it happen too many times. A dev starts strong—learning, coding, shipping projects… But 2 years later? Still stuck at “junior.” Here’s the truth most won’t tell you: You can write code every day and still not grow. Let me break it down: --- ⚠️ You Copy But Don’t Create Watching 100 tutorials doesn’t mean you’ve learned. You grow by struggling to build something on your own. No roadmap. No step-by-step guide. Just you vs the problem. --- ⏳ You Wait for Someone to Lead You Waiting to be told what to build, what to fix, or what to learn… That’s a ceiling you’re placing on your growth. Real growth begins the moment you say: “I’ll figure it out.” --- ❌ You Skip the Fundamentals It’s cool to use React or Tailwind— But can you explain event bubbling? Can you debug async issues? If you don’t know the “why” behind the tools, you’ll always feel lost. --- 📦 You Think Coding Alone Is Enough Guess what? Top-tier developers also think about UX, system design, APIs, testing, and performance. They see the whole picture. You can’t afford to stay in your little corner of the codebase. --- 🎯 You Avoid Feedback You’re not asking for code reviews. You’re not learning from people better than you. And you’re not reflecting on your mistakes. That’s a trap. Growth without feedback is just repetition. --- I used to be there too. I thought more hours meant more experience. But what I needed was intentional effort + clarity + hard truth. --- If you’re a junior dev reading this… You can move fast. Faster than you think. But you’ve got to stop being “busy” and start being brutally focused. Break things. Ask dumb questions. Think in systems. That’s how you rise. --- Tag someone who needs this wake-up call. #SoftwareEngineering #JuniorDeveloper #DevMindset #FrontendDev #LevelUp #CareerGrowth

Explore categories