jeudi 17 octobre 2019

How do I avoid duplicate code while parsing two different objects from a file?

I want to parse a csv file looking like below. The CSV file contains two different types: Planet and Asteroid. Both these types have some unique properties. enter image description here

I created a Planet class and an Asteroid class which both inherit from the abstract SpaceObject class. I created a Parser class that parses my csv file into a list of SpaceObjects. Unfortunately, my class contains duplicate code, and that's what I am trying to avoid.

My code:

switch (ReadStringFromCellBasedOnHeader("type"))
                    {
                        case "Asteroid":
                            var asteroid = new Asteroid();
                            asteroid.Position = new Vector2D(ReadDoubleFromCellBasedOnHeader("x"), ReadDoubleFromCellBasedOnHeader("y"));
                            asteroid.Speed = new Vector2D(ReadDoubleFromCellBasedOnHeader("vx"),ReadDoubleFromCellBasedOnHeader("vy"));
                            asteroid.Radius = ReadDoubleFromCellBasedOnHeader("radius");
                            asteroid.Color =
                                (Color?) ColorConverter.ConvertFromString(ReadStringFromCellBasedOnHeader("color")) ?? Color.FromRgb(0, 0, 0);
                            break;
                        case "Planet":
                            var planet = new Planet();
                            planet.Name = ReadStringFromCellBasedOnHeader("name");
                            planet.Position = new Vector2D(ReadDoubleFromCellBasedOnHeader("x"), ReadDoubleFromCellBasedOnHeader("y"));
                            planet.Speed = new Vector2D(ReadDoubleFromCellBasedOnHeader("vx"), ReadDoubleFromCellBasedOnHeader("vy"));
                            planet.Neighbours.AddRange(ReadStringFromCellBasedOnHeader("neighbours").Split(','));
                            planet.Radius = ReadDoubleFromCellBasedOnHeader("radius");
                            planet.Color =
                                (Color?)ColorConverter.ConvertFromString(ReadStringFromCellBasedOnHeader("color")) ?? Color.FromRgb(0, 0, 0);
                            break;
                        default:
                            throw new Exception("Unknown SpaceObject Type");
                    }

                    string ReadStringFromCellBasedOnHeader(string header)
                    {
                        return fields[columnDictionary[header]];
                    }

                    double ReadDoubleFromCellBasedOnHeader(string header)
                    {
                        return StringConverter.ToDouble(ReadStringFromCellBasedOnHeader(header));
                    }

As you can see my Planet and Asteroid object are exactly the same, besides that Planet contains two unique properties (name and neighbours). I was thinking about using the Factory or Builder pattern, but I don't want to create a function with nine parameters. How can I avoid this duplicate code in an elegant way?

Aucun commentaire:

Enregistrer un commentaire