Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 21.03.2013, 02:48
yasha005 вне форума Посмотреть профиль Отправить личное сообщение для yasha005 Найти все сообщения от yasha005
  № 11  
Ответить с цитированием
yasha005
[+1 16.03.13]
[+1 22.03.13]

Регистрация: Dec 2012
Сообщений: 100
У меня конечно изначально была идея взять за основу шаблон состояние:

Код AS3:
package server_exchange.socket_4444
{
	// Состояние: Контекстный класс
	internal class WorksSocket
	{
		/*//////////////////////////////////////
			Список состояний
		//////////////////////////////////////*/
 
		// Соединение с сокетом не установлено (ожидаются действия)
		private var state1No:IState;
		// Соединение с сокетом устанавливается
		private var state2SocketConnecting:IState;
		// Соединение с сокетом успешно установлено (ожидаются действия)
		private var state3SocketEstablished:IState;
		// Выполняется отправка данных на сервер
		private var state4SocketReading:IState;
		// Выполняется приём данных с сервера
		private var state5SocketWriting:IState;
 
		// Текущее состояние
		private var iStateSocket:IState;
 
		public function WorksSocket()
		{
			// Инициализируем все конкретные состояния
			this.state1No = new State1No(this);
			this.state2SocketConnecting = new State2SocketConnecting(this);
			this.state3SocketEstablished = new State3SocketEstablished(this);
			this.state4SocketReading = new State4SocketReading(this);
			this.state5SocketWriting = new State5SocketWriting(this);
 
			// Устанавливаем первоначальный статус при инициализации конструктора
			this.iStateSocket = this.state1No;
		}
 
		/*/////////////////////////////////////////////////////
			Выполнение события в установленном состоянии
		/////////////////////////////////////////////////////*/
 
		public function set ExecuteState(comand:String):void
		{
			switch(comand)
			{
				case ComandName._command1SocketConnect: this.iStateSocket.Command1SocketConnect(); break;
				case ComandName._command2SocketConnecting: this.iStateSocket.Command2SocketConnecting(); break;
				case ComandName._command3SocketWrite: this.iStateSocket.Command3SocketWrite(); break;
				case ComandName._command4SocketRead: this.iStateSocket.Command4SocketRead(); break;
			}
		}
 
		/*/////////////////////////////////////////////////////
			Устанавливает состояние
		/////////////////////////////////////////////////////*/
 
		public function set SetState(state:String):void
		{
			switch(state)
			{
				case StateName._state1No: this.iStateSocket = this.state1No; break;
				case StateName._state2SocketConnecting: this.iStateSocket = this.state2SocketConnecting; break;
				case StateName._state3SocketEstablished: this.iStateSocket = this.state3SocketEstablished; break;
				case StateName._state4SocketReading: this.iStateSocket = this.state4SocketReading; break;
				case StateName._state5SocketWriting: this.iStateSocket = this.state5SocketWriting; break;
			}
		}
 
 
	} // Конец класса
} // Конец пакета
Интерфейс состояний:
Код AS3:
package server_exchange.socket_4444
{
	// Состояние: команды для выполнения действий в каком-либо из состояний
	internal interface IState
	{
		// Выполняет команду на соединение с сокетом
		function Command1SocketConnect():void;
		// Связь с сокетом устанавливается
		function Command2SocketConnecting():void;
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		function Command3SocketWrite():void;
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		function Command4SocketRead():void
	}
}

Действия состояний:
Код AS3:
package server_exchange.socket_4444
{
	// Действия, выполняемые в каком-либо состоянии
	internal class ComandName
	{
		// Выполняет команду на соединение с сокетом
		internal static const _command1SocketConnect:String = 'Command1SocketConnect';
		// Связь с сокетом устанавливается
		internal static const _command2SocketConnecting:String = 'Command2SocketConnecting';
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		internal static const _command3SocketWrite:String = 'Command3SocketWrite';
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		internal static const _command4SocketRead:String = 'Command4SocketRead';
	}
}

