Open MarkLai0317 opened 2 months ago
Actually, when I was working on this project, ChatGPT suggested using the Visitor pattern many times. However, I’m not really familiar with it.
Is that possible to use UML to show what the changes would look like? Especially about the decouple of Environment and Organism.
Here is the uml to demonstrate the result of refactoring. the add
and remove
is changed to accept EnvironmentObject instead of Food and Organism.
The EnvironmentObjectGetter
is what others call Visitor
and getObject is what's called visit
in visitor pattern.
Visitor pattern can do a lot more than just get. But I currently only use it on Getter. Other usage can be discussed in the future
For the deadOrganism. I suggest we can add variable to Organism to indicate dead. Or is there a reason we need to store them in a different vector ?
This approach decouples Environment
from different EnvironmentObject
implementations, which is beneficial for adding new features.
However, two points should be considered:
getObject
and Getters
might not be intuitive for scripting.EnvironmentObjects
, how will they manage their interactions?The deadOrganism
vector is important for the simulation, and I included it for convenience. However, adding a status attribute to organisms might be a good alternative since iterating through all organisms to find the dead ones is not very intensive.
Maybe we could add another discussion or refactor issue to talk about this.
Another approach is to only use a getObject method that accept a filter lambda function that get what the user want, such as id or class name. we can make the EnvironmentObject constructor set a attribute string that is equal to the class name.
This way, user can easily customize the filter without exposing too many complex things. They just need to implement a simple boolean function. And this can adapt to complex EnvironmentObject that has custom attribute defined by users.
Can you provide some syntax for me to better understand what it will look like?
I have redesign the getObject method that accept a custom filter which accept a EnvironmentObject
pointer and return a vector that satisfy the custom filter.
This will not expose too much things to users. and it's quite common for python scripting like below.
my_list = [12, 65, 54, 39, 102, 339, 221, 50, 70]
# use anonymous function to filter and comparing
# if divisible or not
result = list(filter(lambda x: (x % 13 == 0), my_list))
potential recurrent problem: the
Environment
is coupled withFood
andOrganism
, which will limit the scalability if there are new child ofEnvironmentObject
orFood
,Organism
. That is, we need to add newgetFunction
or new map inEnvironment
.solution: I suggest we can apply visitor pattern so that we can add different getter without hard coding
FoodAllFoods
,getAllOrganism
. That is, we can define different getter and use it as parameter in the one and onlygetEnvironmentObject(getterFilter)
.Expected result: Environment only depend on
EnvironmentObject