# Principles of Conventional Software Engineering

The principles of conventional software engineering are like the "rules of the road" for building computer programs. They're based on years of trial and error in the software industry.

Back in the day, making software was a bit confusing. Projects often ran late, cost too much, or didn't work right. So, people started looking for ways to do it better.

These principles cover a bunch of important ideas, from figuring out what users need to making sure the software stays good over time.

They stress the importance of understanding what users want and involving them early in the process. This helps make sure the final product is something people actually find useful.

They also highlight the need for teamwork and clear communication. Making software isn't just about writing code; it's about people working together to solve problems.

Another big thing these principles talk about is testing and documenting. Basically, they say it's super important to check that the software works properly and to write down how it all fits together. This makes it easier for everyone to understand and fix things later on.

Overall, these principles are like a roadmap for making good software. They might seem basic, but they're the foundation for building programs that work well and last a long time.

Some OF The Principles are:

1. **Create or Ensure Quality**:

* Quality must be quantified, and mechanisms should be in place to motivate its achievement.
* Example: Implementing code review processes and quality metrics to ensure high-quality software.

2. **Large-scale Software is Attainable**:
   * Techniques such as involving customers, prototyping, and hiring skilled personnel contribute to achieving high-quality software.
   * Example: Involving end-users in the development process through iterative prototyping to refine requirements.
3. **Early Delivery to Customers**:
   * Providing early versions of the software to users helps identify and meet their real needs effectively.
   * Example: Releasing minimum viable products (MVPs) to gather user feedback early in the development cycle.
4. **Identify Problems Before Solutions**:
   * Before proposing solutions, thoroughly explore all alternatives to understand the problem better.
   * Example: Conducting root cause analysis before implementing fixes for software defects.
5. **Evaluate Design Alternatives**:
   * Examine various architectural and algorithmic options before finalizing the design.
   * Example: Comparing different database architectures to determine the most suitable one for a project.
6. **Select Appropriate Process Models**:
   * Choose a process model based on factors like corporate culture, risk tolerance, and understanding of requirements.
   * Example: Adopting Agile methodologies for projects with evolving requirements and frequent customer feedback.
7. **Use Different Languages for Various Phases**:
   * Select languages and notations suitable for each phase of the software development life cycle.
   * Example: Using UML for design modeling and Java for implementation in a project.
8. **Minimize Intellectual Distance**:
   * Design software structures closely aligned with real-world concepts to reduce cognitive overhead.
   * Example: Naming variables and functions descriptively to reflect their real-world counterparts.
9. **Prioritize Techniques Over Tools**:
   * Emphasize the mastery of techniques before leveraging tools to avoid misuse or inefficiency.
   * Example: Ensuring developers understand fundamental programming concepts before using advanced IDE features.
10. **Optimize for Correctness Before Efficiency**:
    * Ensure software functions correctly before optimizing its performance.
    * Example: Debugging and testing code thoroughly before implementing performance optimizations.
11. **Inspect Code**:
    * Regularly review and inspect code to identify errors and improve quality.
    * Example: Conducting peer code reviews to catch logical errors and enforce coding standards.
12. **Emphasize Good Management Over Technology**:
    * Effective management motivates teams to perform at their best and adapt to challenges.
    * Example: Encouraging open communication and collaboration among team members to foster a positive work environment.
13. **People are Key to Success**:
    * Skilled, experienced, and motivated individuals are crucial for project success.
    * Example: Investing in training and professional development programs for employees.
14. **Proceed with Care**:
    * Evaluate the applicability of practices and methodologies to specific project contexts.
    * Example: Assessing the suitability of adopting microservices architecture based on project requirements and team capabilities.
15. **Take Responsibility**:
    * Hold developers accountable for the quality and reliability of their software.
    * Example: Conducting post-mortem analyses to identify the causes of software failures and learn from mistakes.
16. **Understand Customer Priorities**:
    * Delivering partial functionality on time may be preferable to delayed delivery of complete features.
    * Example: Releasing basic functionality to meet a critical deadline, with additional features added later.
17. **More Functionality Leads to Increased Expectations**:
    * Users' expectations grow as they become accustomed to additional features and improvements.
    * Example: Adding new features in response to user feedback may lead to higher expectations for future releases.
18. **Plan to Discard Initial Implementations**:
    * New products or architectures may require multiple iterations before achieving stability and success.
    * Example: Building a prototype to validate a concept before developing a production-ready solution.
19. **Design for Change**:
    * Create software architectures and components that can adapt to evolving requirements.
    * Example: Designing modular systems with loosely coupled components to facilitate future updates and enhancements.
20. **Document Design**:
    * Comprehensive documentation is essential for understanding, maintaining, and evolving software systems.
    * Example: Writing design documents to explain the rationale behind architectural decisions and system behavior.
21. **Use Tools Wisely**:
    * Tools should enhance productivity and efficiency without introducing unnecessary complexity.
    * Example: Adopting version control systems to track code changes and facilitate collaboration among team members.
22. **Encapsulate Complexity**:
    * Hide implementation details to simplify software design, testing, and maintenance.
    * Example: Using object-oriented principles to encapsulate data and behavior within classes and objects.
23. **Avoid Clever Tricks**:
    * Write code that is clear, understandable, and maintainable, avoiding overly complex or obscure solutions.
    * Example: Refactoring convoluted code into simpler, more readable implementations.
24. **Independent Testing**:
    * Developers should not be the primary testers of their own software to ensure impartial evaluation.
    * Example: Employing dedicated quality assurance teams to conduct thorough testing of software releases.
25. **Coupling and Cohesion**:
    * Measure software's maintainability and adaptability based on the levels of coupling between modules and the cohesion within modules.
    * Example: Refactoring code to reduce dependencies between classes and increase the coherence of related functionality.
26. **Except for excellence**:
    * Our employees will work in a far better way if we have high expectations for them.
