Разработка мобильного приложения для устройств Blackberry, взаимодействующего с сервисом Twitter
Обоснование выбора средств разработки. Анализ предметной области. Сущность структурного подхода к разработке информационных систем. Требования к информационной и программной совместимости. Запросы к базе данных. Инфологическое проектирование системы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 22.08.2016 |
Размер файла | 1,6 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
- для первой категории работ через 2 часа от начала смены и через 2 часа после обеденного перерыва продолжительностью 15 минут каждый;
- для второй категории работ -- через 2 часа от начала рабочей смены и через 1,5-2,0 часа после обеденного перерыва продолжительностью 15 минут каждый или продолжительностью 10 минут через каждый час работы;
- для третьей категории работ -- через 1,5- 2,0 часа от начала рабочей смены и через 1,5-2,0 часа после обеденного перерыва продолжительностью 20 минут каждый или продолжительностью 15 минут через каждый час работы.
Эффективными являются нерегламентированные перерывы (микропаузы) длительностью 1-3 минуты.
Регламентированные перерывы и микропаузы целесообразно использовать для выполнения комплекса упражнений и гимнастики для глаз, пальцев рук, а также массажа. Комплексы упражнений целесообразно менять через 2-3 недели.
Пользователям ПК, выполняющим работу с высоким уровнем напряженности, показана психологическая разгрузка во время регламентированных перерывов и в конце рабочего дня в специально оборудованных помещениях (комнатах психологической разгрузки)
8.5 Пожарная безопасность
Пожары в помещениях с ПК представляют особую опасность, так как несут за собой большие материальные потери. Характерная особенность помещений с ПК - небольшие площади помещений. Как известно пожар может возникнуть при взаимодействии горючих веществ, окисления и источников зажигания. В помещениях с ПК присутствуют все перечисленные факторы.
Горючими компонентами в помещениях с ПК являются: перегородки, двери, полы, корпус и детали самих ПК, изоляция кабелей и др. Следовательно, в таких помещениях наиболее вероятны пожары классов: А (горение твердых веществ) и Е (горение электроустановок).
Источниками зажигания в помещениях с ПК могут быть электронные схемы ПК, приборы, применяемые для технического обслуживания, устройства электропитания, кондиционирования воздуха, где в результате различных нарушений образуются перегретые элементы, электрические искры и дуги, способные вызвать загорания горючих материалов.
Причины, по которым может возникнуть пожар в помещениях с видеодисплейными терминалами и ПК:
- перегрузка проводов;
- возникновение искрения;
- короткое замыкание.
Для большинства помещений с ПЭВМ установлена категория пожарной опасности В (пожароопасность).
Помещения с видеодисплейным терминалом и ПК должны быть оснащены аптечкой первой помощи и огнетушителями.
Согласно ППБ-01-03, помещения класса А рекомендуется оснащать воздушно-пенными и порошковыми огнетушителями. Помещения класса Е углекислотными и порошковыми огнетушителями.
В замкнутых помещениях объемом до 50 м2 вместо переносных огнетушителей (или в дополнение к ним) можно использовать ОПС. Охранно-пожарная сигнализация (ОПС) - основной элемент системы безопасности охраняемого объекта. Это интегрированный комплекс систем пожарной и охранной сигнализации.
Она объединяет функцию защиты от несанкционированного проникновения в помещение и функцию обнаружения возгорания и возможно автоматического пожаротушения.
Обычно в этот комплекс входят все системы безопасности помещения, что обеспечивает максимальную точность и быстроту обнаружения нарушения безопасности здания: несанкционированного проникновения, возгорания и т.д.
Пожарная безопасность должна обеспечиваться, в том числе и организационно-техническими мероприятиями.
Организационно-технические мероприятия включают в себя:
- организацию пожарной охраны (профессиональной, добровольной);
- обучение рабочих и служащих правилам пожарной безопасности;
- составление инструкций о порядке работы с пожароопасными веществами и материалами;
- отработку действий администрации, рабочих и служащих в случае возникновения пожара и эвакуации людей;
- применение средств наглядной агитации по обеспечению пожарной безопасности.
В случае пожара необходимо срочно покинуть здание, используя основные и запасные (пожарные) выходы или лестницы (пользоваться лифтами опасно), и как можно быстрее позвонить в пожарную охрану.
На начальной стадии развития пожара можно попытаться потушить его, используя имеющиеся средства пожаротушения (огнетушители, внутренние пожарные краны, покрывала, песок, воду и др.). Необходимо помнить, что огонь на элементах электроснабжения нельзя тушить водой. Предварительно надо отключить напряжение или перерубить провод топором с сухой деревянной ручкой. Если принятые меры не принесли требуемого эффекта, и огонь получил распространение, необходимо срочно покинуть здание.
При спасении пострадавших необходимо соблюдать меры предосторожности от возможного обвала, обрушения конструкций помещения и пр. После выноса пострадавших, нужно оказать им первую медицинскую помощь и отправить в ближайший медицинский пункт.
Заключение
В ходе работы были разработаны, созданы и отлажены все компоненты системы и проведена следующая работа:
представлены обоснование выбора обеспечивающих технологий и проектных решений по программному и информационному обеспечению;
продуман пользовательский интерфейс, обозначены возможные пути расширения системы.
Кроме того, в процессе работы были подсчитаны экономические характеристики разработки.
В рамках настоящей работы реализованы следующие функции:
· поиск сообщений;
· сохранение сообщений;
· пересылка сообщений;
· удаление сообщений;
· локализация на русском и английском языках.
Область применения: разработанная система после незначительной доработки может использоваться в любой организации.
Литература
1. Дейт К. Введение в системы баз данных/Пер. с англ. М.:Наука, 2004. -463 с.
2. Anthony Rizk Beginning BlackBerry Development электронная книга, 2009.- 300 с.
Приложение
Код программы
//#preprocess
package com.noveo.twit;
import com.noveo.twit.localization.TwitResource;
import com.noveo.twit.model.TwitHashtable;
import com.noveo.twit.sql.SQLConnection;
import com.noveo.twit.sql.SQLManager;
import com.noveo.twit.sql.SQLTwitManager;
import com.noveo.twit.sql.SdCardNotPresentException;
import com.noveo.twit.ui.TwitBaseScreen;
import net.rim.device.api.applicationcontrol.ApplicationPermissions;
import net.rim.device.api.applicationcontrol.ApplicationPermissionsManager;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
/**
*
* Class is start point
*
* @author mfilonenko
*
*/
public class Twit extends UiApplication {
public static SQLManager _sqlManager;
public static TwitHashtable _favoriteTwit;
private final static String dataBaseName = "TwitDB.bd";
private final static String dataBaseLocation = "file:///SDCard/databases/com.noveo.twit.database/";
/**
* Entry point for application
*
* @param args
* Command line arguments (not used)
*/
public static void main(String[] args) {
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
_assertHasPermissions();
Twit theApp = new Twit();
theApp.enterEventDispatcher();
}
/**
* Creates a new MyApp object
*/
public Twit() {
preLoad();
pushScreen(new TwitScreenWeb());
}
/**
* try connect to database
*
* @return void
*
*/
private void preLoad() {
try {
_sqlManager = new SQLTwitManager(SQLConnection.connect(
dataBaseLocation, dataBaseName));
_favoriteTwit = (TwitHashtable) _sqlManager.getAllElemets();
} catch (SdCardNotPresentException e) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(TwitBaseScreen._resourceBundle.getString(TwitResource.NO_SDCARD_MESSEGE));
System.exit(0);
}
});
} catch (final Exception e) {
System.exit(0);
}
}
/**
* set Permission
*
* @return void
*
*/
private static void _assertHasPermissions() {
ApplicationPermissionsManager applicationPermissionsManager = ApplicationPermissionsManager
.getInstance();
ApplicationPermissions applicationPermissions = applicationPermissionsManager
.getApplicationPermissions();
if (!(applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_EMAIL) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_FILE_API) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_INTERNET) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_RECORDING) == ApplicationPermissions.VALUE_ALLOW
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_WIFI) == ApplicationPermissions.VALUE_ALLOW
//#ifdef VERSION_5
&& applicationPermissions
.getPermission(ApplicationPermissions.PERMISSION_EVENT_INJECTOR
) == ApplicationPermissions.VALUE_ALLOW
//#endif
)) {
ApplicationPermissions permRequest = new ApplicationPermissions();
permRequest
.addPermission(ApplicationPermissions.PERMISSION_LOCATION_DATA);
permRequest
.addPermission(ApplicationPermissions.PERMISSION_ORGANIZER_DATA);
permRequest.addPermission(ApplicationPermissions.PERMISSION_EMAIL);
permRequest
.addPermission(ApplicationPermissions.PERMISSION_FILE_API);
permRequest
.addPermission(ApplicationPermissions.PERMISSION_INTERNET);
permRequest
.addPermission(ApplicationPermissions.PERMISSION_RECORDING);
permRequest.addPermission(ApplicationPermissions.PERMISSION_WIFI);
//#ifdef VERSION_5
permRequest
.addPermission(ApplicationPermissions.PERMISSION_EVENT_INJECTOR);
//#endif
if (!applicationPermissionsManager
.invokePermissionsRequest(permRequest)) {
System.exit(0);
}
}
}
}
package com.noveo.twit;
import com.noveo.twit.backend.RequestJSONCallbackNetwork;
import com.noveo.twit.ui.ContentGetter;
import com.noveo.twit.ui.TwitBaseScreen;
/**
*
* Class is network screen specific
*
* @author mfilonenko
*
*/
public final class TwitScreenWeb extends TwitBaseScreen {
/**
* Creates a new MyScreen object
*/
public TwitScreenWeb() {
super();
}
/**
* listener for search bar button
* @param requestOptions
* @return void
*
*/
public void onSearch(final String searchString, ContentGetter contentGetter) {
String replaceString = searchString;
if (searchString.length() == 0) {
_poolNetworkLoader.addToLoader(
"http://search.twitter.com/search.json?rpp=10&q="
+ searchString, new RequestJSONCallbackNetwork(
contentGetter));
} else {
while (replaceString.indexOf(" ") >= 0) {
int indexP = replaceString.indexOf(" ");
replaceString = replaceString.substring(0, indexP) + "%20"
+ replaceString.substring(indexP + 1);
}
// Dialog.alert(replaceString);
_poolNetworkLoader.addToLoader(
"http://search.twitter.com/search.json?rpp=10&q="
+ replaceString, new RequestJSONCallbackNetwork(
contentGetter));
}
// Dialog.alert("Wait!");
}
}
package com.noveo.twit.sql;
import java.util.Enumeration;
import javax.microedition.io.file.FileSystemRegistry;
import net.rim.device.api.database.Database;
import net.rim.device.api.database.DatabaseFactory;
import net.rim.device.api.io.URI;
/**
*
* Class for connect to Database SQLlyte
*
* @author mfilonenko
*
*/
public class SQLConnection {
public static Database connect(final String dataBaseLocation,
final String dataBaseName) throws SdCardNotPresentException,
Exception {
boolean sdCardPresent = false;
String root = null;
Enumeration e = FileSystemRegistry.listRoots();
while (e.hasMoreElements()) {
root = (String) e.nextElement();
if (root.equalsIgnoreCase("sdcard/")) {
sdCardPresent = true;
break;
}
}
if (!sdCardPresent) {
throw new SdCardNotPresentException();
}
URI uri = URI.create(dataBaseLocation + dataBaseName);
return DatabaseFactory.openOrCreate(uri);
}
}
package com.noveo.twit.sql;
import com.noveo.twit.model.TwitHashtable;
import com.noveo.twit.model.TwitObject;
import net.rim.device.api.database.Cursor;
import net.rim.device.api.database.DataTypeException;
import net.rim.device.api.database.Database;
import net.rim.device.api.database.DatabaseException;
import net.rim.device.api.database.Row;
import net.rim.device.api.database.Statement;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
/**
*
* Class for work with Datebase (add/delete/update...)
*
* @author mfilonenko
*
*/
public class SQLTwitManager extends SQLManager {
public SQLTwitManager(Database database) {
super(database);
}
protected void tableCreate() {
Statement statement;
try {
statement = database
.createStatement("CREATE TABLE IF NOT EXISTS TwitTable (id INTEGER PRIMARY KEY,user TEXT, imageURL TEXT, text TEXT,date TEXT)");
statement.prepare();
statement.execute();
statement.reset();
statement.close();
} catch (DatabaseException e) {
onException(e);
}
}
public void addElement(Object element) {
TwitObject twitObject = (TwitObject) element;
Statement statement;
try {
statement = database
.createStatement("INSERT INTO TwitTable(id,user,imageURL,text,date) VALUES(?,?,?,?,?)");
statement.prepare();
statement.bind(1, twitObject.getId());
statement.bind(2, twitObject.getUser());
statement.bind(3, twitObject.getImageUrl());
statement.bind(4, twitObject.getText());
statement.bind(5, twitObject.getDate());
statement.execute();
statement.close();
} catch (DatabaseException e) {
// TODO Auto-generated catch block
onException(e);
}
}
public Object getAllElemets() {
TwitHashtable twitList = new TwitHashtable();
try {
Statement statement = database
.createStatement("SELECT * FROM TwitTable");
statement.prepare();
Cursor cursor = statement.getCursor();
while (cursor.next()) {
Row row = cursor.getRow();
long id = row.getLong(0);
String user = row.getString(1);
String imageURL = row.getString(2);
String text = row.getString(3);
String date = row.getString(4);
twitList.put(new TwitObject(id,user,text,imageURL,date));
}
statement.close();
cursor.close();
} catch (DatabaseException e) {
onException(e);
} catch (DataTypeException e) {
onException(e);
}
return twitList;
}
public void removeElemet(Object key) {
try {
Statement statement = database
.createStatement("DELETE FROM TwitTable WHERE id = ?");
statement.prepare();
statement.bind(1, ((Long) key).longValue());
statement.execute();
statement.close();
} catch (DatabaseException e) {
onException(e);
}
}
private void onException(final Exception exception) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(exception.toString());
}
});
}
}
package com.noveo.twit.model;
import java.util.Enumeration;
import java.util.Hashtable;
import net.rim.device.api.util.StringUtilities;
/**
*
* Class for store twits
*
* @author mfilonenko
*
*/
public class TwitHashtable extends Hashtable {
public synchronized Object put(Object twitObject) {
return super.put(new Long(((TwitObject) twitObject).getId()),
twitObject);
}
public synchronized Object remove(long id) {
return super.remove(new Long(id));
}
public synchronized boolean containsID(long id) {
return super.containsKey(new Long(id));
}
public synchronized TwitHashtable search(final String searchString) {
if (searchString.length() == 0)
return this;
TwitHashtable twitHashtable = new TwitHashtable();
String[] splitSearchStrings = StringUtilities
.stringToWords(searchString.toLowerCase());
for (Enumeration en = this.elements(); en.hasMoreElements();) {
TwitObject twitObject = (TwitObject) en.nextElement();
boolean isConatin = true;
for (int i = 0; i < splitSearchStrings.length; ++i) {
if (twitObject.getText().toLowerCase()
.indexOf(splitSearchStrings[i]) == -1
&& twitObject.getUser().toLowerCase()
.indexOf(splitSearchStrings[i]) == -1) {
isConatin = false;
}
}
if(isConatin)
{
twitHashtable.put(twitObject);
}
}
return twitHashtable;
}
}
package com.noveo.networkloader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.ui.UiApplication;
import com.noveo.networkloader.callback.RequestCallback;
import com.noveo.networkloader.connectionfactory.HttpConnectionFactory;
/**
*
* Cancelable thread that loads data from the given url
*/
class BackendThread extends Thread {
private String url;
private RequestCallback callback;
private RequestOptions requestOptions;
private boolean isAlive = true;
public BackendThread(String url, RequestCallback callback,
RequestOptions requestOptions) {
super();
this.url = url;
this.callback = callback;
this.requestOptions = requestOptions;
}
/**
* Get byte array from connection
*
* @param connection
* @param callback
* @return Byte array with downloaded data
* @throws IOException
*/
private byte[] getBytes(HttpConnection connection, RequestCallback callback)
throws IOException {
InputStream is = connection.openInputStream();
int maxLength = Integer.parseInt(connection
.getHeaderField("Content-Length"));
ByteArrayOutputStream os = new ByteArrayOutputStream();
int length = -1;
byte[] readBlock = new byte[256];
int fileSize = 0;
while ((length = is.read(readBlock)) != -1 && isAlive) {
fileSize += length;
os.write(readBlock, 0, length);
onProgressUpdate(callback, (int) (fileSize * 1.0 / maxLength * 100));
}
if (!isAlive) {
return null;
} else {
}
return os.toByteArray();
}
public void run() {
HttpConnection connection = null;
HttpConnectionFactory factory;
try {
factory = new HttpConnectionFactory();
connection = factory.getHttpConnection(url);
for (int i = 0; i < requestOptions.getRequestProperties().length; ++i) {
connection.setRequestProperty(
requestOptions.getRequestProperties()[i].getKey(),
requestOptions.getRequestProperties()[i].getValue());
}
if (requestOptions.isPostRequest()) {
connection.setRequestMethod(HttpConnection.POST);
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",
String.valueOf(requestOptions.getPostData().length));
OutputStream os = connection.openOutputStream();
os.write(requestOptions.getPostData());
os.close();
}
byte[] response = getBytes(connection, callback);
onSuccess(callback, response);
} catch (Exception e) {
onFailure(callback, e);
} finally {
try {
if (connection != null)
connection.close();
} catch (IOException e) {
onFailure(callback, e);
}
onPostExecute(callback);
}
}
//#preprocess
package com.noveo.twit.backend;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.pim.Contact;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;
import javax.microedition.pim.PIMItem;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.TextMessage;
import com.noveo.twit.localization.TwitResource;
import com.noveo.twit.model.TwitObject;
import com.noveo.twit.ui.TwitBaseScreen;
import net.rim.blackberry.api.invoke.Invoke;
import net.rim.blackberry.api.invoke.MessageArguments;
import net.rim.blackberry.api.pdap.BlackBerryContactList;
import net.rim.device.api.system.Clipboard;
import net.rim.device.api.system.EventInjector;
import net.rim.device.api.system.KeypadListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
/**
* Class is describes twit send by email or sms
* @author mfilonenko
*/
public class TwitSend {
BlackBerryContactList contactList;
private int waySend = -1;
public static final int WAY_SEND_EMALE = 0;
public static final int WAY_SEND_SMS = 1;
PIMItem contactChoose = null;
private TwitObject twitObject;
public TwitSend() {
try {
contactList = (BlackBerryContactList) PIM.getInstance()
.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
} catch (PIMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void chooseContact() {
if (waySend >= 0) {
contactChoose = contactList.choose();
}
}
private void sendBySMS(final String number) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
MessageConnection mc;
try {
mc = (MessageConnection) Connector.open("sms://");
TextMessage m = (TextMessage) mc
.newMessage(MessageConnection.TEXT_MESSAGE);
m.setAddress("sms://" + number);
//#ifdef VERSION_5
Clipboard clip = Clipboard.getClipboard();
clip.put(twitObject.getText());
// #else
m.setPayloadText(twitObject.getText());
//#endif
MessageArguments messageArguments = new MessageArguments(m);
Invoke.invokeApplication(Invoke.APP_TYPE_MESSAGES,
messageArguments);
//#ifdef VERSION_5
new Thread() {
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EventInjector
.invokeEvent(new EventInjector.NavigationEvent(
EventInjector.NavigationEvent.NAVIGATION_CLICK,0, 0, KeypadListener.STATUS_SHIFT));
}
}.start();
//#endif
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Размещено на Allbest.ur
Подобные документы
Анализ предметной области объекта автоматизации "Компьютерные курсы". Обзор информационных технологий, подходящих для разработки информационной системы. Требования к разрабатываемой базе данных и ее проектирование, особенности ее программной реализации.
курсовая работа [369,8 K], добавлен 30.05.2013Инфологическое моделирование предметной области. Построение диаграммы потоков данных. Обоснование выбора СУБД. Проектирование пользовательского интерфейса. Комплект поставки и порядок установки системы. Описание функционирования приложения и таблиц.
курсовая работа [3,2 M], добавлен 23.08.2014Разработка приложения, позволяющего автоматизировать документооборот предприятия по списанию основных средств. Мероприятия по защите и обеспечению целостности базы данных. Разработка клиентского приложения. Запросы к базе данных, руководство пользователя.
курсовая работа [700,0 K], добавлен 14.01.2015Системный анализ предметной области. Требования к программе и программному изделию, к функциональным характеристикам, к надежности, составу и параметрам технических средств. Обоснование выбора средств выбора для хранения и обработки базы данных.
реферат [403,8 K], добавлен 02.02.2014Анализ решений по автоматизации предметной области. Выбор методологии проектирования информационной системы. Обоснование выбора платформы. Взаимодействие приложения с источниками данных. Выбор жизненного цикла разработки программного обеспечения.
дипломная работа [3,7 M], добавлен 18.12.2010Выбор языка и среды программирования, технологий доступа и взаимодействия с источниками данных. Требования к разработке информационной системы. Проектирование базы данных информационной системы учета и взаимодействующего с ней приложения .NET Framework.
курсовая работа [1,3 M], добавлен 17.05.2013Классификация информационных систем. Использование баз данных в информационных системах. Проектирование и реализация информационной системы средствами MS Access. Анализ входной информации предметной области и выделение основных информационных объектов.
курсовая работа [2,5 M], добавлен 09.08.2012Общие требования к АИС киноцентра "Пирамида". Концептуальное, логическое и физическое проектирование, запросы к базе данных и экранные формы. Основы разработки внешних приложений в Delphi. Создание внешнего приложения и руководство пользователя.
курсовая работа [1,3 M], добавлен 03.11.2014Анализ предметной области. Разработка информационной системы для регистратуры поликлиники. Построение диаграмм и моделей с использование объектно-ориентированного подхода. Формы, таблицы, отчеты и запросы. Создание, редактирование и обработка данных.
курсовая работа [2,7 M], добавлен 04.12.2015Оценка предметной области: концептуальные требования; выявление информационных объектов и связей между ними; построение базы данных. Описание входных и выходных данных информационной системы "Магазин компьютерной техники". Анализ диаграммы прецедентов.
курсовая работа [294,8 K], добавлен 13.04.2014