简体   繁体   中英

Factory pattern implementations with different parameters

I am trying to make a factory that creates classes that use the same base class(or interface) but the concrete factories need different parameter sets. If feel like I'm doing something wrong since these different Enums require extra code. Could this be done better?

Classes to be created:

public interface IShapeData {}

public abstract class ShapeDataWithCorners : IShapeData
{
    public double Width { get; set; }
}

class Square : ShapeDataWithCorners {}

class Rectangle : ShapeDataWithCorners
{
    public double Height { get; set; }
}

class Circle : IShapeData
{
    public double Radius { get; set; }
}

class Oval : IShapeData
{
    public double Radius1 { get; set; }
    public double Radius2 { get; set; }
}

Factories:

public enum RoundShapeTypes
{
    Circle,
    Oval
}

public enum CornerShapeTypes
{
    Square,
    Rectangle
}

public class RoundShapeDataFactory : IShapeDataFactory
{
    private readonly RoundShapeTypes m_shapeType;

    public RoundShapeDataFactory (RoundShapeTypes shapeType)
    {
        m_shapeType = shapeType;
    }

    public IShapeData CreateShapeData ()
    {
        switch (m_shapeType)
        {
            case RoundShapeTypes.Circle:
                return new Circle ();
            case RoundShapeTypes.Oval:
                return new Oval ();
        }
    }
}

public class CornerShapeDataFactory : IShapeDataFactory
{
    private readonly CornerShapeTypes m_shapeType;

    public CornerShapeDataFactory (CornerShapeTypes shapeType)
    {
        m_shapeType = shapeType;
    }

    public IShapeData CreateShapeData ()
    {
        switch (m_shapeType)
        {
            case CornerShapeTypes.Square:
                return new Square ();
            case CornerShapeTypes.Rectangle:
                return new Rectangle ();
        }
    }
}

Classes that call the factory:

public class RoundShapeManager
{
    public IShapeData CurrentShapeData{get; set; }

    public void SetShapeType (RoundShapeTypes shapeType)
    {
        RoundShapeDataFactory factory = new RoundShapeDataFactory (shapeType);
        CurrentShapeData = factory.CreateShapeData ();
    }
}

public class CornerShapeManager
{
    public IShapeData CurrentShapeData {get; set; }

    public void SetShapeType (CornerShapeTypes shapeType)
    {
        CornerShapeDataFactory factory = new CornerShapeDataFactory (shapeType);
        CurrentShapeData = factory.CreateShapeData ();
    }
}

These "managers" are actually WPF viewmodels that will can change their representative displayed data at run-time. I removed the viewmodel specific code for brevity.

You can reduce it to this:

public interface IShapeData { }

public abstract class ShapeDataWithCorners : IShapeData
{
    public double Width { get; set; }
}

public class Square : ShapeDataWithCorners { }

public class Rectangle : ShapeDataWithCorners
{
    public double Height { get; set; }
}

public class Circle : IShapeData
{
    public double Radius { get; set; }
}

public class Oval : IShapeData
{
    public double Radius1 { get; set; }
    public double Radius2 { get; set; }
}

public enum ShapeType
{
    Circle,
    Oval,
    Square,
    Rectangle
}

public interface IShapeDataFactory
{
    IShapeData CreateShapeData(ShapeType shapeType);
}

public class ShapeDataFactory : IShapeDataFactory
{
    public IShapeData CreateShapeData(ShapeType shapeType)
    {
        switch (shapeType)
        {
            case ShapeType.Circle:
                return new Square();
            case ShapeType.Oval:
                return new Oval();
            case ShapeType.Rectangle:
                return new Rectangle();
            case ShapeType.Square:
                return new Square();
            default:
                throw new ArgumentException("invalid shape type");
        }
    }
}

So one factory, one enum with all shape types, and you can have a single manager that basically does this:

IShapeDataFactory s = new ShapeDataFactory();
IShapeData temp = s.CreateShapeData(ShapeType.Square);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM