Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Способы хранения настроек.




В объектном программировании всё представляется в виде объектов. Настройки лучше всего при этом рассматривать как свойства определённых объектов, которые хранятся в файлах конфигураций. То, каким образом эти настройки считываются и записываются тесно взаимосвязано с форматом файлов и выбраной стратегией администрирования. Рассмотрим идеальный вариант:

Настраиваемый объект не должен содержать знаний о формате файлов и способе чтения/записи. Это позволило бы, в случае необходимости, заменить один способ другим.

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

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

К сожалению этот идеальный вариант довольно трудно сделать на практике. Первое требование предполагает разработку универсального механизма сохранения объектов. Такие системы уже есть готовые, но часто они не подходят по тем или иным параметрам. Разработать же самому такую систему - далеко не каждому под силу.

Второе требование подразумевает, что для каждого объекта пишется своя панель (или диалог) для редактирования настроек. В случае большого количества объектов стоит попробовать использовать универсальные механизмы. Один из вариантов - использование стандарта JavaBeans. Этот стандарт разрабатывался для визуальных систем программирования, но, из-за сходства решаемых задач, также хорошо подходит для универсального конфигурирования. Но это тоже не самая простая задача, поэтому часто разумно предусмотреть возможность альтернативного варианта конфигурирования для пожарных случаев - например, при помощи обычных текстовых редакторов в случае использования текстовых форматов файлов.

Разумное же умолчание для параметров часто просто невозможно представить. Например, что поставить в качестве имени SMTP-сервера? В случае Unix-систем можно попробовать поставить localhost, но для Windows-мира это редко кому подойдёт.

Рассмотрим наиболее распространённые варианты:

Ini-файлы.

Ini-файлы - это был самый распространённый вариант в эпоху Windows 3.x. Сейчас в виндовых программах он стал вытесняться хранением настроек в реестре. Тем не менее ini - это один из простейших вариантов хранения настроек. К сожалению довольно часто эта простота заставляет прибегать к различно рода ухищрениям. Пример типичного ini-файла:

[Communication]

InputDir=INPUT

OutputDir=OUTPUT

ArchDir=ARHIV

TransferPath = a:\cour

[Warning]

NoReceived=No

[Addons]

Numb = 3

MenuName1 = ~N~orton

ProgName1 = mousesav c:\command.com /c nc

MenuName2 = Win - ~Б~локнот

ProgName2 = notepad

MenuName3 = Импорт из формата АБ "Инкомбанк"

ProgName3 = incom.bat

В Java нет стандартного класса для чтения ini-файлов, но это не проблема. Т.к. формат очень прост, его легко сделать самому:

import java.io.*;

import java.util.*;

public class INIFile

{

 Properties iniProperty = new Properties();

 public INIFile(File f) { this(f.getPath()); }

 public INIFile(String fname) throws IOException { loadFile(fname); }

 private void loadFile(String fname) throws IOException

 {

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fname)));

try

{

String section = "";

String line;

while((line = br.readLine())!=null)

  {

   if(line.startsWith(";")) continue;

   if(line.startsWith("["))

     {

      section = line.substring(1,line.lastIndexOf("]")).trim();

      continue;

     }

   addProperty(section,line);

  }

}

finally { br.close(); }

 }

 private void addProperty(String section,String line)

 {

int equalIndex = line.indexOf("=");

if(equalIndex > 0)

{

String name = section+'.'+line.substring(0,equalIndex).trim();

String value = line.substring(equalIndex+1).trim();

iniProperty.put(name,value);

}

 }

 public String getProperty(String section,String var,String def)

 {

return iniProperty.getProperty(section+'.'+var,def);

 }

 public int getProperty(String section,String var,int def)

 {

String sval = getProperty(section,var,Integer.toString(def));

 

return Integer.decode(sval).intValue();

 }

 public boolean getProperty(String section,String var,boolean def)

 {

String sval = getProperty(section,var,def? "True":"False");

return sval.equalsIgnoreCase("Yes") || sval.equalsIgnoreCase("True");

 }

}

Файлы Properties.

Этот формат распространён в Unix-мире. Он ещё проще ini-файлов, т.к. в нём отсутствует понятие секций - всё состоит из ключей и значений. Пример типичного файла:

# Database configuration

Database.Driver=sun.jdbc.odbc.JdbcOdbcDriver

Database.DataURL=jdbc:odbc:MyDatabase

Database.Prop.user=user

Database.Prop.password=password

