【问题标题】:Access problems using the Factory Pattern on C#在 C# 上使用工厂模式访问问题
【发布时间】:2019-04-11 11:44:14
【问题描述】:

我是模式的新手,我开始研究工厂模式来做几何图形的练习。

这是我的代码:

namespace MyNameSpace
{
    class MainApp
    {
        static void Main(string[] args)
        {
            //Problem: I can't access to 
            //the Cube() builder because it's private.
            GeometricFigure cube = new Cube(); 

            Console.WriteLine("Blablabla");
            Console.ReadLine();

        }
    }
}

这是我实现工厂模式的“创建者”方法

public abstract class GeometricFigure
{
    private float Dimension { get; set; }
    private float Coordinate_X { get; set; }
    private float Coordinate_Y { get; set; }
    private float Coordinate_Z { get; set; }

    public GeometricFigure()
    {
        CreateFigure();
    }

    //Factory method
    public abstract void CreateFigure();
}

这是我的“ConcrateCreator”课程

class Cube : GeometricFigure
{
    public override void CreateFigure() 
    {
        new Cube(); 
    }
}

我认为我的代码很好......但是......我不明白为什么 Cube 类是私有的。综上所述,公开Cube类是否正确?如果答案不是...如果 Cube 类是私有的,我如何从 Main 方法实例化多维数据集对象? :(

提前感谢大家。

艾玛。

【问题讨论】:

  • 当你没有指定访问修饰符时,你的 Cube 类实际上是 internal。如果您希望它可以在其程序集之外访问,那么您必须将其设置为公开。
  • 您希望new Cube(); 行做什么?
  • 这里有一个很好的例子来说明如何正确实现工厂模式:dofactory.com/net/factory-method-design-pattern
  • 我认为你应该在设计模式之前学习OOP。整个设计模式方法基于 OOP。您还可以检查访问修饰符docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
  • 您的模式应该返回您创建的实例。它不应该是无效的

标签: c# design-patterns factory


【解决方案1】:

正如人们所提到的,C# 中类的默认访问修饰符是Internal,这使得您的类只能在它们声明的同一个程序集中访问。此外,您将要创建的对象与实际工厂混合。工厂是创建对象的单独实例。假设你有这个抽象:

public abstract class GeometricFigure
{
    public float Dimension { get; set; }
    public float Coordinate_X { get; set; }
    public float Coordinate_Y { get; set; }
    public float Coordinate_Z { get; set; }
}

以及派生类:

    public class Triangle: GeometricFigure
    {
        public float Dimension { get; set; }
        public float Coordinate_X { get; set; }
        public float Coordinate_Y { get; set; }
        public float Coordinate_Z { get; set; }
    }

然后你想创建一个应该创建实例的工厂:

public abstract class GeometricFigureFactory
{
   public abstract GeometricFigure Create();
}

以及这个工厂的具体实现:

    public class TriangleFactory: GeometricFigureFactory
    {
        public override GeometricFigure Create()
        {
            return new Triangle();
        }
    }

及用法:

    public class Program
    {
        public static void Main()
        {
            var factory = new TriangleFactory();

            var triangle = factory.Create();
        }
    }

这种模式的优点是每次需要添加继承自GeometricFigure 的新实例时都不会违反打开关闭原则。您只需创建一个扩展 GeometricFigureFactory 的新工厂。此外,您可以多态地使用工厂和GeometricFigure 实体

附:将您的私有 getter 和 setter 更新为公开,因为它们已经封装了私有字段

【讨论】:

  • 这应该是公认的答案。我只想补充一点,这是抽象工厂模式,而不是工厂方法模式,后者更简单,在许多情况下都是可行的方法。如果您试图全面了解工厂模式,则尤其如此。在这种情况下,工厂类看起来像这样:public static class GeometricShapeFactory { public static Triangle CreateTriangle() { return new Triangle(); } } 和 Main 将是 public static void Main() { var triangle = GeometricShapeFactory.CreateTriangle(); }
  • @crazy_crank 我个人不喜欢static,因为不可能伪造单元测试的行为。如果需要,您可以随时将工厂注册为单例
【解决方案2】:

您有两种可能的解决方案。

  1. 公开多维数据集。

  2. 使用另一个公共类的工厂方法在同一个命名空间中创建它。

【讨论】:

    【解决方案3】:

    在您的代码中,您直接调用抽象类。也许在做

    Cube cube = new Cube();
    

    而不是

    GeometricFigure cube = new Cube();
    

    会有所作为。

    以下链接还提供了许多有关工厂模式的有用信息: https://www.c-sharpcorner.com/article/factory-method-design-pattern-in-c-sharp/

    https://www.youtube.com/watch?v=EcFVTgRHJLM

    希望这些对您有所帮助,如果没有,希望能进一步帮助您!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多