Skip to content

[en]02_Design

cuppar edited this page Jul 31, 2023 · 14 revisions

The second step of software development, design

English | 中文


< Prev | Next >

Design is probably the hardest part of the entire software development process

  • A good design can fundamentally affect every aspect of a software
    • Correctness
    • safety
    • performance
    • user experience
    • robustness
    • Scalability
    • Maintainability
    • etc
  • The general process of software design is:
    • Guided by the requirements document produced in the previous chapter
    • By combining the actual situation such as software usage scenarios/user groups/estimated scale
    • In various contradictions such as correctness and implementation convenience / quality and development cycle / performance and resource usage
    • Make an appropriate trade-off to achieve or come close to the desired goal
    • Finally produce a design document to guide the subsequent software implementation
  • Software design generally includes:
    • feature design
    • UI design
    • Interactive Design
    • Architecture design
    • Interface design
    • etc

Let's do the hard part

Functional design and UI design

Since our project is very simple, basically the functional design and UI design are consistent with the description of the requirements document, so this part is skipped

Interactive Design

Interaction design is mainly to design how software interacts with end users, that is, how users input instructions and how programs output results. The main points are:

  • Based on the requirements document produced in the previous chapter, think about how the user inputs and how the program outputs for each function
  • Again, here is your time to think for yourself, grab a pen and paper and write down your answers

Don't look down until you're done thinking, or you'll get nothing and just waste your time!

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

My thoughts

Well, I'm assuming you've finished your thinking and have your answer.

Here are my thoughts, you can compare them with yours. This just represents my own thinking, does not mean that I am right.

Program output, in addition to the content in the above link, error handling is also required

  • Add a todo
Add <todo-name> fail: <why>
  • Complete a todo
Completed todo <todo-id> fail: <why>
  • Mark a completed todo as incomplete
Uncompleted todo <todo-id> fail: <why>
  • Put a todo in the recycle bin
Delete todo <todo-id> fail: <why>
  • Recover todo from a recycle bin
Restore todo <todo-id> fail: <why>
  • Empty Recycle Bin
Destroy all deleted todos fail: <why>
  • Delete a todo
Destroy todo <todo-id> fail: <why>
  • Clear all todos
Clear all todos fail: <why>
  • List all uncompleted todos
List uncompleted todos fail: <why>
  • List all completed todos
List completed todos fail: <why>
  • List all recycle bin todos
List deleted todos fail: <why>
  • List all todos
List all todos fail: <why>

Architecture Design

Architecture design refers to splitting the entire software system into multiple modules, defining what each module does, and how to interact/cooperate between modules to achieve the ultimate goal

Why do architecture design?

  • Because the software system is not a simple thing, medium and large software systems cannot be done by one or two people in a day or two
  • And the software system is a rare product of pure thinking, theoretically separated from any physical medium, just like music and piano, music is played by the piano, but music is invisible
  • It is difficult for the human mind to deal with a large amount of complex things in a short period of time
  • So need: divide and conquer, separation of concerns, abstraction
  • In this way, the human brain can only think about a small part of simple things at a time, and finally combine simple small things to solve complex big problems
  • Architecture design is such a process
  • Reasonable architecture has many other benefits, including but not limited to:
    • Multiplexing
    • Easy to expand
    • Easy maintenance
    • Reduce communication costs
    • etc

How to do architecture design?

This is a difficult question to answer. It needs to be weighed according to the actual situation. It needs rich experience in the target problem area, certain programming experience, etc. This question alone can write countless books, but there are still many problems. Some more general design principles can be used for reference. Here are some simple lists. More still need readers to think more and practice more, and learn in practice.

  • The first and most important: There is no standard answer, no authority, no dogma, according to the actual situation, we must have the courage to break the rules and challenge the authority.
  • KISS (Keep it simple and stupid)
  • DRY (Dont repeat yourself) to eliminate repetition
  • Single responsibility principle, a module only does one thing
  • The principle of least cost, that is, at the beginning of the design, make the correct choice as possible to minimize the cost of subsequent adjustments
  • The principle of least accident, that is, at the beginning of the design, it is possible to reduce accidents, whether it is at the architectural level or at the code level

RTD architecture design

It is more appropriate to think about what kind of architecture should be adopted by RTD? Think for yourself about the following questions and give your answers

  • What behaviors are involved in RTD applications?
  • Which of these behaviors are similar?
  • Which behaviors can be grouped together?
  • Based on the above information, how can the modules be divided?
  • What does each module do?
  • What is the relationship between modules? Who depends on whom?
  • Try to draw a picture to express it.

Don't look down until you're done thinking, or you'll get nothing and just waste your time!

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

My thoughts

  • What behaviors are involved in RTD applications?
    • Interact with users
      • Parsing of command line parameters
      • Successful and failure result output
    • Implement user instructions
      • Add todo
      • Complete todo
      • ...
    • Store user's data
      • Define what a todo includes
        • Data model definition
      • Where to store?
        • csv file
      • How to read and write?
        • File reading and writing
        • Model mapping (serialization/deserialization)
          • A todo object in Rust code can be turned into a row of csv records
          • A row of csv records can be turned into a todo object in Rust code
  • Based on the above information, how can the modules be divided? What does each module do?
    • Command line interface layer (interaction with user, input and output)
    • Program interface layer (encapsulate all program behavior, except for the part that interacts with the user)
    • Business logic layer (encapsulates each function)
    • Data model layer (defining what todo items include, such as id, name, creation time, etc.)
    • Data storage layer (data mapping/file reading and writing)
  • What is the relationship between modules? Who depends on whom? Try to draw a picture to express these.

