Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 层架构的最佳实践是什么?_C#_Refactoring_Data Access Layer_Business Logic Layer - Fatal编程技术网

C# 层架构的最佳实践是什么?

C# 层架构的最佳实践是什么?,c#,refactoring,data-access-layer,business-logic-layer,C#,Refactoring,Data Access Layer,Business Logic Layer,现在我正在开发一个用VB6开发的大型银行解决方案。该应用程序大量基于表单,缺乏分层体系结构。所有用于数据访问、业务逻辑和表单操作的代码都在单个表单类中。我现在的工作是重构这段代码。我正在用C编写一个适当的业务逻辑层和数据访问层,表单将保留在VB中 以下是代码片段: public class DistrictDAO { public string Id{get;set;} public string DistrictName { get; set; } public str

现在我正在开发一个用VB6开发的大型银行解决方案。该应用程序大量基于表单,缺乏分层体系结构。所有用于数据访问、业务逻辑和表单操作的代码都在单个表单类中。我现在的工作是重构这段代码。我正在用C编写一个适当的业务逻辑层和数据访问层,表单将保留在VB中

以下是代码片段:

public class DistrictDAO
{
    public string Id{get;set;}
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
    public DateTime SetDate { get; set; }
    public string UserName { get; set; }
    public char StatusFlag { get; set; }
}
地区实体类,为什么它的扩展是DAO,我不清楚

 public class DistrictGateway
{
    #region private variable
    private DatabaseManager _databaseManager;
    #endregion

    #region Constructor
    public DistrictGateway(DatabaseManager databaseManager) {
        _databaseManager = databaseManager;
    }
    #endregion

    #region private methods
    private void SetDistrictToList(List<DistrictDAO> dataTable, int index, DistrictDAO district){
        // here is some code for inserting 
    }    
    #endregion

    #region public methods
        try
        {
        /*
         query and rest of the codes
         */    

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }


    public void InsertDistrict() { 
        // all query to insert object
    }

    public void UpdateDistrict() { 

    }
    #endregion
}
DistrictGateway类负责数据库查询处理 现在是业务层

  public class District
{
    public string Id { get; set; }
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
}


public class DistrictManager
{
    #region private variable
    private DatabaseManager _databaseManager;
    private DistrictGateway _districtGateway;
    #endregion

    #region Constructor
    public DistrictManager() { 
        // Instantiate the private variable using utitlity classes
    }
    #endregion

    #region private method
    private District TransformDistrictBLLToDL(DistrictDAO districtDAO) { 

        // return converted district with lots of coding here
    }

    private DistrictDAO TransformDistrictDLToBLL(District district)
    {

        // return converted DistrictDAO with lots of coding here
    }

    private List<District> TransformDistrictBLLToDL(List<DistrictDAO> districtDAOList)
    {

        // return converted district with lots of coding here
    }

    private List<DistrictDAO> TransformDistrictDLToBLL(List<District> district)
    {

        // return converted DistrictDAO with lots of coding here
    }


    #endregion

    #region public methods
    public List<District> GetDistrict() {
        try
        {
            _databaseManager.ConnectToDatabase();
          return TransformDistrictBLLToDL(  _districtGateway.GetDistrict());

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }
    }

    #endregion
这是业务层的代码

我的问题是:

这是一个完美的设计吗? 如果没有,这里有什么缺陷? 我认为,这段代码带有重复的try-catch块 对于这个实现,什么是好的设计
完美?没有这样的事。如果你不得不在这里问,那可能是错的。即使它现在是完美的,它也不会被时间和熵控制

你做得有多好的衡量标准将在延长的时候到来。如果您的更改顺利进行,那么您做得很好。如果您觉得自己在与遗留代码作斗争以添加更改,请找出错误并重构它

瑕疵?很难说。我现在没有精力、时间或动机去深入挖掘

我不明白你说的3是什么意思

典型的分层如下所示,箭头显示相关性:

view <- controller -> service +-> model <- persistence  (service knows about persistence)
每层都有交叉关注点:

视图了解表示、样式和本地化。它做任何可能的验证来改善用户体验,但不包括业务规则。 控制器与视图紧密相连。它关注来自视图的请求的绑定和验证、路由到适当的服务、错误处理以及路由到下一个视图。就这样。业务逻辑属于服务,因为您希望web、平板电脑、移动设备等的业务逻辑相同。 服务是业务逻辑存在的地方。它担心根据业务规则进行验证,并与模型层和持久层协作以实现用例。它了解用例、工作单元和事务。 如果您更喜欢功能性更强的样式,则模型对象可以是值对象;如果您非常喜欢,则模型对象可以被赋予更丰富的业务逻辑。 持久性隔离了所有数据库交互。
<>你可以考虑安全性、事务、监视、日志记录等交叉方面的问题,如果你使用一个像Spring这样的框架,包括面向方面的编程。

< P>虽然,你并不是真的在这里问一个具体的问题,看起来你可能只是需要一些一般的指导来让你走上正确的道路。由于我们没有像您那样对整个应用程序有深入的了解,所以建议您使用一种方法就够奇怪了

n层体系结构似乎是最近一个流行的问题,但它激发了我写一系列关于它的博客。检查这些问题和博客帖子。我想他们会帮你大忙的

关于N层体系结构的博客系列,带有示例代码


对于一个大型项目,我建议使用MVVM模式,这样您就可以全面测试代码,以后扩展或更改部分代码就容易多了。甚至您也可以更改UI,而无需更改其他层中的代码

如果你的工作是重构代码,那么首先要问你的老板你是否真的应该重构代码或者为代码添加功能。在这两种情况下,您都需要围绕代码进行自动化测试。如果幸运的话,你应该为它添加功能,那么你至少有一个起点和目标。否则,你将不得不自己选择起点,而没有目标。您可以无休止地重构代码。如果没有一个目标,那会很令人沮丧

重构代码而不进行测试会导致灾难。重构代码意味着在不改变其行为的情况下改进其结构。如果你没有做任何测试,你就不能确定你没有弄坏什么东西。由于您需要定期进行大量测试,因此这些测试必须是自动化的。否则,您将花费太多时间进行手动测试

遗留代码很难压入某些测试工具中。您需要修改它以使其可测试。您围绕代码包装测试的努力将隐含地导致代码的某种分层结构

现在有一个母鸡和鸡蛋的问题:你需要重构代码来测试它,但是你现在没有测试。答案是从“防御性”重构技术开始,并进行手动测试。你可以在Micheal Feather的书中找到关于这些技术的更多细节。如果你需要重构很多遗留代码,你应该认真阅读。这真是令人大开眼界

关于你的问题:

没有完美的设计。只有可能更好的。 如果 e应用程序没有任何单元测试,那么这就是最大的缺陷。首先介绍测试。另一方面,这些代码片段并没有那么糟糕。看起来DistrictDAO有点像District的技术版本。也许有人试图引入一些领域模型。并且:至少DistrictGateway将DatabaseManager作为构造函数参数注入。我见过更糟的。 是的,try-catch块可以被视为代码副本,但这并不奇怪。您可以尝试通过合理选择异常类来减少catch子句。或者您可以使用委托或使用一些AOP技术,但这会降低代码的可读性。有关更多信息,请参阅。 将遗留代码放入一些测试工具中。一个更好的设计将悄然出现。 任何方法:首先,澄清你的老板对重构代码的意义。仅仅重构代码而没有目标是没有效率的,也不会让老板高兴。

这里可能会更幸运: