So I'm working on making a draft of my program.
This is my plan:
GUI
---
Business Logic
---
Data
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?
Perhaps I should make an enum, that corresponds to different hardcoded SQL queries, which the data layer is aware of?
E.g.
Datalayer.GetResults(Queries.GetAllCustomersIDs);
Queries being an enum.
If this is the right way, what should GetResults return? a string array? but what if the query has multidimensional data?
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;
etc.
The business logic layer contains objects that execute the business functions. The Command pattern should be considered to implement these objects. With the Command pattern, each use case in the requirements document is implemented as a separate command or set of commands executed in the business logic layer.
Introduction. The Data Access Layer (DAL) created in the first tutorial cleanly separates the data access logic from the presentation logic. However, while the DAL cleanly separates the data access details from the presentation layer, it does not enforce any business rules that may apply.
The business logic layer is the business components that provide OAGIS services to return data or start business processes. The presentation layer uses these OAGIS services to display data, or to invoke a business process. The business logic provides data required by the presentation layer.
Business logic should live in the data model. And, what's more, it should live in the graph data model because that's the right abstraction for the next twenty years. If you've been paying attention to this blog or to Stardog generally, then you must have known this is where we were going to end up.
What is a Business Logic Layer & Why Does It Matter? The business logic layer is the connector between the database and the application, defining the rules and restrictions of how the database data is used.
Presentation Layer: The layer at which users interact with the application and the final data will be visible to the users at this interface. It acts as an interface between the user and the application. Business Logic Layer: It acts as an intermediate between the Presentation and the Data Access Layer.
Application logic is logic related to the fact that you are running a computer program. This can be stuff such as CSV import export, wizards, etc. Could also contain stuff like creating forgotten password emails. The kind of "business logic" that you can place in the controller layer is Application logic.
If there is business logic shared between controller and model the two layers are no longer separable, and someone inheriting the code may be confused by this unevenness in location of business logic related code. My question is how much business logic should be allowed in the controller and in what circumstances, if any?
In general, what I use to do is:
Data layer:
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.
Business layer:
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.
GUI:
Calls business logic methods and show / format data presentation. There's no logic here other than call the right methods of the business logic.
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;
}
}
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.
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 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 ;)
Your Data "Layer" should probably be more than a set of semantic queries and you should encapsulate it in an API, otherwise your Business Logic layer will have to know too much about the implementation of your Data layer. The same reasoning you have used between your GUI and Business Logic layers should apply, and for the same purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With