В Java есть готовый класс для чтения/записи таких файлов (java.util.Properties), но с ним есть некоторые проблемы. Во первых для чтения невозможно задать кодировку файла, а это означает проблемы с русскими буквами. Во вторых стандартная функция записи сохраняет данные в порядке следования хэш-значений ключей, что значит - как ей больше понравится. Но это тоже легко разрешимо - достаточно написать свою читалку/писалку.

XML-файлы.

Этот формат подходит для многих целей, в том числе и для хранения настроек. XML-формат ориентирован на древовидные структуры, что довольно естественым образом отображается на объекты. Пример типичного файла:

<?xml version="1.0" encoding="Windows-1251"?>

<!-- Database configuration -->

<database

driver="sun.jdbc.odbc.JdbcOdbcDriver"

dataURL="jdbc:odbc:MyDatabase">

<prop name="user">user</prop>

<prop name="password">password</prop>

</database>

Для чтения и записи таких файлов предназначены специальные библиотеки - так называемые XML-парсеры. Таких парсеров уже сделано довольно много, так что писать его самому нет большого смысла - достаточно лишь подобрать подходящий. Для парсеров было разработано два стандартных программных интерфейса - событийный (SAX) и иерархический (DOM). Есть также и парсеры со своим интерфейсом. Размер jar-а с парсером может варьироваться от нескольких килобайт до мегабайта - в зависимости от поддерживаемых интерфейсов и возможностей.

Для XML также написано несколько библиотек для универсального сохранения (сериализации) объектов в файлах XML. Такие библиотеки позволяют отделить алгоритм сохранения от самого объекта, а это, как уже упоминалось, имеет много плюсов.

Сериализация.

Под термином "сериализация" понимают запись содержимого объекта в поток двоичных данных. Обычно имеется в виду универсальный алгоритм, реализуемый классами java.io.ObjectOutputStream и java.io.ObjectInputStream. Пользоваться ими просто настолько, насколько это вообще возможно - обычно достаточно лишь отметить в классе поддержку при помощи интерфейса Serializable и отметить ключевым словом transient те поля объекта, которые сохранять не нужно. Собсно и всё.:-) Пример:

public class SerialObject implements java.io.Serializable

{

 private String name;

 private transient int state;

 public SerialObject() {}

 public SerialObject(String n) { name = n; }

 public String getName() { return name; }

 public void setState(int s) { state = s; }

}

Запись объектов:

SerialObject o =...;

OutputStream os =...;

ObjectOutputStream oos = new ObjectOutputStream(os);

oos.writeObject(o);

Чтение объектов:

InputStream is =...;

ObjectInputStream ois = new ObjectInputStream(is);

SerialObject o = (SerialObject)ois.readObject();

Использование сериализации - это один из самых простых вариантов по реализации, но и у него есть свои недостатки. Получаемые файлы являются двоичными, а значит в текстовом редакторе их уже не подправить - придётся делать редактирование параметров из программы. Кроме того, необходимо следить за изменением сохраняемых объектов, дабы не нарушить совместимость при изменении и развитии программы.

Базы данных.

В базах данных можно хранить любые данные, конфигурация программы - не исключение. Это имеет смысл в нескольких случаях:

Настройки связаны весьма сложным образом и древовидные структуры типа XML подходят плохо.

Доступ к настройкам должен быть только у авторизованых пользователей.

Доступ к этим данным должен быть и из других программ, например из генератора отчётов типа Crystal Reports.

БД могут применятся объектные или реляционные. Другие типы сейчас широкого распространения не имеют. Использовать хорошую объектную БД часто так же просто, как и сериализацию. Для реляционых баз можно применить объектную надстройку, которая также позволяет сильно упростить жизнь. Ну а можно делать обычные SELECT-ы.

Скрипты.

Использование скриптов - это один из самых экстремальных способов конфигурирования. Они позволяют добится максимальной гибкости программы за счёт вынесения логики наружу. В использовании скриптов надо тоже знать меру - в конце концов заказчик платит Вам за программу, решающую задачи, а не за ещё один интерпретатор или компилятор за который ему потребуется посадить ещё одного программиста. А то получается, как в том анекдоте - какую программу не начнёшь писать, всё компилятор получается.

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

Для программ на Java в качестве скрипт-языка хорошо использовать язык Python в его Java-инкарнации под названием JPython. Там легко организовать двусторонюю связь между программой и скриптом. Если не будет хватать скорости интерпретации, то код на Python-е можно скомпилировать в байт-код - получится обычный Java-класс. Про JPython можно почитать на сайте www.jpython.org или в новой книжке Брюса Эккеля Thinking In Patterns with Java (доступна на www.bruceeckel.com).

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...