Posts Tagged ‘CleanCode’
[PHPForumParis2023] Open/Closed Principle: Extend, Don’t Extends! – Thomas Dutrion
Thomas Dutrion, CTO and a passionate advocate for clean code, presented an engaging session at Forum PHP 2023 on the Open/Closed Principle, a cornerstone of the SOLID principles. With a playful nod to avoiding PHP’s extends keyword, Thomas clarified how to design extensible systems without relying on inheritance. His talk, infused with practical examples and a call for team collaboration, offered PHP developers a clear framework for building flexible, maintainable codebases.
Demystifying the Open/Closed Principle
Thomas began by explaining the Open/Closed Principle, which states that software entities should be open for extension but closed for modification. He emphasized that this principle enables developers to add new functionality without altering existing code, reducing the risk of introducing bugs. Using relatable analogies, Thomas distinguished between “extending” a system’s behavior through design patterns and the pitfalls of using PHP’s extends for inheritance, which can lead to rigid, tightly coupled code.
Practical Techniques for Extension
Delving into implementation, Thomas showcased techniques like decorators and callbacks to achieve extensibility. He provided examples of middleware patterns, such as those defined in PSR-15, where request handlers are passed through a stack of processes, allowing behavior to be extended dynamically. Thomas cautioned against overly complex callback chains, advocating for clear, team-aligned designs. His demonstrations highlighted how these patterns maintain code stability while allowing for seamless enhancements.
Team Collaboration and Clarity
Concluding his talk, Thomas stressed the importance of team agreement when applying the Open/Closed Principle. He noted that patterns like decorators often rely on dependency injection, which can obscure implementation details unless well-documented. By advocating for clear communication and tools like event dispatchers, Thomas inspired developers to work collaboratively, ensuring extensible designs are both effective and understandable within their teams.
[PyConUS 2023] Fixing Legacy Code, One Pull Request at a Time
At PyCon US 2023, Guillaume Dequenne from Sonar presented a compelling workshop on modernizing legacy codebases through incremental improvements. Sponsored by Sonar, this session focused on integrating code quality tools into development workflows to enhance maintainability and sustainability, using a Flask application as a practical example. Guillaume’s approach, dubbed “Clean as You Code,” offers a scalable strategy for tackling technical debt without overwhelming developers.
The Legacy Code Conundrum
Legacy codebases often pose significant challenges, accumulating technical debt that hinders development efficiency and developer morale. Guillaume illustrated this with a vivid metaphor: analyzing a legacy project for the first time can feel like drowning in a sea of issues. Traditional approaches to fixing all issues at once are unscalable, risking functional regressions and requiring substantial resources. Instead, Sonar advocates for a pragmatic methodology that focuses on ensuring new code adheres to high-quality standards, gradually reducing technical debt over time.
Clean as You Code Methodology
The “Clean as You Code” approach hinges on two principles: ownership of new code and incremental improvement. Guillaume explained that developers naturally understand and take responsibility for code they write today, making it easier to enforce quality standards. By ensuring that each pull request introduces clean code, teams can progressively refurbish their codebase. Over time, as new code replaces outdated sections, the overall quality improves without requiring a massive upfront investment. This method aligns with continuous integration and delivery (CI/CD) practices, allowing teams to maintain high standards while delivering features systematically.
Leveraging SonarCloud for Quality Assurance
Guillaume demonstrated the practical application of this methodology using SonarCloud, a cloud-based static analysis tool. By integrating SonarCloud into a Flask application’s CI/CD pipeline, developers can automatically analyze pull requests for issues like bugs, security vulnerabilities, and code smells. He showcased how SonarCloud’s quality gates enforce standards on new code, ensuring that only clean contributions are merged. For instance, Guillaume highlighted a detected SQL injection vulnerability due to unsanitized user input, emphasizing the tool’s ability to provide contextual data flow analysis to pinpoint and resolve issues efficiently.
Enhancing Developer Workflow with SonarLint
To catch issues early, Guillaume introduced SonarLint, an IDE extension for PyCharm and VSCode that performs real-time static analysis. This tool allows developers to address issues before committing code, streamlining the review process. He demonstrated how SonarLint highlights issues like unraised exceptions and offers quick fixes, enhancing productivity. Additionally, the connected mode between SonarLint and SonarCloud synchronizes issue statuses, ensuring consistency across development and review stages. This integration empowers developers to maintain high-quality code from the outset, reducing the burden of post-commit fixes.
Sustaining Codebase Health
The workshop underscored the long-term benefits of the “Clean as You Code” approach, illustrated by a real-world project where issue counts decreased over time as new rules were introduced. By focusing on new code and leveraging tools like SonarCloud and SonarLint, teams can achieve sustainable codebases that are maintainable, reliable, and secure. Guillaume’s presentation offered a roadmap for developers to modernize legacy systems incrementally, fostering a culture of continuous improvement.
Links:
Hashtags: #LegacyCode #CleanCode #StaticAnalysis #SonarCloud #SonarLint #Python #Flask #GuillaumeDequenne #PyConUS2023
[DevoxxFR2013] Clean JavaScript? Challenge Accepted: Strategies for Maintainable Large-Scale Applications
Lecturer
Romain Linsolas is a Java developer with over two decades of experience, passionate about technical innovation. He has worked at the CNRS on an astrophysics project, as a consultant at Valtech, and as a technical leader at Société Générale. Romain is actively involved in the developpez.com community as a writer and moderator, and he focuses on continuous integration principles to automate and improve team processes. Julien Jakubowski is a consultant and lead developer at OCTO Technology, with a decade of experience helping teams deliver high-quality software efficiently. He co-founded the Ch’ti JUG in Lille and has organized the Agile Tour Lille for two years.
Abstract
This article analyzes Romain Linsolas and Julien Jakubowski’s exploration of evolving JavaScript from rudimentary scripting to robust, large-scale application development. By dissecting historical pitfalls and modern solutions, the discussion evaluates architectural patterns, testing frameworks, and automation tools that enable clean, maintainable code. Contextualized within the shift from server-heavy Java applications to client-side dynamism, the analysis assesses methodologies for avoiding common errors, implications for developer productivity, and challenges in integrating diverse ecosystems. Through practical examples, it illustrates how JavaScript can support complex projects without compromising quality.
Historical Pitfalls and the Evolution of JavaScript Practices
JavaScript’s journey from a supplementary tool in the early 2000s to a cornerstone of modern web applications reflects broader shifts in user expectations and technology. Initially, developers like Romain and Julien used JavaScript for minor enhancements, such as form validations or visual effects, within predominantly Java-based server-side architectures. A typical 2003 example involved inline scripts to check input fields, turning them red on errors and preventing form submission. However, this approach harbored flaws: global namespace pollution from duplicated function names across files, implicit type coercions leading to unexpected concatenations instead of additions (e.g., “100” + 0.19 yielding “1000.19”), and public access to supposedly private variables, breaking encapsulation.
These issues stem from JavaScript’s design quirks, often labeled “dirty” due to surprising behaviors like empty array additions resulting in strings or NaN (Not a Number). Romain’s demonstrations, inspired by Gary Bernhardt’s critiques, highlight arithmetic anomalies where [] + {} equals “[object Object]” but {} + [] yields 0. Such inconsistencies, while entertaining, pose real risks in production code, as seen in scope leakage where loop variables overwrite each other, printing values only 10 times instead of 100.
The proliferation of JavaScript-driven applications, fueled by innovations from Gmail and Google Docs, necessitated more code—potentially 100,000 lines—demanding structured approaches. Early reliance on frameworks like Struts for server logic gave way to client-side demands for offline functionality and instant responsiveness, compelling developers to confront JavaScript’s limitations head-on.
Architectural Patterns for Scalable Code
To tame JavaScript’s chaos, modular architectures inspired by Model-View-Controller (MVC) patterns emerge as key. Frameworks like Backbone.js, AngularJS, and Ember.js facilitate separation of concerns: models handle data, views manage UI, and controllers orchestrate logic. For instance, in a beer store application, an MVC setup might use Backbone to define a Beer model with validation, a BeerView for rendering, and a controller to handle additions.
Modularization via patterns like the Module Pattern encapsulates code, preventing global pollution. A counter example encapsulates a private variable:
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
value: function() {
return privateCounter;
}
};
})();
This ensures privacy, unlike direct access in naive implementations. Advanced libraries like RequireJS implement Asynchronous Module Definition (AMD), loading dependencies on demand to avoid conflicts.
Expressivity is boosted by frameworks like CoffeeScript, which compiles to JavaScript with cleaner syntax, or Underscore.js for functional utilities. Julien’s analogy to appreciating pungent cheese after initial aversion captures the learning curve: mastering these tools reveals JavaScript’s elegance.
Testing and Automation for Reliability
Unit testing, absent in early practices, is now feasible with frameworks like Jasmine, adopting Behavior-Driven Development (BDD). Specs describe behaviors clearly:
describe("Beer addition", function() {
it("should add a beer with valid name", function() {
var beer = new Beer({name: "IPA"});
expect(beer.isValid()).toBe(true);
});
});
Tools like Karma run tests in real browsers, while Istanbul measures coverage. Automation integrates via Maven, Jenkins, or SonarQube, mirroring Java workflows. Violations from JSLint or compilation errors from Google Closure Compiler are flagged, ensuring syntax integrity.
Yeoman, combining Yo (scaffolding), Grunt (task running), and Bower (dependency management), streamlines setup. IDEs like IntelliJ or WebStorm provide seamless support, with Chrome DevTools for debugging.
Ongoing Challenges and Future Implications
Despite advancements, integration remains complex: combining MVC frameworks with testing suites requires careful orchestration, often involving custom recipes. Perennial concerns include framework longevity—Angular vs. Backbone—and team upskilling, demanding substantial training investments.
The implications are profound: clean JavaScript enables scalable, responsive applications, bridging Java developers into full-stack roles. By avoiding pitfalls through patterns and tools, projects achieve maintainability, reducing long-term costs. However, the ecosystem’s youth demands vigilance, as rapid evolutions could obsolete choices.
In conclusion, JavaScript’s transformation empowers developers to tackle ambitious projects confidently, blending familiarity with innovation for superior outcomes.