Unit 11
Development individual project: coding output and evidence of testing
Summative assessment reflection
The assignment was focused on building a school grading system based on the design submitted in Unit 6. It provides user-role-based access, implements functionality to create, read, update, and delete user records, marks, subject information, etc., and, most importantly, includes several security features with an option to switch them off. The system generally follows the initial design, although with some changes: for example, the actions aren’t directly reconstructed from the payload, and there is now a dedicated HTTP connection handler that was absent from the original design but was required for Python’s built-in HTTP server.
Still, the design provided a solid foundation for the system architecture and allowed for quicker initial project setup. However, as I mentioned in previous modules, the UML diagrams usually diverge from the actual code, which is also evident from the diagram in the submission report: there are some methods or even classes that weren’t part of the initial design, as the need for them only became obvious during development.
Python’s rich standard library and the lack of restrictions on using external components allowed for a fast setup of the HTTP server — I only had to implement the logic to be called for each of the methods — and the hashing functionality. This also led me to learn more about password hashing: having never worked with it before, I only had some basic knowledge on the topic, so I was quite amazed by the bcrypt
algorithm’s approach, where the password and random salt are hashed repeatedly, and the resulting hash string contains all the information — algorithm version, salt, and password hash — required to verify the match.
This project allowed me to explore different testing approaches in more variation than before: the test suite for the server component includes not only unit tests, but also integration tests to verify proper behavior of the HTTP endpoints. I found this approach very rewarding, as not only could it confirm that the endpoints and the actions behind them work, but it also prevented some regressions and — most importantly — provided a foundation for the client code.
Unlike in previous projects, this one implements HTTP connectivity between the server and the client part of the application. It was both a requirement — there had to be an API present — and something another student on the course shared he had used in earlier modules. For some reason, I had never considered local HTTP connectivity for course projects, but it turned out to be quite convenient, if adding some overhead in the form of implementing completely separate logic for the client. I will definitely consider using this approach in future projects.
The most challenging part of this assignment was implementing the attack scenarios: as a software developer, I’m mostly used to developing applications that are well-designed and secure to the best of my understanding and capabilities. Here, the requirement to provide switchable security encouraged me to look into some of the application’s capabilities and sometimes think about how they might be implemented in a worse way — for example, by using eval()
instead of json.loads()
. Ultimately, I liked this part for how it made me look at software development from a new angle and research more about the security of Python applications.
Architecture is not the goal — it is the tool
Read the following books:
- Valente, M.T. (2024) Software Engineering: A Modern Approach (Chapters 7.1 and 7.4).
- Gandhi, R., Richards, M. and Ford, N. (2024) Head First Software Architecture (Chapters 8 and 10).
The forum has a message that says: “Torvalds has been proven wrong and it only took nearly thirty years. Microservices and microkernels are the future. “
On the forum post a message either agreeing or disagreeing with the above and give a justification (ideally with an academic reference) supporting your view.
While applying microkernel and microservices approaches can be beneficial in some cases, it is important to consider the specific use case before settling on an architecture. In software development, there is rarely a one-size-fits-all solution. It is always easier to judge in hindsight, once the outcome is known, but we can still learn from others’ successes and mistakes, including the case of the Linux kernel.
Addressing the question of monolith vs. microkernel architecture, Valente (2024) interprets Linus Torvalds’s comment about the Linux kernel becoming “huge and bloated” as him agreeing with the opinion that microkernel architecture would be a better choice for the project. Indeed, had Linux been designed this way from the start, it might have been easier to extend and maintain.
Even the smallest software systems typically benefit from using their language’s built-in tools for organizing functionality into modules or packages (Oracle, 2021a, 2021b; Python Software Foundation, 2025). Microservices and microkernels take this idea further, splitting a monolithic system into multiple independent components that communicate via predefined application programming interfaces (APIs). This allows for independent upgrades, improves robustness by isolating failures, and makes it easier to add new modules without extensive testing (Gandhi, Richards and Ford, 2024).
Still, does splitting a system into independent modules automatically make it better? Probably not. Modular architectures are more difficult to design and implement, requiring experience and an understanding of best practices (Gandhi, Richards and Ford, 2024). They only make sense for larger, more complex systems expected to grow over time. Returning to the Tanenbaum–Torvalds debate, when Linux began as a hobby project, these concerns likely did not matter to Torvalds (Torvalds, 1991).
In conclusion, architectural decisions should be driven by the system’s requirements: how robust it needs to be, how important extensibility is, what the development roadmap looks like, and so on. Only then will architecture serve as a tool for building the right solution instead of being an independent goal.
References
Gandhi, R., Richards, M. and Ford, N. (2024) Head First Software Architecture. O’Reilly Media, Inc.
Oracle (2021a) Introduction to Modules in Java - Dev.java, Dev.java: The Destination for Java Developers. Available at: https://dev.java/learn/modules/intro/ (Accessed: 20 July 2025).
Oracle (2021b) Objects, Classes, Interfaces, Packages, and Inheritance - Dev.java, Dev.java: The Destination for Java Developers. Available at: https://dev.java/learn/oop/#package (Accessed: 20 July 2025).
Python Software Foundation (2025) 6. Modules, Python documentation. Available at: https://docs.python.org/3/tutorial/modules.html (Accessed: 20 July 2025).
Valente, M.T. (2024) Software Engineering: A Modern Approach. Self-published. Available at: https://softengbook.org (Accessed: 28 April 2025).