Architecture 我的业务逻辑应该如何与我的数据层交互?
所以我正在起草我的计划 这是我的计划:Architecture 我的业务逻辑应该如何与我的数据层交互?,architecture,Architecture,所以我正在起草我的计划 这是我的计划: GUI --- Business Logic --- Data 您应该能够更换GUI或Data层而不会出现问题。 每一层都在观察自己。因此GUI将从businesslogic调用方法,这些方法将始终返回一个状态,可能还返回一些数据。GUI应如何响应数据,始终应由GUI层决定。业务逻辑对此不应有影响。 因此,解决了与GUI和业务逻辑的关系。 我希望你能跟我来 现在来看看更具体的东西。 我的数据层计划是使用数据库。 现在,业务逻辑应该如何从数据层调用方法 也
GUI
---
Business Logic
---
Data
您应该能够更换GUI
或Data
层而不会出现问题。
每一层都在观察自己。因此GUI
将从businesslogic
调用方法,这些方法将始终返回一个状态,可能还返回一些数据。GUI应如何响应数据,始终应由GUI层决定。业务逻辑对此不应有影响。
因此,解决了与GUI和业务逻辑的关系。
我希望你能跟我来
现在来看看更具体的东西。
我的数据层计划是使用数据库。
现在,业务逻辑应该如何从数据层调用方法
也许我应该创建一个枚举,对应于数据层知道的不同硬编码SQL查询
例如
作为枚举的查询
如果这是正确的方法,那么GetResults应该返回什么?字符串数组?但是如果查询有多维数据呢
那么我应该有2个泛型方法吗
Datalayer.GetSingleDimensionResults(SingleDimensionQueries.GetAllCustomersIDs);
Datalayer.GetMultipleDimensionResults(MultiDimensionQueries.GetAllCustomers);
或者我应该为每种类型的数据请求进行查询吗
Datalayer.GetAllCustomerIDs;
DataLayer.GetAllCustomers;
等等。您的数据“层”可能不仅仅是一组语义查询,您应该将其封装在API中,否则您的业务逻辑层将不得不对数据层的实现了解太多。您在GUI和业务逻辑层之间使用的相同推理应该适用,并且出于相同的目的。一般来说,我用来做的是: 数据层: 对于数据访问,我为每个对象创建了一个接口。每个接口都列出了相关对象的所有公共数据访问方法。为了保存数据,我还为每个对象创建了容器类型,这些容器类型可以是结构或仅包含数据的简单类。我还依赖于语言数据集(如列表)来保存数据,因此我没有链接到特定的数据库类型。在那之后,我创建了一个实现数据接口的类,这个类拥有所有的SQL和访问数据库的权限,因此在数据存储技术发生变化的情况下,这是唯一会被改变的类 业务层: 所有的逻辑都与数据有关,如何验证,数据接口中的哪些方法应该被调用,以及调用的顺序。此类使用容器(例如列表)接收数据并将数据“发送”到数据存储或GUI,其中数据类型是上面提到的my容器 图形用户界面: 调用业务逻辑方法并显示/格式化数据表示。除了调用业务逻辑的正确方法之外,这里没有其他逻辑 容器(C#)的小代码示例
//部门类数据访问接口。数据存储组件
命名空间数据存储
{
公共接口IDepartmentDS
{
void Open();//打开数据连接
void Close();//关闭数据连接
List();//获取所有部门(从数据库)
}
}
//此类保存一个部门的所有数据。这里没有逻辑。存储库程序集
命名空间存储库
{
公共课系
{
[可浏览(错误)]
公共部门()
{
}
[可浏览(错误)]
公共部门(字符串符号、字符串名称)
{
这个符号=符号;
this.DeptName=名称;
}
公共部门(部门)
{
this.Symbol=部门.Symbol;
this.DeptName=department.DeptName;
}
[可浏览(错误)]
公共字符串符号{get;set;}
公共字符串DeptName{get;set;}
}
}
//这个类本身实现了数据操作,访问真实的数据库。
//但是,此类之外的数据交换是通过存储库和类完成的
//泛型-主要列出
公共类数据存储:IDepartmentDS
{
//这里我用一般函数来连接数据库,格式存储
//程序参数清单等。
//部门界面列表方法declare的实现
List IDepartmentDS.List()
{
String query=String.Format(“从{0}中选择*”,DepartmentTable);
int行=0;
DataSet ds=ExecSqlCommand(查询,输出行);//此方法对此类是私有的
如果(ds==null)
返回null;
列表=新列表();
foreach(ds.Tables[0].行中的DataRow行)
{
list.Add(newrepositories.Department((String)行[DepFN_Symbol],(String)行[DepFN_DepName]);
//DepFN_符号和其他符号只是表示列索引的常量变量
}
退货清单;
}
}
公共类部门逻辑
{
公共部门逻辑
{
.....
}
公共列表GetAllDepartments()
{
//这里我创建了一个DataStorage的实例,但使用的是Department接口
//因此,我只限制对部门数据方法的访问。这可能是一个好方法
//这里的想法是使用工厂模式。
IDepartmentDS department=(IDepartmentDS)新数据存储();
部门开放(;
List departments=department.List();
部门关闭();
返回部门;
}
}
这个业务逻辑示例确实非常简单,它只展示了如何从存储层检索数据,但只要您有权访问数据,就可以按照您想要的方式对其进行操作。这里只是一个评论:如果在一个有数千个请求的非常繁忙的服务器上实现,可能应该重新考虑这个解决方案,因为它会占用大量内存
用于业务逻辑和用户界面
Datalayer.GetAllCustomerIDs;
DataLayer.GetAllCustomers;
//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;
}
}