Lucas Liu's Technical Blog
website·Indexed 30 days ago
https://lucasliu-blog.netlify.appA collection of technical articles and tutorials covering frontend development (Vue, Vite, CSS), programming principles (SOLID, Object-Oriented Programming), Git workflows, Linux system administration, and source code analysis of libraries like Axios and Vue2.
What's inside Lucas Liu Blog
- NJS is a specialized NGINX module that provides a JavaScript scripting framework. It uses a custom-built JavaScript interpreter designed specifically for the NGINX runtime to allow developers to implement complex logic within NGINX configurations without the overhead of a full JS engine like V8 or SpiderMonkey.
Overview of create-vite execution flow and dependencies
The
create-viteCLI follows a four-step main process: 1. Collect user input (CLI flags or interactive prompts), 2. Check for existing directories and handle overrides, 3. Read and write template files based on the selected framework/variant, 4. Prompt the user to enter the directory and install dependencies.Key dependencies used:
spawn: For executing system commands.minimist: For parsing command-line arguments.prompts: For creating interactive CLI prompts.kolorist: For adding colors to terminal output.
Understand the Liskov Substitution Principle (LSP)
The Liskov Substitution Principle (LSP) states that objects of a superclass should be replaceable with objects of its subclasses without breaking the application or changing the program's original logical behavior and correctness.
While similar to polymorphism, they differ in focus: polymorphism is a language feature/implementation mechanism, whereas LSP is a design principle guiding how inheritance relationships should be structured to ensure behavioral consistency.
Understand Rich Domain Models in DDD
A Rich Domain Model (central to Domain-Driven Design or DDD) encapsulates both data and the corresponding business logic within the same class (the Domain object). This adheres to object-oriented encapsulation. In this architecture, the Service layer becomes 'thin,' acting primarily as an orchestrator, while the Domain layer is 'rich' and handles the core business rules.Understand Anemic Domain Models in traditional development
An Anemic Domain Model is a design pattern where data structures (such as BOs, Entities, or VOs) contain only data and no business logic. In this approach, business logic is centralized in a separate Service layer. This separates data from the operations that act upon it, resulting in a procedural programming style that breaks the object-oriented principle of encapsulation.// Anemic Model: Data is separated from logic public class UserBo { private Long id; private String name; private String cellphone; // Only getters/setters, no business logic } public class UserService { public void updateUserName(Long userId, String newName) { UserBo user = userRepository.findById(userId); user.setName(newName); // Logic resides in the service userRepository.save(user); } }Apply the Law of Demeter (LOD) to reduce class coupling
The Law of Demeter (LOD), or the Least Knowledge Principle, states that a module should have limited knowledge about other modules and only interact with those closely related to it ("talk to friends, not strangers").
Key implementation goals:
- Avoid dependencies between classes that should not have a direct relationship.
- When a dependency is necessary, rely only on the minimum required interfaces.
- Increase class independence so that changes in one part of the system minimize the number of other classes that must be updated.
Compare Procedural Programming and Object-Oriented Programming
Procedural Programming (PP) organizes code around processes or methods as the basic unit, characterized by the separation of data and methods. In contrast, Object-Oriented Programming (OOP) uses classes as the basic unit and integrates data and behavior. PP languages typically lack advanced OOP features such as inheritance, polymorphism, and encapsulation. OOP is generally better suited for large-scale, complex programs with non-linear execution flows and offers higher extensibility and maintainability.Benefits of Monorepo for Vue Component Libraries
A Monorepo structure is recommended for complex projects like component libraries to avoid the overhead of MultiRepo management. It allows splitting the project into logical sub-packages (e.g.,
componentsfor core logic,sharedfor utilities,themefor styling,docsfor documentation, andclifor scaffolding) while providing the following advantages:- Rapid Code Sharing: Modules can reuse code without manual installation of dependencies across different projects.
- Immediate Feedback: Changes in one module (e.g.,
shared) are immediately reflected in dependent modules (e.g.,componentsordocs) without requiring a publish-and-update cycle. - Configuration Reuse: Shared configurations (like
.babelrcorvite.config.js) and CI scripts can be reused across all packages. - Centralized Management: Package versions and inter-dependencies are managed in one place.
Understand Abstraction in OOP
Abstraction focuses on hiding the specific implementation details of a method, allowing the user to focus on what the method does rather than how it does it. This is typically achieved using interface classes or abstract classes. Abstraction improves extensibility and maintainability because implementation changes do not require changes to the definition, and it helps manage complex systems by filtering out irrelevant details.Understand the fundamentals of Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is a programming paradigm that uses classes and objects as the basic units for organizing code. It is built upon four primary pillars: Encapsulation, Abstraction, Inheritance, and Polymorphism.Understand Inheritance in OOP
Inheritance represents an 'is-a' relationship between classes and is primarily used to achieve code reuse. It exists in two main modes: single inheritance (one subclass inherits from one parent) and multiple inheritance (one subclass inherits from multiple parents).Implement the Liskov Substitution Principle (LSP) in class inheritance
The Liskov Substitution Principle (LSP) guides the design of subclasses in an inheritance relationship. The core concept is 'design by contract': while a subclass can change the internal implementation logic of a function, it must not change the 'contract' or 'agreement' defined by the parent class.
To adhere to LSP, a subclass must respect the following parent class agreements:
- The functionality declared in the function signature.
- The constraints and expectations regarding inputs, outputs, and thrown exceptions.
- Any special instructions or constraints listed in the documentation/comments.
Unlike polymorphism (which is a language feature and implementation mechanism), LSP is a design principle ensuring that replacing a parent class with a subclass does not alter the original program's logic or destroy its correctness. It is an application of the 'Open-Closed Principle' within inheritance: the subclass should perfectly inherit the parent's original design intent while providing enhancements.