所以我正在制定我的计划草案.
这是我的计划:
GUI --- Business Logic --- Data
您应该能够毫无问题地替换任何一个GUI
或该Data
层.每一层都看着自己.因此GUI
将调用方法,Business logic
并且方法将始终返回状态和可能的一些数据.应该始终在GUI层中确定GUI应如何响应数据.业务逻辑应该对此没有影响.因此,与GUI和业务逻辑的关系已经得到解决.我希望你能跟着我.
现在换一些更具体的东西.我对数据层的计划是使用数据库.现在,Business Logic应该如何从数据层调用方法?
也许我应该创建一个枚举,它对应于数据层知道的不同硬编码SQL查询?
例如
Datalayer.GetResults(Queries.GetAllCustomersIDs);
查询是枚举.
如果这是正确的方法,GetResults应该返回什么?一个字符串数组?但是如果查询具有多维数据呢?
我应该使用2种通用方法吗?
Datalayer.GetSingleDimensionResults(SingleDimensionQueries.GetAllCustomersIDs); Datalayer.GetMultipleDimensionResults(MultiDimensionQueries.GetAllCustomers);
或者我应该对每种数据请求进行查询?
Datalayer.GetAllCustomerIDs; DataLayer.GetAllCustomers;
等等
一般来说,我用来做的是:
数据层:
对于数据访问,我为每个对象创建一个接口.每个接口都列出了相关对象的所有公共数据访问方法.为了保存数据,我也为每个对象创建容器类型,它们可以是只有数据的结构或简单类.我还依赖语言数据集(如列表)来保存我的数据,因此我没有链接到特定的数据库类型.之后,我创建了一个实现数据接口的类,这个类具有所有SQL并访问数据库,因此在数据存储技术发生变化的情况下,这是唯一将被更改的类.
业务层:
是否应该调用所有具有数据的逻辑,如何验证,以及来自数据接口的方法以及以何种顺序调用.该类使用容器(例如列表)接收数据并将数据"发送"到数据存储或GUI,其中数据类型是上面提到的容器.
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 ListList(); //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 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 list = new List (); 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 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 departments = department.List(); department.Close(); return departments; } }
这个业务逻辑示例实际上非常简单,只是展示了如何从存储层检索数据,但只要您可以访问数据,就可以按照自己的方式对其进行操作.这里只是一个评论:如果在一个拥有数千个请购单的非常繁忙的服务器中实现,也许应该重新考虑这个解决方案,因为它可以使用大量内存.
对于业务逻辑和UI的观点,所有数据都使用通用容器(如列表)在模块之间进行通信.所有这些模块之间的链接点是容器类,因此所有类的解耦都不太好.
UI对业务逻辑类进行请购,因此它就像服务提供者一样.这样做,更改UI不会影响下面的类.
业务逻辑使用通用数据请求并将数据发送到数据存储类,因此更改数据库/存储技术不应影响它.
这就是我用来做的方式,我正在努力改进它;)