rtd_architecture

Let's imagine:

  • We only need to change the command line interface module to the touch screen of the smart watch, and the csv file to the storage in the smart watch, and our todo application becomes an App on the smart watch.
  • If we change the file storage to a database on the server, and the command line interface layer to a web page, we will get an online Todo application website.
  • If we want to add a function of modifying todo, we only need to add a piece of code in the business logic layer, and the upper layer can call it directly, and a new function will come out.

Isn't it great?

Interface design

Interface design can be said to be a further refinement of architecture design. The interaction between each module is determined using a more formal definition. Think about it. According to the above architecture, what kind of interface should each module provide to the outside world?

Don't look down until you're done thinking, or you'll get nothing and just waste your time!

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

My thoughts

Command Line Interface Layer

Provide operation instructions to the user and call the lower layer interface

Help document

rtd -h
rtd --help

Add a todo

rtd -a <item-name>
rtd --add <item-name>

List all uncompleted todos

rtd
rtd -l
rtd --list
rtd -l uncompleted
rtd --list uncompleted

Complete a todo

rtd -c <item-id>
rtd --complete <item-id>

List all completed todos

rtd -l completed
rtd --list completed

Mark a todo as incomplete

rtd -u <item-id>
rtd --uncomplete <item-id>

Throw a todo into the recycle bin

rtd -d <item-id>
rtd --delete <item-id>

List all todos in the recycle bin

rtd -l deleted
rtd --list deleted

Restore a todo from the recycle bin

rtd -r <item-id>
rtd --restore <item-id>

Physically delete a todo

rtd --destroy <item-id>

Empty trash

rtd --destroy-deleted

List all todos

rtd -l all
rtd --list all

Clear all todos

rtd --clear

Program interface layer

Centralize all the program logic here and provide it to the outside world. At present, it is only a transfer of the interface provided by the business logic layer

Business logic layer

Define an interface using the form

function_name(input) -> output

Add a todo

add_item(todo_name) -> result_message

List all uncompleted todos

list_uncompleted() -> result_message

Complete a todo

complete_item(todo_id) -> result_message

List all completed todos

list_completed() -> result_message

Mark a todo as incomplete

uncomplete_item(todo_id) -> result_message

Throw a todo into the recycle bin

delete_item(todo_id) -> result_message

List all todos in the recycle bin

list_deleted() -> result_message

Restore a todo from the recycle bin

restore_item(todo_id) -> result_message

Physically delete a todo

destroy_item(todo_id) -> result_message

Empty trash

destroy_deleted() -> result_message

List all todos

list_all() -> result_message

Clear all todos

clear() -> result_message

Data Model Layer

Define what attributes and behaviors a todo should have

item {
   id,            // unique identifier
   name,          // name description
   completed,     // whether to complete
   deleted,       // Whether to throw into the recycle bin
   created_at,    // creation time
   completed_at,  // completed time
   deleted_at,    // delete time

   // create a new todo
   new(id, name, completed, deleted, created_at, completed_at, deleted_at),
   to_prettier_string(),  // pretty output when displayed on screen
   to_string(),           // Serialize to string for insertion into csv file
   from_string(),         // Deserialize from string to todo for recovery from csv file
}

Data storage layer

Define how to convert between todo and csv file records, create/delete/modify/read, and file read and write operations

csv {
   filename,    // csv file name
   file,        // file handle (an object that stores file-related metadata)

   new(),       // Open or create a new csv file storage
   content(),   // read file content

   // Modify the content at will, start from the `offset` position, delete `delete_size` bytes, and write the `write_content` string
   splice(offset, delete_size, write_content),
}

add_item(item),               // add a todo to the csv file storage
update_item(item),            // modify an existing todo
delete_item(id),              // delete a todo record in a csv file
get_all() -> item[],          // read all todo records and return a todo array
get_item_by_id(id) -> item,   // add a todo to the csv file storage
get_max_id(),                 // Return the largest id in the current csv file, so as to calculate the self-incrementing id when adding todo

Output design document

Finally, based on the above content, output a design document. This step is left as an exercise for the readers. After all, the most difficult part has been completed, and the rest is just some text layout work. But don't skip it lightly, remember, Learning by doing, you can still learn a lot from it, otherwise you will gain nothing.

If you feel a little strenuous in this chapter, don't worry, it's normal, stop and think about it, or when you start to implement it later, you will come back and think about it, and you will gradually become familiar with it.

Summary

  • You did it, you thought out the whole design plan from the requirements document, it's amazing!
  • It is not an exaggeration to say that software design is the most difficult step in the software development process.
  • The output of software design is the design document, which is used as a guide for subsequent development.
  • The hardest part is done, we are halfway there, we just need to make it happen.
  • We're finally about to start writing some code, come on!

< Prev | Next >