1
\$\begingroup\$

There are my shapes (for example):

public abstract class Shape
{
  protected int _id;
  protected string _description;

  public abstract string ToXml();
}

public sealed class Triangle : Shape
{
  public int TriangleId { get { return _id; } set { _id = value; } }
  public string TriangleDescription { get { return _description; } set { _description = value; } }
  public ConsoleColor color { get; set; }

  public override string ToXml()
  {
    // First implementation
    throw new NotImplementedException();
  }
}

public sealed class Circle : Shape
{
  public int CircleId { get { return _id; } set { _id = value; } }
  public string CircleDescription { get { return _description; } set { _description = value; } }
  public int Radius { get; set; }

  public override string ToXml()
  {
    // Second implementation
    throw new NotImplementedException();
  }
}

public sealed class Square : Shape
{
  public int SquareId { get { return _id; } set { _id = value; } }
  public string SquareDescription { get { return _description; } set { _description = value; } }
  public int Edge { get; set; }

  public override string ToXml()
  {
    // Third implementation
    throw new NotImplementedException();
  }
}

Client have to choose one kind of shape to get xml-view:

public enum ShapeType
{
  Triangle,
  Circle,
  Square
}

public class Module
{
  public string GetXml( ShapeType type, int id )
  {
    switch( type )
    {
      case ShapeType.Circle:
        return DB.GetEntity( id ).ToTypedEntity<Circle>().ToXml();
      case ShapeType.Square:
        return DB.GetEntity( id ).ToTypedEntity<Square>().ToXml();
      case ShapeType.Triangle:
        return DB.GetEntity( id ).ToTypedEntity<Triangle>().ToXml();
    }
  }
}

As you can see, there are too much the same code parts that are matching enumerations with shape's types. It is not good.

How can I avoid it?

\$\endgroup\$
5
  • 2
    \$\begingroup\$ I don't know C# much, but do you really have to redefine the getters and setters for id and description? \$\endgroup\$
    – toto2
    Commented Aug 28, 2013 at 15:38
  • \$\begingroup\$ Also, how does the DB work? Is there a different table for each type? It seems dangerous to have the user ask for both the type and the id since they might be inconsistent. Only asking for the id should be enough (?). \$\endgroup\$
    – toto2
    Commented Aug 28, 2013 at 15:42
  • \$\begingroup\$ I came up with this code for example. It is not real code. \$\endgroup\$
    – FireShock
    Commented Aug 29, 2013 at 7:03
  • \$\begingroup\$ Public methods marked AOP aspects that are checking permissions. \$\endgroup\$
    – FireShock
    Commented Aug 29, 2013 at 7:46
  • \$\begingroup\$ And yes, each type has different table. \$\endgroup\$
    – FireShock
    Commented Aug 29, 2013 at 7:50

2 Answers 2

1
\$\begingroup\$

Just expose the class types to the user (which they already appear to be) rather than forcing them to use a gawd-awful enum.

public class Module
{
  public string GetXml<TShape>( int id ) where TShape : Shape
  {    
    return DB.GetEntity( id ).ToTypedEntity<TShape>().ToXml();    
  }
}

The the user can just make a normal call like

new Module().GetXml<Triangle>(34);
\$\endgroup\$
1
  • \$\begingroup\$ Might need to add a where TShape : Shape onto the end of the method declaration. \$\endgroup\$ Commented Aug 28, 2013 at 15:26
0
\$\begingroup\$

I would consider decoupling the Xml serialization from the entity objects. The Xml serialization namespace gives you very fine grained control over how an object is represented in Xml plus a lot fo built in functionality that you do not need to reinvent.

The advantages of this decoupling is that your Shape object hierarchy implementations become smaller, you get better on single responsibilty for the shape objects.

public class Module
{
  public string GetXml<TShape>( int id ) where TShape : Shape
  {   
        XmlSerializer ser = new XmlSerializer(typeof(TShape));
        StringBuilder builder = new StringBuilder();
        using(StringWriter sww = new StringWriter(builder))
        using (XmlWriter writer = XmlWriter.Create(sww))
            ser.Serialize(writer, DB.GetEntity( id ).ToTypedEntity<TShape>());
        return builder.ToString(); // Your xml   
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.