3单层模式的层应用

时间:2012-05-31 08:04:56

标签: c# design-patterns n-tier-architecture

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

- MY BASE CLASS:DAL Class

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;
    }
}

我的业务层类将继承DLL类

- 我的孩子CLASS:BLL CLASS

public class Person : Domain
{
    public string name
    {
        get;
        set;
    }
    public string number
    {
        get;
        set;
    }

    protected override List<object> SaveEntity()
    {
        this.Parameters.Add(name);
        this.Parameters.Add(number);
        return this.Parameters;
    }
}

- 使用 这是使用我的基类

的方法
void Main()
{
    Person p = new Person();
    p.name = "Vijay";
    p.number = "23";
    p.Save();
}

问题

  • 这是我正在遵循的正确架构吗?有没有机会将基类创建为Singleton?
  • 还有其他击球手架构吗?
  • 我可以遵循任何模式来扩展我的功能吗?

请建议。

3 个答案:

答案 0 :(得分:1)

让我们看看。我会尝试提供我的意见。 我在这里看到你要做的是ORM。所以请将基类的名称从Domain更改为其他

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

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

还有其他击球手架构吗?

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

我可以遵循哪些模式来扩展我的功能吗?

始终记住SOLID原则,它为您提供松散耦合并允许轻松扩展。

SOLID

我建议有几处改变。而不是基类,从Interface开始,然后继承它以创建一个抽象类。

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

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

答案 1 :(得分:0)

  

这是我正在遵循的正确架构

对于没有上下文的任何问题,没有最佳的架构。也就是说,你可以做的事情,让你的生活更加困难。 Singleton不是您实施中的问题。

  

还有其他击球手架构吗?

可能,是的。只是瞥见代码,我看到很多东西会在近期而不是不久的将来伤害到你。

首先,一条建议:正确掌握,在你走路之前不要跑步。这可能是downvotes的原因。

一些随机问题:

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

建议阅读:Code Complete表示基本内容,Architecting Applications for the Enterprise表示您可能需要的架构模式。

答案 2 :(得分:0)

根据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
}

新的SQL类是

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;
    }
}

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