jeudi 30 avril 2015

Design pattern for class with nested generic types

I can't find a good solution for the following problem:

I'm writing a traffic simulator. It should support various types of engines, for example a Queue-based engine and a Cellular Automata-based engine.

The simulator consists of Links and on these Links are Vehicles. Depending on the engine, there can be various properties, that the links and the vehicle need. So i came up with the following design, the abstract classes are the base and implement most of the functionality, the concrete classes do the rest:

public abstract class Vehicle {
    //Implement common logic
}

public abstract class Link<V> where V : Vehicle {
    public List<V> Vehicles {get;set;}
    //Implement common logic
}

public abstract class TrafficSimulator<L,V> where L : Link<V>, V : Vehicle {
    public List<L> Links {get;set;}
    //Implement common logic
}


public class QueueTrafficSimulator : TrafficSimulator<QueueLink<QueueVehicle>, QueueVehicle>> {
    //Implement queue-specific logic
}


public class CATrafficSimulator : TrafficSimulator<CALink<CAVehicle>, QueueVehicle>> {
    //Implement ca-specific logic
}

It works, but I have the feeling that it's too complicated. And it gets even uglier, if I want to use the simulator as a generic parameter for another class (it does work though):

public abstract class FlowBuilder<T,L,V>
        where T : TrafficSimulator<L,V> 
        where V : Vehicle
        where L : Link<V> {

    public T Build() {
        // Do Stuff
        foreach(var link in T.Links) {
            // Do Stuff
            DoInternalStuff(link);
        }
    }
    protected abstract void DoInternalStuff(L link);
}

public class QueueFlowBuilder : FlowBuilder<QueueTrafficFlow, QueueLink, QueueVehicle> {

    protected override void DoInternalStuff(QueueLink link) {
        // Internal setup of QueueLink
    }
}

Do you have any suggestions on how to improve this design? I'm thinking of the classical design pattern but cant find a suitable match for this.

Aucun commentaire:

Enregistrer un commentaire