This is not a formal blog entry for this post but just a musing about my own poor design choices after reviewing some of the material for this course.
My web app: quaildata.app
…. was my first serious attempt at creating a web app with some complexity. I learnt a lot of to do’s and don’t’s.
The structure of my website in the beginning used two SQL tables called <<poultry>> and <<batch>> to signify a batch of quails or an individual bird.
The only difference were the following added fields (in <<batch>>):
- is_batch: Boolean
- total_incubated: Int
- total_hatched: Int
- dead_birds: Int
And the following added fields (in <<poultry>>):
- sex: Boolean
- alive: Boolean
- batch: Int
- tag: Int
- culled: Timestamp
Here is a UML diagram of the original system tables:
This is a poor design as there is because the <<batch>> schema has multiple roles:
- A source of data about quail batches
- Forms a relational link with <<poultry>> (tight coupling)
- Forms a dependency as well as an inheritance
As you can see “batch is a batch” but “poultry is part of a batch”. This makes the programming difficult because the roles of each class are not defined and do not follow the “single responsibility principle”.
This design pattern breaks the SOLID design principals. Numbers 1, 2, and 3:
- Single responsibility principle: One class should have only a single responsibility.
- Open-closed principle: Components (classes, methods, etc.) should be open for extension but closed for modification.
- Liskov’s substitution principle: Derived types must be completely substitutable for their base types.
- Interface segregation principle: Clients should not be forced to depend upon the interfaces they do not use.
- Dependency inversion principle: Program to an interface, not to an implementation.
I actually rewrote the website to rely on a single table <<poultry>> with an extra row called “is_batch”. This was an attempt at polymorphism but still failed the first rule of SOLID.
Here is a class diagram to show roughly how that worked.
As you can see the design still overloads the measurement table which breaks the first rule of SOLID.
I have redesigned the system in UML form to better conform to SOLID design principals:
In this new design the following improvements have been made:
- Animal now inherits from Stock which allows Stock to have as little attributes as possible
- Animal can now have a type allowing the program to be expanded to handle more types of animals
- language used in general to allow for birds/mammals and other animals
- Loose coupling is made between measurement class
- Measurements can now have unlimited fields as measurements are referred to as a UUID rather than an ID.
- Measurement types are unlimited as well due to types being implemented for them
After building a few projects I can definitely see the importance of OOP and SOLID design principals. I will be creating an Anki deck to cement the concepts better.
I am at the early stages of studying for this certification but can already see the usefulness of the subjects taught.