Непосредственно сами состояния:
Код AS3:
package server_exchange.socket_4444
{
	// Конкретное состояние
	internal class StateName
	{
		// Соединение с сокетом не установлено (ожидаются действия)
		internal static const _state1No:String = 'State1No';
		// Соединение с сокетом устанавливается
		internal static const _state2SocketConnecting:String = 'State2SocketConnecting';
		// Соединение с сокетом успешно установлено (ожидаются действия)
		internal static const _state3SocketEstablished:String = 'State3SocketEstablished';
		// Выполняется отправка данных на сервер
		internal static const _state4SocketReading:String = 'State4SocketReading';
		// Выполняется приём данных с сервера
		internal static const _state5SocketWriting:String = 'State5SocketWriting';
	}
}

Описание состояний:
Код AS3:
package server_exchange.socket_4444
{
	internal class State1No implements IState
	{
		// Состояние
		private var worksSocket:WorksSocket;
 
		public function State1No(worksSocket:WorksSocket)
		{
			this.worksSocket = worksSocket;
		}
 
		// Выполняет команду на соединение с сокетом
		public function Command1SocketConnect():void { }		
		// Связь с сокетом устанавливается
		public function Command2SocketConnecting():void { }
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		public function Command3SocketWrite():void { }
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		public function Command4SocketRead():void { }
 
	}
}
Код AS3:
package server_exchange.socket_4444
{
	internal class State2SocketConnecting implements IState
	{
		// Состояние
		private var worksSocket:WorksSocket;
 
		public function State2SocketConnecting(worksSocket:WorksSocket)
		{
			this.worksSocket = worksSocket;
		}
 
		// Выполняет команду на соединение с сокетом
		public function Command1SocketConnect():void { }		
		// Связь с сокетом устанавливается
		public function Command2SocketConnecting():void { }
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		public function Command3SocketWrite():void { }
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		public function Command4SocketRead():void { }
 
	}
}
Код AS3:
package server_exchange.socket_4444
{
	internal class State3SocketEstablished implements IState
	{
		// Состояние
		private var worksSocket:WorksSocket;
 
		public function State3SocketEstablished(worksSocket:WorksSocket)
		{
			this.worksSocket = worksSocket;
		}
 
		// Выполняет команду на соединение с сокетом
		public function Command1SocketConnect():void { }		
		// Связь с сокетом устанавливается
		public function Command2SocketConnecting():void { }
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		public function Command3SocketWrite():void { }
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		public function Command4SocketRead():void { }
 
	}
}
Код AS3:
package server_exchange.socket_4444
{
	internal class State4SocketReading implements IState
	{
		// Состояние
		private var worksSocket:WorksSocket;
 
		public function State4SocketReading(worksSocket:WorksSocket)
		{
			this.worksSocket = worksSocket;
		}
 
		// Выполняет команду на соединение с сокетом
		public function Command1SocketConnect():void { }		
		// Связь с сокетом устанавливается
		public function Command2SocketConnecting():void { }
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		public function Command3SocketWrite():void { }
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		public function Command4SocketRead():void { }
 
	}
}
Код AS3:
package server_exchange.socket_4444
{
	internal class State5SocketWriting implements IState
	{
		// Состояние
		private var worksSocket:WorksSocket;
 
		public function State5SocketWriting(worksSocket:WorksSocket)
		{
			this.worksSocket = worksSocket;
		}
 
		// Выполняет команду на соединение с сокетом
		public function Command1SocketConnect():void { }		
		// Связь с сокетом устанавливается
		public function Command2SocketConnecting():void { }
		// Связь с сокетом установлена, выполняется отсылка данных на сервер (запись в сокет)
		public function Command3SocketWrite():void { }
		// Связь с сокетом установлена, выполняется приём данных с сервера (чтение из сокета)
		public function Command4SocketRead():void { }
 
	}
}
А экземпляр самого XMLSocket вынести в контекстный класс
Код AS3:
package server_exchange.socket_4444
{
	import flash.net.XMLSocket;
	import flash.events.IEventDispatcher;
	import flash.events.Event;
	import flash.events.DataEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
 
	// Структута соединения на сокет
	internal class StructSocket
	{
		private var socket:XMLSocket;
 
		public function StructSocket()
		{
			this.socket = new XMLSocket();
			configureListeners(socket);
            if (hostName && port) 
			{
                socket.connect(hostName, port);
            }
        }
 
        public function send(data:Object):void 
		{
            socket.send(data);
        }
 
        private function configureListeners(dispatcher:IEventDispatcher):void 
		{
            dispatcher.addEventListener(Event.CLOSE, closeHandler);
            dispatcher.addEventListener(Event.CONNECT, connectHandler);
            dispatcher.addEventListener(DataEvent.DATA, dataHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        }
 
        private function closeHandler(event:Event):void 
		{
            trace("closeHandler: " + event);
        }
 
        private function connectHandler(event:Event):void 
		{
            trace("connectHandler: " + event);
        }
 
        private function dataHandler(event:DataEvent):void 
		{
            trace("dataHandler: " + event);
        }
 
        private function ioErrorHandler(event:IOErrorEvent):void 
		{
            trace("ioErrorHandler: " + event);
        }
 
        private function progressHandler(event:ProgressEvent):void 
		{
            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }
 
        private function securityErrorHandler(event:SecurityErrorEvent):void 
		{
            trace("securityErrorHandler: " + event);
        }
 
	} // Конец класса
} // Конец пакета
тогда в этом случе будет большое нагромождение, что вобщем-то и тормазнуло процесс дальнейшей разработки

Старый 21.03.2013, 09:53
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 12  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
1. Реализовывать наблюдатель не нужно - используйте нативные для AS3 события.
2. Я бы сделал MVC, (не то, что оно тут уместно, но у меня всегда MVC получается
__________________
Отряд Котовскага

Старый 21.03.2013, 10:07
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 13  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
Что касается кода, я только черновые набросочки сделал, но это не окончательный вариант
Жесть. 100% жесть. Вам не код нужно разрабатывать. Вам сначала нужно удобный API для вашей библиотечеки разработать. Чтобы ею было удобно пользоваться. А уже затем что-то внутри проектировать.

Дальше по коду.
Код AS3:
// Реализация шаблона одиночки
private static var _instance:SocketExchange;
Зачем он здесь? Почему данный класс не предоставляет static accessors к своей функциональности? Он же ничем нужным и полезным не параметризуется. А если параметризуется, автоматически могут существовать несколько экземпляров, параметризованных по-разному. И вообще, посмотрите, зачем же используется singleton. Даже там, где его можно было бы использовать, его стоит на нормальный dependency injection переделать.

Код AS3:
// Реализация шаблона наблюдателя
private var mySub:ISubject;
Не было никогда наблюдателя в сетевых обменах. Не было, нет и не будет. Потому что там нет "состояния" в явном виде. Там есть события. Поэтому максимум, что можно сделать - это message bus. Хотя вру, я делал что-то подобное на observer, но это было для состояния одного конкретного обмена, а не для всего уровня коммуникаций. Кстати, а что должен делать клиент, чтобы какой-нибудьб справочник с сервера подгрузить? И зачем там вообще интерфейс, если реализация примерно одна предполагается и не инжектится снаружи?

Код AS3:
// Парсит объекты из XML в Object
this.parsingXMLtoObject = new ParsingXMLtoObject();
Гениально! Если мне захочется использовать этот обмен в другом проекте, мне нужно будет его исходный код менять? Ведь объекты в другом приложении другие, а я люблю их иметь строго типизированными...

Код AS3:
SocketExchange._instance = new SocketExchange(new PrivateClass());
А смысл? Я вам туда null передам и будет у меня второй SocketExchange. И ничего даже не сломается. И даже в некоторых случаях это будет единственным нормальным вариантом использования этой библиотеки (две подписки на "одно и то же" сообщение).

Код AS3:
// Уведомление наблюдателя
function SetParam(obserName:String, objectParam:Object):void;
Почему не notifyObserver то???

Код AS3:
// Реализует процесс подписки
public function AddObserver(obserName:String,obserFunc:Function):void {
  this.observers[obserName] = obserFunc;
}
Угу. Т.е. только один обсервер для события. А если мне нужно два?

Код AS3:
for(var notify:String in this.observers) {
  // Применяется метод update из интерфейса Observer
  if (notify == this.observerName)
А сразу по this.observerName в this.observers не пойти? В чем глубокий смысл то этого цикла?

Код AS3:
this.observerName = obserName;
this.objectParam = objectParam;
this.NotifyObserver();
Обмен данными через поля класса вместо параметров. Типичный антипаттерн. Выпиливается при первом же рефакторинге (и заменяется на параметры). Потому что отлаживать такое счастье тяжелее, чем передачу параметров. И тестировать отдельные функции проще, чем объекты с состоянияем.

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

Код AS3:
internal function set InputData(inputData:Function):void
Вы себя на место пользователя вашей библиотеки ставили? Почему функция "начать загрузку" у вас называется "установить входные данные" и в качестве входных данных устанавливается функция? Ведь не понятно же...

Код AS3:
private function TextError():String
А это должно быть здесь? При переносе этой библиотеки в другой проект мне придется еще и сообщения править. Я всегда думал, что конкретное форматирование ошибок - дело UI-части, а не самого транспорта. А на уровне транспорта нужно предоставить способ различать разные коды ошибок.

Код AS3:
// желательно применить шаблон декоратор к объекту this.xmlDataObject
Зачем там декоратор? Что он будет добавлять?

Код AS3:
var xmlData:XML = XML(e);
О как. А если там не XML? Банальный текст, например (ну не работает сервер)? У вас ведь все умрет (в обычном плеере). Ошибка куда-нибудь улетит и больше не вернется.

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

Ваши парсеры не валидируют структуру. Т.е. у вас все поля опциональные (и весь остальной код к этому должен быть готов).

P.S. Я не помню, что у вас в той библиотеке происходит при двух параллельных запросах (т.е. второй приходит тогда, когда первый еще не отработал). Вроде бы что-то нехорошее...

Старый 21.03.2013, 10:47
yasha005 вне форума Посмотреть профиль Отправить личное сообщение для yasha005 Найти все сообщения от yasha005
  № 14  
Ответить с цитированием
yasha005
[+1 16.03.13]
[+1 22.03.13]

Регистрация: Dec 2012
Сообщений: 100
Цитата:
Сообщение от Котяра Посмотреть сообщение
1. Реализовывать наблюдатель не нужно - используйте нативные для AS3 события.
2. Я бы сделал MVC, (не то, что оно тут уместно, но у меня всегда MVC получается
В теории конечно представление об этом шаблоне есть, но вот на практике ни разу не доводилось его использовать. Учитывая то обстоятельство, что MVC относится к типу множественных шаблонов, то в теории я себе его структуру для моей реализации представляю следующим образом:

Модель - занимается состоянием, значит строим на основе: Наблюдатель или Состояние
Представление - отображает состояние, значит строим на основе: Компановщик или Декоратор
Контроллер - обрабатывает действия, значит строим на основе: Наблюдатель или Состояние

конечно я могу и ошибаться

Цитата:
Сообщение от maxkar Посмотреть сообщение
Жесть. 100% жесть. Вам не код нужно разрабатывать. Вам сначала нужно удобный API для вашей библиотечеки разработать. Чтобы ею было удобно пользоваться. А уже затем что-то внутри проектировать...
В этом я с вами полностью солидарен. Вот только где взять удобный API?

Старый 21.03.2013, 11:06
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 15  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
Вот только где взять удобный API?
Придумать конечно же . Вот в этом в основном и состоит работа программиста (разработчика ПО). Нужно:
1. Понять, чем вообще занимается приложение
2. Понять, как будет устроен обмен с сервером. Подсказка - обмен может быть устроен неоднородно, может быть несколько различных типов обмена.
3. Детализировать и формализовать (не обязательно слишком усердствовать) требования к API (как то обработка ошибок, мониторинг процесса загрузки).
4. Определиться, что может измениться в ближайшее время (неделя, месяц, три месяца, год).
5. Определиться, что вряд ли будет меняться в ближайшее время (месяц, три месяца, год).
6. Сделать draft API. Типичные действия пользователей библиотеки (на момент разработки) должны делаться легко и просто. 90% действий в идеале должны выполняться за 1-3 строчки кода. 1 строчка - идеал, но не всегда достижима. Все зависит от того, насколько "общей" получается задача.
7. Реализовать этот внешний API. О внутренностях можно не очень заботится. При необходимости их можно будет переписать или отрефакторить. Главное, что внешний API будет удобен.
8. На практике отследить, что API действительно удобен. При необходимости исправить API.

Вот примерно в том, что выше, и состоит работа разработчика ПО. А код - это побочный продукт разработки. Через несколько подобных реализаций вы начнете видеть похожие элементы в них и получите несколько удобных кубиков, из которых можно что-то собрать. Только вот "кубики" слишком универсальными все равно не поулчатся. У разных приложений разные требования, разные сценарии работы и т.п. Поэтому процентов 50 вы, может, на кубиках наберете (упрощение API URLLoader'а, какие-то совсем базовые вещи). А остальные 50% все равно придется реализовывать под конкретный проект. То же сетевое API во флеш достаточно высокоуровневое, до API уровня приложения там не так много можно добавить.

Старый 21.03.2013, 11:41
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 16  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
2 yasha005: Это тот случай, когда надо использовать свичи и не плодить классов.

Старый 21.03.2013, 12:05
gagaga вне форума Посмотреть профиль Отправить личное сообщение для gagaga Найти все сообщения от gagaga
  № 17  
Ответить с цитированием
gagaga
[+1 22.04.13]
[+1 06.03.13]

Регистрация: Apr 2012
Сообщений: 239
вы тратите слишком много времени на ерунду (комментирование закрывающих скобок это вообще фаталити)... пишите легкий для восприятия код KISS - keep it simple stupid. Правильно декомпозируйте код, давайте методам понятные имена и всё у вас получится.

Старый 21.03.2013, 12:13
yasha005 вне форума Посмотреть профиль Отправить личное сообщение для yasha005 Найти все сообщения от yasha005
  № 18  
Ответить с цитированием
yasha005
[+1 16.03.13]
[+1 22.03.13]

Регистрация: Dec 2012
Сообщений: 100
Цитата:
Сообщение от maxkar Посмотреть сообщение
Придумать конечно же . Вот в этом в основном и состоит работа программиста (разработчика ПО). Нужно:
1. Понять, чем вообще занимается приложение
2. Понять, как будет устроен обмен с сервером. Подсказка - обмен может быть устроен неоднородно, может быть несколько различных типов обмена.
3. Детализировать и формализовать (не обязательно слишком усердствовать) требования к API (как то обработка ошибок, мониторинг процесса загрузки).
4. Определиться, что может измениться в ближайшее время (неделя, месяц, три месяца, год).
5. Определиться, что вряд ли будет меняться в ближайшее время (месяц, три месяца, год).
6. Сделать draft API. Типичные действия пользователей библиотеки (на момент разработки) должны делаться легко и просто. 90% действий в идеале должны выполняться за 1-3 строчки кода. 1 строчка - идеал, но не всегда достижима. Все зависит от того, насколько "общей" получается задача.
7. Реализовать этот внешний API. О внутренностях можно не очень заботится. При необходимости их можно будет переписать или отрефакторить. Главное, что внешний API будет удобен.
8. На практике отследить, что API действительно удобен. При необходимости исправить API.

Вот примерно в том, что выше, и состоит работа разработчика ПО. А код - это побочный продукт разработки. Через несколько подобных реализаций вы начнете видеть похожие элементы в них и получите несколько удобных кубиков, из которых можно что-то собрать. Только вот "кубики" слишком универсальными все равно не поулчатся. У разных приложений разные требования, разные сценарии работы и т.п. Поэтому процентов 50 вы, может, на кубиках наберете (упрощение API URLLoader'а, какие-то совсем базовые вещи). А остальные 50% все равно придется реализовывать под конкретный проект. То же сетевое API во флеш достаточно высокоуровневое, до API уровня приложения там не так много можно добавить.
1. Само приложение занимается много чем (у меня на его компиляцию, несмотря на то что находится ещё в стадии разработки, уходит порядка 20 минут на компе с 4-хядерным 3-хгигогерцовым процессором) и одним абзацем тут для описания не обойтись
2. Разумеется обмен с сервеном будет неоднородным, единственное что объединяет обмен данных между собой, это то что они в XML формате
3. Обработка ошибок, мониторинг процесса передачи данных, парсинг данных после их принятия с сервера из XML в объект, формирование данных для отправки их на сервер из объекта в XML
4. Возможно, добавятся новые XML объекты (как приёма, так и передачи данных)
5. Возможно, изменятся существующие XML объекты
6. Вот с этим сложнее, почему-то на практике получается, что я хоть и отправляю одни какие-либо данные ввиде объекта-параметра методу нужного класса. В итоге получается что в этот объект приходится запихивать кучу функций, таким образом не получается уложиться в 1-3 строчки.
7. Если это построение структуры, то беру за основу либо шаблон Компановщик, либо Декоратор; если это какое-либо поведение, то беру за основу либо шаблон Наблюдатель, либо Состояние
8. В том плане что шаблон проектировани удобен - тут сомнений нет, другое дело, что он не всегда в тему может оказаться.


За совет, спасибо

Добавлено через 6 минут
Цитата:
Сообщение от expl Посмотреть сообщение
2 yasha005: Это тот случай, когда надо использовать свичи и не плодить классов.
По мне так проще в контекстном классе, метод, который содержит свитчи объявить новый экземпляр класса в каждом кейсе и передать в него this, чем ростить один большой класс и складывать всё туда

Добавлено через 9 минут
Цитата:
Сообщение от gagaga Посмотреть сообщение
вы тратите слишком много времени на ерунду (комментирование закрывающих скобок это вообще фаталити)... пишите легкий для восприятия код KISS - keep it simple stupid. Правильно декомпозируйте код, давайте методам понятные имена и всё у вас получится.
Комментирую окончание метода или класса, чтобы удобнее было определять где начинается и где заканчивается, если в случае надобности добавлять что-то ещё.

Старый 21.03.2013, 12:55
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 19  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
И самое главное!
Начните с использования конвенций наименований, принятых в AS3.
__________________
Отряд Котовскага

Старый 21.03.2013, 13:02
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 20  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Ну время сборки это не принципиально. Оно еще и зависит от используемых инструментов. Да и штатный компилятор параллелить не умеет вроде бы сборку, так что задействовано одно ядро.

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

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

Цитата:
Вот с этим сложнее, почему-то на практике получается, что я хоть и отправляю одни какие-либо данные ввиде объекта-параметра методу нужного класса. В итоге получается что в этот объект приходится запихивать кучу функций, таким образом не получается уложиться в 1-3 строчки.
Зачем вы все параметры запихиваете в один объект? Почему бы их не передать отдельными параметрами в функцию? Может быть, вы чего-то лишнего из-за своих шаблонов хотите от пользователя. Что может быть проще "синхронного" сетевого обмена? Адрес/название службы, входной параметр, обработчик результата, список и обработчики поддерживаемых ошибок. Все. Один вызов в одну строку. Откуда там еще какие-то параметры берутся?

Цитата:
Если это построение структуры, то беру за основу либо шаблон Компановщик, либо Декоратор; если это какое-либо поведение, то беру за основу либо шаблон Наблюдатель, либо Состояние
Ни "наблюдатель", ни "состояние" не являются поведенческими шаблонами! Это в основном вариации как раз на тему глобального состояния. Фактически, это и есть реализация заката солнца вручную state monad в каждом удобном месте. В идеале это все загоняется в библиотеку и никаких ручных наблюдателей и состояний обычно не нужно. Вся композиция с использованием pure functions. Ну и некоторые обработки когда уже "совсем все завершилось", конечно. Декоратор - специфичный шаблон. Он применим в некоторых узких случаях (хотя да, там действительно применим). Кто такое "компоновщик" я не знаю, как он по-английски зовется? В общем, это все фигня. Основным приемом должна быть функциональная композиция и декомпозиция. В идеале вообще на функциях, но иногда можно и на интерфейсах. Для практики стоило бы на каком-нибудь из диалектов ml'а пописать. Ну или на haskell, но там слишком много своей специфики (хотя, если не увлекаться монадами, тоже будет нормально). После этого вы поймете, что декоратор - частный случай обычной функциональной декомпозиции.

Цитата:
В том плане что шаблон проектировани удобен - тут сомнений нет, другое дело, что он не всегда в тему может оказаться.
Да не нужно же шаблонов! Я про API говорю. Если вы хотите от пользователя реализации какого-то "шаблона" для использования библиотеки, ваша библиотека моментально отправится в мусор. Именно API должно быть удобным. Используется ли там какой-нибудь паттерн или нет - дело второе. Как раз обычно при хорошем API никаких особых паттернов не видно, оно используется "естественным образом". Причем для удобного API порой необходимы приемы, которые в паттернах не рассматриваются.

Создать новую тему Ответ Часовой пояс GMT +4, время: 17:26.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 17:26.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.