我的业务逻辑应该如何与我的数据层交互? [英] How should my business logic interact with my data layer?

查看:25
本文介绍了我的业务逻辑应该如何与我的数据层交互?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm working on making a draft of my program.

这是我的计划:

GUI
---
Business Logic
---
Data

您应该能够毫无问题地替换 GUIData 层.每一层都在监视自己.所以GUI 将调用来自业务逻辑 的方法,这些方法将始终返回一个状态和一些数据.GUI 应如何响应数据,应始终在 GUI 层中决定.业务逻辑不应对此产生影响.这样GUI和业务逻辑的关系就解决了.希望你能关注我.

You should be able to replace either GUI or the Data layer without issues. Every layer watches itself. So GUI will call methods from Business logic and the methods will always return a status and perhaps some data. How the GUI should respond to the data, should always be decided in the GUI layer. Business logic should have no influence over this. So the relations with GUI and business logic has been solved. I hope you can follow me.

现在来做更具体的事情.我对数据层的计划是使用数据库.现在,业务逻辑应该如何从数据层调用方法?

Now for something more concrete. My plan for the data layer, is to use an database. Now, how should Business Logic call methods from the data layer?

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

Perhaps I should make an enum, that corresponds to different hardcoded SQL queries, which the data layer is aware of?

例如

Datalayer.GetResults(Queries.GetAllCustomersIDs);

查询是一个枚举.

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

If this is the right way, what should GetResults return? a string array? but what if the query has multidimensional data?

那么我应该有 2 个泛型方法吗?

Should I then have 2 generic methods instead?

Datalayer.GetSingleDimensionResults(SingleDimensionQueries.GetAllCustomersIDs);
Datalayer.GetMultipleDimensionResults(MultiDimensionQueries.GetAllCustomers);

或者我应该对每种数据请求进行查询吗?

Or should I perhaps have a query for each kind of data request?

Datalayer.GetAllCustomerIDs;
DataLayer.GetAllCustomers;

推荐答案

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

In general, what I use to do is:

数据层:

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

For data access, I create an Interface, for each object. Each interface lists all the public data access methods for the object in question. To hold the data, I create container types, for each object as well, which can be structs or simple classes only with data. I also rely on language data set, like lists, to hold my data, so I not linked to a particular database type. After that, I create a class that implements the data interfaces, this class has all SQL and access the database, so in case of change in the data storage technology, this is the only class that will be changed.

业务层:

处理数据的所有逻辑,如何验证,应调用数据接口中的方法以及调用顺序.此类使用容器(例如列表)接收和发送"数据到数据存储或 GUI,其中数据类型是我上面提到的容器.

Does all the logic with data, how to validate, wich methods from the data interfaces should be called and in which order. This class receives and "send" data to the data storage or GUI, using containers (lists for example) where the data types are my containers mentioned above.

界面:

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

Calls business logic methods and show / format data presentation. There's no logic here other than call the right methods of the business logic.

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

Small code example of a container (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;
   }

}

这个业务逻辑的例子,确实很简单,只是展示了如何从Storage层检索数据,但是只要你能访问到数据,你就可以按照你想要的方式操作它.只是在这里发表评论:如果在具有数千个请求的非常繁忙的服务器中实施该解决方案,可能应该重新考虑该解决方案,因为它可以使用大量内存.

This Business logic example is, indeed, very simple, just shows how to retrieve data from Storage layer, but as long as you have access to data, you can manipulate it in the way you want. Just a comment here: maybe this solution should be re-thinked if implemented in a very busy server with thousands of requisitions because it can use lots of memory.

从业务逻辑和 UI 的角度来看,所有数据都使用列表等通用容器在模块之间进行通信.所有这些模块之间的链接点是容器类,因此所有类的解耦程度都较低.

For the business logic and also UI point of view, all data are communicated between modules using general purpose containers like Lists. The link point between all those modules are the containers classes so all the classes are more less well decoupled.

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

UI makes requisitions to the Business logic classes, so it acts like a service provider. Doing in that way, changing the UI will not affect the classes below to it.

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

The Business logic requests and send data to the Data storage classes using general purpose data, so changing the data base / storage technology should not affect it.

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

That's the way I use to do and I'm trying to improve it ;)

这篇关于我的业务逻辑应该如何与我的数据层交互?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