C# 具有单例模式的3层应用程序

C# 具有单例模式的3层应用程序,c#,design-patterns,n-tier-architecture,C#,Design Patterns,N Tier Architecture,我正在创建一个具有以下模式的三层WinForm应用程序 --我的基类:DAL类 public class Domain { public string CommandName = string.Empty; public List<Object> Parameters = new List<Object>(); public void Save() { List<Object> Params = thi

我正在创建一个具有以下模式的三层WinForm应用程序

--我的基类:DAL类

public class Domain
{

    public string CommandName = string.Empty;
    public List<Object> Parameters = new List<Object>();

    public void Save()   
    {
        List<Object> Params = this.SaveEntity();
        this.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Delete() 
    {
        List<Object> Params = this.DeleteEntity();
        this.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Update() 
    {
        List<Object> Params = this.UpdateEntity();
        this.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    protected virtual List<Object> SaveEntity()
    {
        return null;
    }
    protected virtual List<Object> UpdateEntity()
    { 
        return null;
    }
    protected virtual List<Object> DeleteEntity()
    {
        return null;
    }

    public int ExecuteNonQuery(string SqlText, params object[] Params)
    {
        /*
         * Code block for executing Sql
         */
        return 0;
    }
}
问题

void Main()
{
    Person p = new Person();
    p.name = "Vijay";
    p.number = "23";
    p.Save();
}
  • 这是我遵循的正确体系结构吗?是否有机会将基类创建为Singleton
  • 还有其他的batter架构吗
  • 有什么模式可以扩展我的功能吗

请建议。

让我们看看。我会尽力提供我的意见。 我在这里看到你试图做的是ORM。因此,请将基类的名称从域更改为其他名称

这是我遵循的正确体系结构吗?是否有机会将基类创建为Singleton?

为什么你需要你的基类作为单身。您将继承基类并创建子类的实例。您永远不会创建base本身的实例。(99%的次数:)

是否还有其他batter架构?

明白这一点。要做某件事,可能有多种方法。事实上,哪一个最适合你

有什么模式可以扩展我的功能吗?

始终记住坚实的原则,它使您能够松耦合并允许轻松扩展

我建议做一些改变。不是基类,而是从接口开始,然后继承它以生成一个抽象类

还要确保基类可以完成所有CRUD功能。我在这里看不到检索功能。你打算怎么做?您可能需要一个返回应用程序所有实体的存储库类。所以,当您需要person时,您可以继续要求存储库返回所有person

总之,有很多ORM工具可以实现这种功能并节省开发人员的时间。学习这些技术更好。例如LINQ-SQL

这就是我所遵循的架构吗

没有哪种体系结构可以在没有上下文的情况下对任何问题进行优化。也就是说,你可以做一些事情让你的生活变得更加困难。在您的实现中,单例不是您的问题

还有其他的batter架构吗

可能是的。只要看一眼代码,我就会发现很多东西会在不久的将来伤害到你

首先,一条建议:正确掌握基本知识,在你能走路之前不要跑。这可能是投反对票的原因

一些随机问题:

  • 您所说的是3层体系结构,但从技术上讲,这里没有层,甚至没有层
    Person
    在我看来不像业务逻辑:如果我理解正确,它还必须提供要执行的命令的字符串,因此它必须知道SQL
  • 空的虚拟方法应该是抽象的。如果希望能够执行任意SQL,请将其移到类之外
  • 正如@Anand指出的,没有可以查询的方法
  • CommandName和参数作为字段而不是属性公开
  • CommandName不是一个名称,Domain看起来不适合该类
  • 它看起来像是一个著名问题(ORM)的笨拙解决方案。您说您希望能够执行自定义SQL,但任何像样的ORM都应该能够让您这样做

建议阅读:对于基本内容和您可能需要的架构模式的一些清晰性。

正如Anand所建议的,我从基类中删除了所有与SQL相关的函数,并将它们全部放在另一个类中,
SQL

接下来,我将
Sql
类变成了一个单例。我将
Sql
实例存储在
BaseDAL
中,因此它可以在所有DAL类中访问

我的代码看起来像这样

public class BaseDAL
{
    // Singleton Instance
    protected Sql _dal = Sql.Instance;

    public string CommandName = string.Empty;
    public List<Object> Parameters = new List<Object>();

    public void Save()   
    {
        List<Object> Params = this.SaveEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Delete() 
    {
        List<Object> Params = this.DeleteEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Update() 
    {
        List<Object> Params = this.UpdateEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    protected virtual List<Object> SaveEntity()
    {
        return null;
    }
    protected virtual List<Object> UpdateEntity()
    { 
        return null;
    }
    protected virtual List<Object> DeleteEntity()
    {
        return null;
    }

   // Other functions, like DataTable and DataSet querying
}

CommandName
参数
作为字段而不是属性公开。在原始解决方案中,它们是属性。另外,我在BaseDAL中有一个查询数据的方法,以帮助实现
Person
类。

所以his的问题是他缺少第四个?3轮胎结构。。。听起来像:)代码审查或程序员的候选人?@Seki我同意你的编辑,但你毁了这个笑话:-)我的朋友,你提出的代码有很多问题,我不知道从哪里开始…第一点。。。我想要和singleton一样,不是因为子类,而是因为其他实体。就像您查看我的代码一样,我提到了与执行sql过程和文本相关的函数(ExecuteNonQuery/ExecuteDataTable/ExecuteScaler/ExecuteDataSet)。所以,所有其他不继承基类的实体都可以访问数据层,因为在演示中,我们需要执行一些自定义代码。对于数据重试,我总是使用datatable并用该表填充UI。我从不使用类对象来填充我的UI。我不太喜欢ORM,因为它们总是需要列映射。而且,如果我们想在数据库上做一些自定义操作,那么在ORM中会更加困难。使用sql存储过程也可以很容易地实现这一点。我认为您应该将sql助手函数分离到另一个类中,并使其成为静态的。这是我所说的可靠原则之一(单一责任)。对于检索,您使用DataTable,但我想问的是,您在哪里调用此代码。您可以看到创建、更新和删除功能仅驻留在对象中。检索部分应该放在哪里?这就是为什么我建议您创建一个名为repository的公共类,然后返回应用程序的所有实体。比如Repository.GetPerson()
public class BaseDAL
{
    // Singleton Instance
    protected Sql _dal = Sql.Instance;

    public string CommandName = string.Empty;
    public List<Object> Parameters = new List<Object>();

    public void Save()   
    {
        List<Object> Params = this.SaveEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Delete() 
    {
        List<Object> Params = this.DeleteEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    public void Update() 
    {
        List<Object> Params = this.UpdateEntity();
        _dal.ExecuteNonQuery(CommandName, Params.ToArray());
    }

    protected virtual List<Object> SaveEntity()
    {
        return null;
    }
    protected virtual List<Object> UpdateEntity()
    { 
        return null;
    }
    protected virtual List<Object> DeleteEntity()
    {
        return null;
    }

   // Other functions, like DataTable and DataSet querying
}
public class Sql
{

    // All other functions are also present in this class for DataTable DataSet and many other 
    // So this class is more then enough for me.
    public int ExecuteNonQuery(string SqlText, params object[] Params)
    {
        // Code block for executing SQL
        return 0;
    }
}