Category Archives: Software Engineering

How to Automate Cleaning Up a .NET Solution

Motivation:

You have a .NET solution with many projects.
You need to deliver the solution to a client very frequently.
You need to clean up all intermediate folders or files to reduce the package size and make the result look tidy.
You want to automate this process to reduce cleaning up time.

Solution:
  1. In Visual Studio, right click a project and select Properties.
  2. Click on Build Events.
  3. Enter the following commands to the Post-build event command line text box:
    rd /s /q $(ProjectDir)obj
    cd $(TargetDir)
    del *.config
    del *.pdb
    del *.xml

    rd /s /q $(ProjectDir)obj: Remove the obj folder in the project directory.
    cd $(TargetDir): Move to the output directory.
    del *.config: Delete all the config files in the output directory.
    del *.pdb: Delete all the pdb files in the output directory.
    del *.xml: Delete all the xml files in the output directory.

    You can modify these commands or add new commands for your specific purpose.

  4. Save the project.
  5. Repeat the process for all the projects in the solution.

 

How to Quickly Estimate Project Effort using Expert Judgement?

Motivation:

You need to quickly estimate effort for building an enterprise system.

Solution:
  1. Ensure that you have a requirements analysis document.
    This can be

    • list of artifacts or
    • a list of features or
    • a list of use cases or
    • a list of user stories or
    • a list of user interfaces or
    • a list of workflows with their steps.
      Never conduct an estimation using expert judgement without any inputs.
  2. Break down each of item in the list into the following (but not limited to) tasks to create:
    • UI and navigation code,
    • database script or storage schema definition code,
    • API code,
    • business logic code,
    • data access code,
    • scheduler code,
    • unit tests code,
    • deployment script,
    • end-to-end test cases and test reports, and
    • user guide.
      You do not need to break down a feature into tasks if you can estimate an effort to complete it with high confidence.
  3. Estimate the effort in man-days for completing each task.
    When giving an estimate for each task, think about

    • possible inputs validation and error handling aspect,
    • possible navigation framework preparation,
    • possible alternative scenarios of the feature related to the task,
    • possible encryption and decryption aspect,
    • possible attacks prevention (e.g. adding CAPTCHA, trimming special characters),
    • possible frameworks, libraries or external tools preparation, and
    • communication, meeting and status report for each task.
      You should break down a task into sub-tasks if you are still not confident when giving an estimate for completing it.
  4. You do not need to perform the second and third step in a sequential order, just complete anything you can and repeat these 2 steps as many times as you like.
  5. If you cannot break down a feature into tasks or cannot give an estimated value for a task then you need to create a prototype or a proof of concept related to the feature.
  6. If you want to have a more accurate estimated value for a task then you should give 3 values for the task estimation: the best case value (optimistic value), the worse case value (pessimistic value) and the most likely value, then calculate the estimated value using the formula below.
    Estimated value = (Best case value + (4 X Most likely value) + Worse case value)/6
  7.  If you just need to give an effort guestimate for a project containing too many requirements then you can group similar items together, then guess an effort for completing one item in a group and multiply this value with the number of items in the group, then repeat this guess and calculation for all the remaining groups.

 

     

     

    How to Quickly Capture and Analyze Requirements for Building a Prototype or Proof of Concept?

    Motivation:

    You need to quickly capture and analyze requirements for building a prototype or proof of concept for an enterprise system.

    Solution:
    1. Capture any artifacts related to a business need. They may be some emails, presentation slides, a proposal document, a legacy system, some similar systems, a feature list or an initial requirement specification.
    2. Define terminologies (terms), build a background and context around the terminologies, expand the terminologies into business roles, business workflows, business components, business entities (objects), and business artifacts as much as possible.
    3. Identify the main stakeholders (roles) who will interact with the system (e.g. Guest, Admin, Developer, User, etc.) and their corresponding business problems or needs (i.e. their motivation of using the software system), and their current business workflows. Create as many scenarios (real world or domain business workflows) as possible. Create a domain model (a model of real world or domain entities, their properties and their relationships) if necessary.
    4. Identify the main components that each stakeholder will interact with (e.g. Accounts, Profiles, Reporting, APIs, Lessons, Videos, etc.) and their corresponding purposes.
    5. Identify the main tasks that each stakeholder will perform (e.g. Register an Account, Log in System, Create/Edit Profile, Create a Bucket, Generate an API Key, Create/Edit/Delete a Lesson, Create/Edit/Delete a Video, View Bandwidth, etc.).
    6. Identify the inputs and outputs and create mock-ups (sketches) or capture similar screens for each task. The quickest way to create a mock-up is to find similar existing screens in your system or external systems, and modify them. You can also search for templates of similar features in the Internet, and modify them. You can also brainstorm a  new one if you are good at creativity and imagining.
    7. Build or draw a prototype demonstrating 2 or 3 critical end-to-end workflows (An end-to-end workflow is a sequence of tasks that solves a real world problem completely). Contrast a current business workflow with a selected end-to-end workflow. The quickest way to create a prototype is to find similar existing workflow of of your system or external systems, and modify them. You can also repurpose a business workflow for a prototype. You can also brainstorm a  new one if you are good at creativity and imagining.
    8. Implement a proof of concept related to the selected end-to-end workflow.
    9. For a complicated system, you may need to implement a proof of concept, build a prototype, and create a work break down structure or product backlog in parallel to ensure that the requirements are technologically and economically feasible.

     

    How to Quickly and Confidently Read Code?

    Motivation:

    You need to read existing source code to add your feature or fix a bug or to replicate its functions in another language or system.

    Solution:
    1. Try building and running the code without any modification.
    2. Try building and running the code with your inputs.
    3. Try modifying or adding simple UI elements without touching the business logic or data layer.
    4. Try writing a unit test for a function.
    5. Try changing a variable name and make sure that the change does not break anything.
    6. Try changing a package or module name and make sure that that the change does not break anything.
    7. Try breaking a long method to smaller ones.
    8. Try breaking a large object or file to smaller ones.
    9. Try replacing an algorithm with with a better one.
    10. Try replacing an old component with a newer or better one.
    11. Try recreating the code structure from the separate components. If you cannot do this then try to understand the architecture of the existing source code.
    12. If you get an error when making the changes above then try showing the error on client side.
    13. If you cannot show the error on client side then try identifying the logic flow of the code related to the error, debug information, and learn about new terminologies or concepts in the code.

    Example:

    const maskPhone = (val) => {
        const x = val.replace(/\D+/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
        return !x[2] ? x[1] : `(${x[1]}) ${x[2]}` + (x[3] ? `-${x[3]}` : ``);
    };
    export { maskPhone }

    If you are not sure about what the JavaScript code above does then try to learn

    Another example:

    <div class="container">
        <iframe class="responsive-iframe" src="https://www.youtube.com/embed/u9Dg-g7t2l4"></iframe>
    </div>
    .container {  
        position: relative;  
        overflow: hidden;  
        width: 100%;  
        padding-top: 56.25%; /* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */
    }
    /* Style the iframe to fit in the container div with full height and width */
    .responsive-iframe {  
        position: absolute;  
        top: 0;  
        left: 0;  
        bottom: 0;  
        right: 0;  
        width: 100%;  
        height: 100%;
    }
    

    If you are not sure about what the HTML and CSS code above  do then try to learn

    • how many ways an element can be placed in a web page (a document),
    • what is the position relationship between an element and its parent,
    • what is the position relationship between an element and its siblings,
    • what is the position relationship between an element and the document root, and
    • what position: relative , position: absolute , overflow: hidden do.

     

     

    Software Requirements Lessons Learned

    Lessons learned 1: Emerging requirements.

    Problem: Requirements do not exist. They are emerging and often become incorrect and therefore constant change of requirements happens.

    Context: Our goal is to ensure project’ success and client’s satisfaction. In order to achieve this goal our delivered solution must solve our client’s problems and satisfy our client’s needs. Unfortunately many clients do not know exactly what they want because they want to try a new business process or would like to enhance their current daily business workflow but the new process or workflow has not been defined yet. They would like us to build something for them to try, then if it does not work in real world then they will switch to something else.

    The issue becomes even worse when they do not have time to review our prototype and await a quite complete solution.

    Sometimes they consider our prototype a complete solution and want us to revise it around their constant changes for production although the architecture limits of the prototype make it very time consuming for such revision or even prevent us from doing such revision. These limits exist because we only build the prototype for the envisioned requirements, not for the endless changes.

    Solution:

    • Analysis and communication are critical to ensure that our deliverables match with client’s needs. It does not matter whether we use RUP or Agile process for development. It does not matter whether we use UML, or boxes and lines, or text, or coded prototypes or paper and pen for describing the problems that need to be solved. Our client and analyst must review, refine and confirm problem specification regularly.
    • Otherwise formal requirements should be modeled, reviewed and approved before design begins to ensure that our project will deliver solution to the right problems.
    Lessons learned 2: Vague requirements.

    Problem: Requirements are described vaguely and therefore are implemented incorrectly and many detailed elements are missing.

    Context: Our clients often just give what they have. It can be a video demo of their existing legacy systems, a list of what they want, some screenshots captured from other similar systems, a long conversation in an email thread, some phone calls. We build a solution based on these artifacts and it turns out that they want something completely different or many detailed requirements are missing.

    Solution:

    • Our responsibility is to clarify our client’s problems and needs. Again analysis is an important tool to clarify our client’s problems and needs. Early requirements can be described in any form, including phone calls, emails, screenshots, video demo, feature list. However all of them should then be refined properly using use cases, user interfaces, workflows, story map and prototypes for client to review regularly.
    • Sometimes we are stuck at analysis, especially when we analyze integration or enhancement needs that have not existed yet and require creativity. In this case a dirty prototype and a proof of concept or small technical exercises should be done so that we can have inputs for inspiring ideas for analysis.
    Lessons learned 3: Requirements dispute.

    Problem: Requirements are described only at business level, and therefore many detailed elements are not implemented. However customer does not have time to review the implemented system. When the project is in transition phase it turns out that most of the implemented requirements are non-compliant.

    Context: In order to reduce development time and cost many teams just take business requirements and implement them. They may create a work break down structure or a detailed task list for completing these business requirements. However these tasks just describe HOW a business requirement is implemented, NOT WHAT it should be. It means that both USER functional and non-function requirements of a BUSINESS requirement are not analyzed. The situation become bad when it costs too much for a customer to review an implemented business requirement regularly, so the customer just let the teams finish their work. When the project is in the transition phase it turns out that many details of user requirements are not implemented.

    Solution:

    • Critical business requirements must be refined into appropriate user stories or use cases.
    • Non-function requirements must be incorporated as notes into each story or use case.
    • Adequate UI sketches (mock-ups) or prototypes or captured screens should be created.
    • Test cases should be created and agreed to validate requirements.
    • A single repository for all requirements should be used for change management and traceability.
    • Architecture and/or proof of concept should be created to discover integration limits of specific requirements.
    • User manual should be created for each business requirement.
    • More importantly, frequent requirements and system validation should be done by a customer if possible to improve the understanding about requirements and prevent communication gaps, especially when an Agile development method is selected to reduce the time and cost. Customer’s assessment must be done regularly (at least weekly, preferred daily if an Agile method is selected), not just once when the project is about to be closed.



     

    How to Use Git

    Motivation:

    You want to use Git to version your files or share your files with other people.

    Solution:
    • Register a GitHub or a GitLab account.
    • Create a GitHub repository or a GitLab project.
    • Download and install a Git client.
    • Pull (checkout) a remote repository (e.g. https://github.com/huybien/asp.net-core.git) to an empty local folder (e.g. C:\Users\admin\Downloads\code).
      cd C:\Users\admin\Downloads\code
      git init
      git remote add origin -f https://github.com/huybien/asp.net-core.git
      git pull origin main
      / * or * /
      git pull origin master
    • Pull (checkout) a remote repository (e.g. https://github.com/huybien/asp.net-core.git) to a local folder that contains existing code (e.g. C:\Users\admin\Downloads\code).
      cd C:\Users\admin\Downloads\code
      git init --initial-branch=main
      git remote add origin https://github.com/huybien/asp.net-core.git
      git fetch --all
      git reset --hard origin/main
      git add *.*
      git commit -m "new files added"
      git push -u origin main
      
    • Push local files to a remote empty repository.
      git credential-manager delete https://github.com
      git config --global user.email "info@huybien.com"
      git config --global user.email
      git config --global user.name "Huy Bien"
      git config --global user.name
      git init
      git add *.*
      git commit -m "first commit"
      git branch -M main
      git remote add origin https://github.com/huybien/asp.net-core.git
      git push -u origin main
    • Push changes to a remote repository.
      git credential-manager delete https://github.com
      git config --global user.email "info@huybien.com"
      git config --global user.email
      git add *.*
      git commit -m "CP form"
      git branch -M main
      git push -u origin main
    • Update (fetch and merge) a local repository.
      git pull origin main
      /* or */
      git branch --set-upstream-to=origin/main main
      git pull
      
    • Force updating (fetch and overwrite) the current repository.
      git fetch --all 
      git reset --hard origin/main
      git clean -fd 
      git pull
    • Force updating (fetch and overwrite) a local repository (e.g. C:\Users\admin\Downloads\code).

      git -C C:\Users\admin\Downloads\code fetch --all
      git -C C:\Users\admin\Downloads\code reset --hard origin/main
      git -C C:\Users\admin\Downloads\code clean -fd 
      git -C C:\Users\admin\Downloads\code pull
    • Reset (Revert) a local repository to a previous version.
      cd C:\Users\admin\Downloads\code 
      git log --oneline 
      git reset --hard 4355842  
      // where 4355842 is a version id.
    • Remove all cached files.
      git rm -r --cached .

     

     

    How to Quickly and Reliably Fix a Bug

    Problem:

    It may take you much effort to fix a bug. The fix may not be reliable. How can you avoid this situation?

    Solution:
    1. Try to reliably reproduce the bug. It is okay if this may not be successful.
    2. Try isolating the bug on the same environment by using specific, smaller data and settings. It is okay if this is still not successful.
    3. Search for an existing solution using the error message, the library or framework name and version, and the operating system name and version. This can save us a lot of effort.
    4. Try to understand all the concepts in the error message.
    5. Debug and log messages to identify the exact location of the source code that causes the issue. In order to to this we need to do the followings.
      • Identifying the flow of the data, i.e. the use case, the entry point and the exit point.
      • Trying to understand the programming language syntax. Do not guess anything.
      • Trying to understand the purpose, inputs and outputs of a library function. Again, do not guess anything.
      • Trying to understand the data structure and a part of the database schema related to the use case.
      • Trying to review some values inside the database if possible.
      • Trying to understand the concepts, algorithms and architecture related to the use case.
      • These steps may be done in parallel and iteratively.
    6. Guess a cause of the problem based on the information retrieved in the third step.
    7. Try to isolate the issue, i.e. try to reproduce the issue using specific code and unit tests, if possible.
    8. Search for or propose a solution for the cause, i.e. propose a fix.
    9. Test the fix.
    10. Repeat from Step 5 to 8 if needed.

    Topic 15 – Advanced Software Design

    Why do I need to learn about advanced software design?

    I think that I already learned about software design in the Topic 12 – Introduction to Software Design.

    Now your task is not just to build a house.  Your task is to build a city. 
    
    The situation is similar to when you create complex software. Now, you are responsible for creating a software system containing about 10,000 classes for 5,000 people to use in 15 years. The maximum system downtime must be less than 5 minutes per year.
    Image that you have to create a system that serves millions of people simultaneously like Facebook or YouTube or Amazon or Office 365 or GMail. Are you able to create one?
    Image that you are tasked to create a web framework for developers to extend such as ASP.NET Core or Yii or React.js. Are you confident in creating one?
    If you are not sure how to fulfill these tasks then probably, you should learn how other people crafted similar systems and adapt their experiences to your case. Advanced software design knowledge will then be useful for you.

    What can I do after finishing learning advanced software design?

    You will know how to design a complex software system that satisfies not only functional requirements but also security, modifiability, scalability, reusability, extensibility and reliability requirements.

    That sounds interesting! What should I do now?

    Advanced software design requires a lot of reading. Please do review the software design knowledge introduced to you in the Topic 12 - Introduction to Software Design first.
    Nowadays software can be applied to many fields. Each of them requires specific advanced software design knowledge. In this topic, we only focus on enterprise software due to its popularity.
    Before you design a complicated system you must thoroughly  understand its sophisticated requirements. This is a critical step when building a large system.
    
    Please read this David C. Hay (2002). Requirements Analysis: From Business Views to Architecture. Prentice Hall PTR book to learn how to elicit, analyze and document requirements for an enterprise system.
    After that please read 
    - this Deepak Alur, Dan Malks and John Crupi (2003). Core J2EE Patterns: Best Practices And Design Strategies. Prentice Hall PTR book, and
    - this Martin Fowler et al. (2002). Patterns Of Enterprise Application Architecture. Addison Wesley book, and
    - this Philip A. Bernstein and Eric Newcomer (2009). Principles of Transaction Processing. Second Edition. Morgan Kaufmann book.
    
    After that please read 
    - this Eric Evans (2003). Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison Wesley book, and
    - this Jimmy Nilsson (2006). Applying Domain-Driven Design and Patterns: With Examples in C# and .NET. Addison-Wesley Professional book, and
    - this Dino Esposito and Andrea Saltarello (2014). Microsoft .NET: Architecting Applications for the Enterprise. Microsoft Press book, and
    - this Vaughn Vernon (2013). Implementing Domain-Driven Design. Addison-Wesley Professional book.
    
    After that please read
    - this Mark Endrei et al. (2004). Patterns: Service-Oriented Architecture and Web Services. IBM Corp book, and 
    - this Sam Newman (2021). Building Microservices: Designing Fine-Grained Systems. O'Reilly book, and
    - this Sam Newman (2019). Monolith to Microservices - Evolutionary Patterns to Transform Your Monolith. O'Reilly Media book, and
    - this Cloves Carneiro and Tim Schmelmer (2016). Microservices From Day One. Apress book.
    After that please read 
    - this Martin Kleppmann (2016). Making Sense of Stream Processing. O'Reilly Media book.

    After finishing the books please click Topic 16 – Calculus to continue.

    Topic 13 – Software Project Management

    Why do I need to learn about software project management?

    Knowing how to create software does not mean that you will create software SUCCESSFULLY. Creating software successfully means that you satisfy all customer's REQUIREMENTS ON TIME, ON BUDGET with HIGH QUALITY while making both the customer and yourself HAPPY. Especially, your software must create REVENUE for the customer.
    
    Have you ever wondered why many software projects failed; why Microsoft, Oracle, Google, Apple, Amazon and IBM abandoned many projects?
    Software project management will provide you knowledge so that you could improve the success probability of your software projects and mitigate all the project risks.

    What can I do after finishing learning about software project management?

    You will know how to plan a project, including scoping, estimating time and resources, creating a schedule or an adaptive release plan, identifying and responding to risks.
    
    You will know how to create software using the mindset of a specific methodology (i.e. Waterfall, Rational Unified Process, Iterative and Incremental Development, Agile Methods, Scrum, Extreme Programming, Kanban, PMI, PRINCE2).
    
    You will know how to perform project configuration management, how to combine development and operations to release software faster, how to control project changes, how to report project status, how to control product and process quality.
    
    You will know how to collaborate with others to create software, how to motivate your team members.

    Uh-oh! I am a developer. I do not want to be a project manager. Do I really need to know about project management?

    If you have a doubt about the usefulness of project management knowledge then just review the situations below. If you can overcome all of them then congratulation, you already have enough project management knowledge that a developer needs.
    - You are asked by your manager when you can finish your tasks. Unfortunately, the tasks are new to you. The requirements are vague. It is even worse that you have not found technical solutions for them.
    - You are required to finish a task requiring a collaboration with other team members. Conflicts arise frequently. You do not want to work with them anymore but you still have to complete the task.
    - You cannot complete a task on time due to many incidents.
    - You are given only a project idea and asked to create a product. The difficulty is that you do not know where to start.
    - Most of your projects cannot be complete on time and on budget and you do not know what are the root cases.
    - Most of your customers do not want to partner with your team again although their projects were finished on time with high quality by your team.

    Alright! What should I do now?

    Software project management requires a lot of reading.
    In order to get familiar with software project management concepts please read this Jennifer Greene and Andrew Stellman (2005). Applied Software Project Management. O'Reilly book.
    After that please read this Steve McConnell (2006). Software Estimation: Demystifying the Black Art. Microsoft Press book to learn how to estimate effort, time and cost for a software project.
    After that please read 
    - this Frederick P. Brooks, Jr. (1995). The Mythical Man-Month: Essays on Software Engineering. Addison-Wesley Professional book to learn the timeless principles of software project management, and
    - this Tom DeMarco and Timothy Lister (2013). Peopleware: Productive Projects and Teams. Addison-Wesley Professional book, and 
    - this Zachary Wong (2007). Human Factors in Project Management: Concepts, Tools, and Techniques for Inspiring Teamwork and Motivation. Jossey-Bass book to learn how to deal with human side of project management.
    
    After that please read this Tom DeMarco and Timothy Lister (2003). Waltzing with Bears: Managing Risks On Software Projects. Dorset House book to learn how to deal with software project risks.
    After that please read 
    - this Philippe Kruchten (2003). The Rational Unified Process: An Introduction. Addison-Wesley Professional book, and 
    - this Per Kroll and Philippe Kruchten (2003). The Rational Unified Process Made Easy: A Practitioner's Guide to the RUP. Addison-Wesley Professional book, and
    - this Scott W. Ambler et al. (2005). The Enterprise Unified Process - Extending the Rational Unified Process. Prentice Hall book to learn how to develop software using a managed process.
    
    After that please read 
    - this Ken Schwaber (2004). Agile Project Management with Scrum. Microsoft Press book, and
    - this Jonathan Rasmusson (2010). The Agile Samurai: How Agile Masters Deliver Great Software. Pragmatic Bookshelf book, and
    - this Kenneth S. Rubin (2012). Essential Scrum: A Practical Guide to the Most Popular Agile Process. Addison-Wesley Professional book, and
    - this Mike Cohn (2010). Succeeding with Agile: Software Development Using Scrum. Addison Wesley book, and
    - this Dean Leffingwell (2011). Agile Software Requirements. Lean Requirements Practices for Teams, Programs, and the Enterprise. Addison-Wesley Professional book, and
    - this Mike Cohn (2005). Agile Estimating And Planning. Pearson Education book, and
    - this Kent Beck and Cynthia Andres (2004). Extreme Programming Explained: Embrace Change. 2nd Edition. Pearson Education book, and
    - this James Shore and Shane Warden (2008). The Art of Agile Development. O'Reilly book, and 
    - this Esther Derby and Diana Larsen (2006). Agile Retrospectives: Making Good Teams Great. Pragmatic Bookshelf book to learn how to develop software using Scrum and agile mindset.
    After that please read
    - this Eric Brechner (2015). Agile Project Management with Kanban. Microsoft Press book, and 
    - this David J. Anderson (2010). Kanban: Successful Evolutionary Change for Your Technology Business. Blue Hole Press book to learn how to develop software using Kanban method.
    After that please read 
    - this Jessica Keyes (2004). Software Configuration Management. Auerbach Publications book to learn how to perform software configuration management, and
    - this Len Bass, Ingo Weber and Liming Zhu (2015). DevOps: A Software Architect's Perspective. Pearson Education book to learn how to release software faster.
    After that please read 
    - this Project Management Institute (2017). A Guide to the Project Management Body of Knowledge. Sixth Edition. Project Management Institute book, and
    - this Kathy Schwalbe (2017). An Introduction to Project Management. 6th Edition. Schwalbe Publishing book to review the techniques developed by the Project Management Institute (PMI).
    If you are interested in taking a PMP exam then please read 
    - this Kim Heldman (2018). PMP Project Management Professional Study Guide. Sybex book, and 
    - this Joseph Phillips (2018). PMP Project Management Professional Study Guide. McGraw-Hill Education book.
    After that please read 
    - this Steve McConnell (1996). Rapid Development: Taming Wild Software Schedules. Microsoft Press book to review classical methods and techniques of software development
    - this Murali K. Chemuturi and Thomas M. Cagley Jr. (2010). Mastering Software Project Management: Best Practices, Tools and Techniques. J. Ross Publishing book to review approaches to software project management, especially when organizational-level processes and practices establish a platform on which a software project is managed.
    The information in these 2 books may help you in some specific situations.
     After finishing the books please click Topic 14 - Introduction to Database Design to continue.

    Topic 12 – Introduction to Software Design

    Why do I need to learn about software design?

    What will you do if you are tasked to build a house. You will need to sketch its first and build the house based upon the sketch. Otherwise you may build a house that may collapse in a few weeks or cannot be decorated due to errors.
    
    The situation is similar when you create software. You need to plan how you will build it first by deciding how many components and objects will be used for constructing to solve at least a core problem, what are their responsibility, how they work together, how data will be organized, how data will be flowed within these components, how users will interact with your application, how these components will be deployed.
    
    Software design knowledge will show you how to do these tasks.

    What can I do after finishing learning software design?

    You will know how to create a design for an application including static and dynamic structure, data organization, business processing workflows.

    Is is really useful? I feel that you can write the code right after having the requirements and I could refactor my code when needed.

    That's great if you can do it like that. Just return to this topic
    (i) when you do not know how to write the code for a feature or 
    (ii) when you cannot refactor your code because only a small change breaks the whole application or 
    (iii) when you write a software system together with 20 other developers and you do not know how to integrate results of all the developers into one solution or 
    (iv) when you software system serves 20 users simultaneously very well but it stops when serving 2,000 users simultaneously and you do not know how to fix it.

    Alright! What should I do now?

    Software design requires a lot of reading. Each application type (enterprise systems, games, intelligent systems) require specific design knowledge. At this point we focus only on the basic elements of software design.
    In order to get familiar with software design please read these 3 books below in parallel:
    
    - Grady Booch et al. (2005). The Unified Modeling Language User Guide. Addison Wesley Professional
    
    - Craig Larman (2004). Applying UML And Patterns. 3rd Edition. Prentice Hall
    
    - Robert C. Martin (2003). Agile Software Development - Principles, Patterns, and Practices. Pearson
    After that please read this Erich Gamma et al (1994). Design Patterns Elements Of Reusable Object Oriented Software. Addison-Wesley Professional book.
    
    Please focus on the Motivation section of each pattern. You can skip a pattern if the problem presented in its Motivation section is not relevant to your situation.
    After that please read this Frank Buschmann et al. (1996). Pattern-Oriented Software Architecture: A System Of Patterns. John Wiley & Sons Ltd book.
    After that please read 
    - this Meilir Page-Jones (1988). The Practical Guide to Structured Systems Design. Pearson Education book, and 
    - this Bertrand Meyer (1997). Object-Oriented Software Construction. Prentice Hall book, and
    - this Grady Booch et al. (2007). Object-Oriented Analysis and Design with Applications. Pearson book, and
    - this David Budgen (2003). Software Design. Pearson book and this David Budgen (2020). Software Design. CRC Press book
    to learn how to design software systematically.
    After that please read this Robert C. Martin (2017). Clean Architecture: A Craftsman’s Guide to Software Structure and Design. Pearson Education book to learn how to create a real world architecture for an enterprise system.
    After that please read 
    - this Len Bass, Paul Clements and Rick Kazman (2012). Software Architecture in Practice. Addison-Wesley book to review software architecture aspects, and
    - this Paul Clements et al. (2010). Documenting Software Architectures: Views and Beyond. Pearson book to learn how to document an architecture so that it can be used for communicated, built and maintained, and
    - this Humberto Cervantes and Rick Kazman (2016). Designing Software Architectures: A Practical Approach. Addison-Wesley Professional book to learn how to create an architecture systematically, and
    - this Nick Rozanski and Eoin Woods (2012). Software Systems Architecture: Working with Stakeholders Using Viewpoints and Perspectives. Addison-Wesley Professional book to learn how to apply theory to create an architecture systematically in real world.
    After finishing the books please click Topic 13 - Software Project Management to continue.