Как моя бизнес-логика должна взаимодействовать с моим слоем данных?

Я записал Python tsr, который опросил сервер время от времени (он вытянул свою частоту запросов с сервера), и распечатает для маркировки принтера. Было относительно хорошо.

Когда-то записанный в Python, я использовал py2exe на нем, тогда inno компилятор установки, затем поставивший интранет, и сделал, чтобы пользователь установил его.

Это не было большим, но это работало. Пользователи запустили бы его утром, и программа получит переключатель уничтожения от сервера ночью.

6
задан CasperT 23 November 2009 в 10:43
поделиться

2 ответа

Обычно я использую следующие функции:

Уровень данных:

Для доступа к данным я создаю интерфейс для каждого объекта. В каждом интерфейсе перечислены все общедоступные методы доступа к данным для рассматриваемого объекта. Для хранения данных я также создаю типы контейнеров для каждого объекта, которые могут быть структурами или простыми классами только с данными. Я также полагаюсь на языковой набор данных, например списки, для хранения моих данных, поэтому я не связан с конкретным типом базы данных. После этого я создаю класс, который реализует интерфейсы данных, этот класс имеет весь SQL и обращается к базе данных, поэтому в случае изменения технологии хранения данных это единственный класс, который будет изменен.

Бизнес-уровень:

Выполняет всю логику с данными, как проверять, какие методы из интерфейсов данных должны вызываться и в каком порядке. Этот класс получает и "отправляет" данные в хранилище данных или графический интерфейс пользователя, используя контейнеры (например, списки), где типы данных являются моими контейнерами, упомянутыми выше.

Графический интерфейс:

Вызывает методы бизнес-логики и показывает / форматирует представление данных. Здесь нет никакой логики, кроме вызова правильных методов бизнес-логики.

Небольшой пример кода контейнера (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 делает запросы к классам бизнес-логики, поэтому он действует как поставщик услуг. Таким образом, изменение пользовательского интерфейса не повлияет на следующие классы.

Бизнес-логика запрашивает и отправляет данные в классы хранилища данных с использованием данных общего назначения, поэтому изменение технологии базы данных / хранилища не должно влиять на нее.

Я так делаю и пытаюсь улучшить;)

7
ответ дан 10 December 2019 в 02:49
поделиться

«Уровень» ваших данных, вероятно, должен быть больше, чем набор семантических запросов, и вы должны инкапсулировать его в API, иначе вашему слою бизнес-логики придется слишком много знать о реализации вашего уровня данных. Те же рассуждения, которые вы использовали между слоями графического интерфейса пользователя и бизнес-логики, должны применяться и для той же цели.

2
ответ дан 10 December 2019 в 02:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: