Architecture design – How to pass a set of constant in multiple functions?

TL; DR: I need to share a set of read-only parameters in many methods of various objects. I can't use global variables since each simulation can use a different set of those parameters. How should I architecture my code?

I am creating a simulation. I have two (relatively big) objects to define the constraint of the simulation: World (which contains all the assets) and Parameters (which is the list of parameters common for many sub-function of the simulation). In my main(), I load the world, then create a set of parameters, and then run a simulation. Multiple simulations can be run in parallel. For a given simulation, both the world and the simulation parameters will never change (so I can pass both of them by non-mutable reference). Multiple simulations run in parallel can have different words and/or parameters (it's why I'm not using global variable initialized at start-up).

I have 17 functions and methods that takes both a &World and a &Parameters as argument. This doesn't feel like the right design. This is especially annoying since I can't implements traits like From or Index since such operation needs to be able to access to the word and the simulation parameters.

fn main() {
    let mut world = World::load_from_disk();
        let parameters = Parameters::ask_the_user();

        // Between simulation, the parameters and the world can change.
        // Simulation can also be run in parallel.
        run_simulation(&world, &parameters);

// In a given simulation, neither the world nor the parameters changes
pub fn run_simulation(world: &World, params: &params) {
    let mut state = State::new(wold, params);
    for _ in params.number_of_iterations() {
        // Create new component based on the previous state.

        // Many/most of the intermediates states need to access to both
        // the world and the paramaters.
        let a = component_A::new(world, params, &state).do_stuff(world, params);
        let b = component_B::new(world, params, &state).compute_other_stuff(world, params);

        // I would like to ensure that only objects created with the same
        // world and parameters could be assembled together.
        state = assemble(a, b);

    // Here I would have liked to be able to use `state.into()`
    let text = convert_to_textual_representation(world, params, state);

My first impression is that I should add those &Word and &Parameters to the object being manipulated, but I'm not sure it's the right idea since there are about 10 different objects. If possible, it would also be nice to make it impossible to assemble() multiple components that were not created using the same set of parameters.

You’re already passing World and Parameters into State::new; can State provide accessors to them that the other objects use?

Currently neither &World, nor &Parameters are stored in any objects. I could add both of them to State (that's reasonable), but would solve the issue for about half of the function. The other functions and object don't know anything about what a State is, and I wouldn't like to introduce coupling. I still think I will try this as a first step.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.