architecture - 我的业务逻辑应该如何与我的数据层交互?

标签 architecture

所以我正在制作我的程序的草稿。

这是我的计划:

GUI
---
Business Logic
---
Data

您应该可以替换 GUIData层没有问题。
每一层都在观察自己。所以GUI将从 Business logic 调用方法并且这些方法将始终返回一个状态,也许还有一些数据。 GUI 应如何响应数据,应始终在 GUI 层中决定。业务逻辑应该对此没有影响。
这样就解决了GUI和业务逻辑的关系。
我希望你能关注我。

现在来说点更具体的东西。
我对数据层的计划是使用数据库。
现在,业务逻辑应该如何从数据层调用方法?

也许我应该创建一个枚举,对应于数据层知道的不同硬编码 SQL 查询?

例如。
Datalayer.GetResults(Queries.GetAllCustomersIDs);

查询是一个枚举。

如果这是正确的方法,GetResults 应该返回什么?一个字符串数组?但是如果查询有多维数据怎么办?

那么我应该有2个通用方法吗?
Datalayer.GetSingleDimensionResults(SingleDimensionQueries.GetAllCustomersIDs);
Datalayer.GetMultipleDimensionResults(MultiDimensionQueries.GetAllCustomers);

或者我是否应该对每种数据请求进行查询?
Datalayer.GetAllCustomerIDs;
DataLayer.GetAllCustomers;

等等

最佳答案

一般来说,我用来做的是:

数据层:

对于数据访问,我为每个对象创建一个接口(interface)。每个接口(interface)都列出了相关对象的所有公共(public)数据访问方法。为了保存数据,我也为每个对象创建了容器类型,它可以是结构或仅包含数据的简单类。我还依赖语言数据集(如列表)来保存我的数据,因此我没有链接到特定的数据库类型。之后,我创建了一个实现数据接口(interface)的类,这个类有所有的SQL和访问数据库,所以如果数据存储技术发生变化,这是唯一会改变的类。

业务层:

是否包含数据的所有逻辑,如何验证,应该调用数据接口(interface)中的哪些方法以及调用顺序。此类使用容器(例如列表)接收数据并将数据“发送”到数据存储或 GUI,其中数据类型是我上面提到的容器。

图形用户界面:

调用业务逻辑方法并显示/格式化数据表示。除了调用业务逻辑的正确方法之外,这里没有其他逻辑。

容器的小代码示例 (C#)

    //Interface for Department class data access. DataStorage assembly

    namespace DataStorage
    {
        public interface IDepartmentDS
        {
            void Open();  //Open data conection
            void Close(); //Close data conection
            List<Repositories.Department> List(); //Gets all departments (from data base)
        }
    }


    //This class holds all data regarded a department. There's no logic here. Repositories assembly

    namespace Repositories
    {
        public class Department
        {
            [Browsable(false)]
            public Department()
            {
            }

            [Browsable(false)]
            public Department(String Symbol, String Name)
            {
                this.Symbol = Symbol;
                this.DeptName = Name;
            }

            public Department(Department department)
            {
                this.Symbol = department.Symbol;
                this.DeptName = department.DeptName;
            }

            [Browsable(false)]
            public String Symbol { get; set; }

            public String DeptName { get; set; }
        }
    }


    //This class implements the data manipulation itself, accessing the real database.
    //However the data exchange outside this class is done via repositories classes and 
    //Generics - Lists mainly

    public class DataStorage : IDepartmentDS
    {
       //Here I use to put generic functions to connect with the database, format stored
       //procedure parameters list etc.

       //Implementation of the List method declare in the Department Interface
           List<Repositories.Department> IDepartmentDS.List()
            {
                String query = String.Format("SELECT * FROM {0}", DepartmentTable);
                int rows = 0;
                DataSet ds = ExecSqlCommand(query, out rows); //this method is private to this class

                if (ds == null)
                    return null;

                List<Repositories.Department> list = new List<Repositories.Department>();
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    list.Add(new Repositories.Department((String)row[DepFN_Symbol], (String)row[DepFN_DepName]));
                    //DepFN_Symbol and the others are just const variables representing the column index
                }

                return list;
            }

    }

public class DepartmentLogic
{
   public DepartmentLogic()
   {
      .....
   }

   public List<Repositories.Department> GetAllDepartments()
   {
      //Here I create an Instance of the DataStorage but using the Department interface
      //so I restrict the access to Department data methods only. It could be a good 
      //idea here to use the factory pattern.

      IDepartmentDS department = (IDepartmentDS) new DataStorage();
      department.Open();

      List<Repositories.Department> departments = department.List();

      department.Close();

      return departments;
   }

}

这个业务逻辑示例确实非常简单,只是展示了如何从存储层检索数据,但只要您可以访问数据,就可以按照您想要的方式对其进行操作。这里只是一个评论:如果在具有数千个请求的非常繁忙的服务器中实现这个解决方案,也许应该重新考虑这个解决方案,因为它可以使用大量内存。

对于业务逻辑和 UI 观点,所有数据都使用通用容器(如列表)在模块之间进行通信。所有这些模块之间的链接点是容器类,因此所有类的解耦都不太好。

UI 向业务逻辑类发出请求,因此它就像一个服务提供者。这样做,更改 UI 不会影响下面的类。

业务逻辑使用通用数据请求数据并将数据发送到数据存储类,因此更改数据库/存储技术不应影响它。

这就是我过去的方式,我正在努力改进它;)

关于architecture - 我的业务逻辑应该如何与我的数据层交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1782325/

相关文章:

database - 为什么 DBMS 需要守护进程?

entity-framework - WCF 数据服务实现策略

asp.net-mvc - 我在哪里放置我的 View 模型验证?

java - 将Java代码组织到包中等于架构模式/风格吗?

c# - 两种方式通信的服务器/客户端架构?

c++ - 解决代码中模块之间的相互依赖

html - CMS 中搜索表单的 POST 与 GET 方法

c++ - 用c++解析海量数据

php - 数据库工作的组织

iphone - iOS 客户端 : "Caching" Server-side data to persistent storage