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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 08.05.2011, 01:55
honest_man вне форума Посмотреть профиль Отправить личное сообщение для honest_man Найти все сообщения от honest_man
  № 21  
Ответить с цитированием
honest_man

Регистрация: Aug 2010
Сообщений: 86
Цитата:
Сообщение от expl Посмотреть сообщение
А что это меняет?
Как это что. Программист А специально реорганизовал класс, чтоб программисту В был кукиш. =) Пусть с нуля создает, а не спиногрызит тут.

Хотя с другой стороны программист А тоже хорош, пусть не мешает личное с делами...

Уволить обоих! И нанять программистов C & D!


Последний раз редактировалось honest_man; 08.05.2011 в 01:59.
Старый 08.05.2011, 02:08
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 22  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Цитата:
Сообщение от Crazy Посмотреть сообщение
Де-факто человек, проектирующий обычный класс, как правило не задается вопросом "что будет, если от этого класса будут наследоваться".
Такие люди хорошо лечатся написанием юнит тестов. Вообще, у юнит тестов оказалось много позитивных эффектов не связаных напрямую с тестированием. Так, например, удалось донести до молодого сотрудника вредность синглтонов. Ну и тот факт, что для написания юнит теста очень часто нужно наследоваться от тестируемого класса просто заставляет писать так, чтобы наследование работало, ну, или по крайней мере заставляет задуматься о такой возможности.

Есть еще такой момент - я, (все еще) почему-то предполагаю, что человека, который будет использовать мой код возможно заинтересует реализация, и при наследовании он не будет делать каких-то явных глупостей. Увы, так не работает. И если необходимо получить результат не взирая на "идиотов" сотрудников, которым жалко лишний раз посмотреть чужой исходник... да, иногда наверное не помешает и final...
__________________
Hell is the possibility of sanity

Старый 08.05.2011, 02:55
Crazy вне форума Посмотреть профиль Отправить личное сообщение для Crazy Посетить домашнюю страницу Crazy Найти все сообщения от Crazy
  № 23  
Ответить с цитированием
Crazy
[+1 23.05.11]
 
Аватар для Crazy

Регистрация: Dec 2001
Сообщений: 4,159
Цитата:
Сообщение от wvxvw Посмотреть сообщение
Такие люди хорошо лечатся написанием юнит тестов.
К сожалению, это помогает не всегда. Качественные юнит-тесты встречаются реже, чем многие думают. Думаю, не ошибусь, если предположу, что три четверти здешнего контингента их вообще не пишет.

Где-то с год назад мне довелось поработать с кодом большого сторонника модульных тестов. Покрытие -- свыше 95%. При этом "работа над ошибками" показала, что в оставшиеся 5% аккуратно вошли разные аномальные состояния. Тесты -- работают. А если вдруг из стороннего модуля исключение прилетит -- вся система в алмазный дым обращается. А юнит-тестов при этом -- процентов на 20 больше, чем "полезного" кода.

Цитата:
для написания юнит теста очень часто нужно наследоваться от тестируемого класса
Поступаю так временами. Во всех случаях -- в лично моей практике -- это оказывается следствием огрехов проектирования.

Цитата:
Есть еще такой момент - я, (все еще) почему-то предполагаю, что человека, который будет использовать мой код возможно заинтересует реализация, и при наследовании он не будет делать каких-то явных глупостей. Увы, так не работает. И если необходимо получить результат не взирая на "идиотов" сотрудников, которым жалко лишний раз посмотреть чужой исходник... да, иногда наверное не помешает и final...
Здесь, как мне кажется, спутано теплое с мягким. Если некто наследует от чужого класса и тщательно изучает при этом его код -- это никак не страхует от правок, позднее внесенных автором родительского класса. А автор родительского класса, если специально не предназначал свой класс для наследования, на практике редко находит время для инспекции всех внезапных потомков его класса. И идиоты здесь совершенно параллельны.
__________________
GIT d++ s++:++ a C++$ UB++ P++ L+ E+ W+++ N++ w++ O+ M V- t-- 5-- X+ R+++ tv- b+++ D++

Старый 08.05.2011, 11:23
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 24  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
Да, я о другом
Вот, непридуманная ситуация, буквально пару дней назад. Был у меня класс, в котором была переменная хранившая XML. Этот класс должен был использоваться другим человеком. Если занулить / не инициализировать переменную, то были бы ошибки, и очевидно поэтому человек использовавший мой класс решил сделать следующее: _xml = new XML() (и заработало, но не совсем...). Я не предполагал, что XML в этом месте может быть не элементом, а текстом, например. Я когда увидел, чуть не заплакал. Переделал переменную в константу - стало менее удобно, но без ошибок.

Ну а если я что-то поменял в моем классе, что потенциально приведет в нерабочее состояние чужой код - ну так я, чисто по-человечески должен хотя-бы в коммит-лог об этом написать. Опять же, юнит тесты с большой вероятностью покажут, что я что-то сломал, если сломал. Ну и я делаю так: public и protected, если я меняю, я дописываю [Deprecated] и оставляю так на несколько версий, пока все не переделают под новый вариант. То, что я не предполагаю, что другие будут использовать - private / internal. Если кто-то использовал internal - на свой страх и риск, и если не работает / перестало - не мои проблемы.
__________________
Hell is the possibility of sanity

Старый 08.05.2011, 12:23
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 25  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Так, например, удалось донести до молодого сотрудника вредность синглтонов.
Меня не вылечило Ситуация обратная - если тянуть ссылку на класс - надо перелопатить 10 тестов, если обращаться в тестируемом классе к синглтону (в тесте, конечно, аккуратно снаружи подменить синглик моком) - то 1 тест. Чего-то идет не так...

Хотя с другой стороны, эти 10 тестов, в которых ни слухом - ни духом о реальном, не замененном моком синглике - могут однажды повести себя неадекватно.


Последний раз редактировалось expl; 08.05.2011 в 12:26.
Старый 08.05.2011, 12:45
Crazy вне форума Посмотреть профиль Отправить личное сообщение для Crazy Посетить домашнюю страницу Crazy Найти все сообщения от Crazy
  № 26  
Ответить с цитированием
Crazy
[+1 23.05.11]
 
Аватар для Crazy

Регистрация: Dec 2001
Сообщений: 4,159
Цитата:
Сообщение от expl Посмотреть сообщение
Меня не вылечило Ситуация обратная - если тянуть ссылку на класс

...то синглетон для этого не нужен. Применяемая для этого конструкция похожа, но не имеет к синглетону никакого отношения.
__________________
GIT d++ s++:++ a C++$ UB++ P++ L+ E+ W+++ N++ w++ O+ M V- t-- 5-- X+ R+++ tv- b+++ D++

Старый 08.05.2011, 13:58
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 27  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Имеете в виду статическую фабрику?
Код AS3:
public function ServiceOwner
{
    private var _service:IService;
    public static function get service():IService
    {
          if (_service == null)
          {
               _service = new MyService();
           }
           return _service;
    }
}
Ну да, преимуществ по сравнению с сингилком 2: Нет ограничения на количество сервисов, код сервиса свободен от выполнения обязанностей по контролю за своим инштанцированием. Но на них и забить можно - тупо _не_ запрещать синглику инштанцироваться вне getInstance() - кому второй синглик понадобится - фабрику се сделает.


Последний раз редактировалось expl; 08.05.2011 в 14:01.
Старый 08.05.2011, 17:57
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 28  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
expl.
ОК, пример
Код AS3:
package tests
{
	import com.***.net.tcp.NinjaEvent;
	import com.***.net.tcp.NinjaMethods;
	import com.***.net.tcp.NinjaService;
 
	import flash.events.Event;
 
	import flexunit.framework.Assert;
 
	import org.flexunit.async.Async;
 
	public class TestNinjaKillActivity
	{
		private var _activityDead:Boolean;
		// Падаван хотел это сделать синглотоном :) А тут внезапно их два - облом :)
		private var _sender:NinjaService = 
			new NinjaService("123456", "127.0.0.1");
		private var _receiver:NinjaService = 
			new NinjaService("654321", "127.0.0.1");
 
		public function TestNinjaKillActivity() { super(); }
 
		[Before(async)]
		public function before():void
		{
			this._sender.addEventListener(Event.CONNECT, this.sender_connectHandler);
			this._receiver.addEventListener(
				Event.CONNECT, this.receiver_connectHandler);
			this._receiver.addEventListener(
				NinjaEvent.GET_ACTION, this.getActionHandler);
			this._receiver.addEventListener(
				NinjaEvent.CALL_RECEIVED, this.receiver_callReceivedHandler);
			this._sender.addEventListener(
				NinjaEvent.CALL_STARTED, this.sender_callStartedHandler);
			Async.proceedOnEvent(this, this._receiver, "test", 10000);
			this._sender.connect();
			this._receiver.connect();
		}
 
		private function sender_connectHandler(event:Event):void
		{
			if (this._receiver.connected) this.bothConnected();
			trace("sender_connectHandler");
		}
 
		private function receiver_connectHandler(event:Event):void
		{
			if (this._sender.connected) this.bothConnected();
			trace("receiver_connectHandler");
		}
 
		private function sender_callStartedHandler(event:NinjaEvent):void
		{
			this.killActivity();
			trace("sender_callStartedHandler");
		}
 
		private function receiver_callReceivedHandler(event:NinjaEvent):void
		{
			(this._receiver.methods as NinjaMethods)
			.acceptCall(this._sender.clientId);
			trace("receiver_callReceivedHandler");
		}
 
		public function bothConnected():void
		{
			(this._sender.methods as NinjaMethods)
			.startCall(this._receiver.clientId, "externalId", "a", "b", "c", "d");
			trace("bothConnected");
		}
 
		private function killActivity():void
		{
			(this._sender.methods as NinjaMethods)
				.killActivity(this._receiver.clientId);
		}
 
		private function getActionHandler(event:NinjaEvent):void
		{
			this._activityDead = true;
			this._receiver.dispatchEvent(new Event("test"));
			this.testReceive();
			trace("getActionHandler");
		}
 
		[Test(async, timeout="10000")]
		public function testReceive():void
		{
			Assert.assertTrue(this._activityDead);
		}
	}
}
(Названия не я придумывал, это тяжелое наследие царского режима).
__________________
Hell is the possibility of sanity

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

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Ага, как обломали подавана, понятно (ох, как я часто от коллег слышу "А давай этот класс сделаем синглтоном" - хочется увесистой книжкой по пальцам сразу).
А вот как вы ссылки тянете на эти сервисы в клиентские классы не очень.

Например есть модель:
- Юзер
--деревня
---грядка
Главный контроллер (его я даже не пытаюсь покрыть unit-тестами - он завязан на все и вся, но сложной логики там мало, большинство делегируется его детям и модели) инштанцирует СинхронизаторВремениССервером.
Если передавать его всем детям в стиле "push" получается:
- надо протащить ссылки через Юзера и деревню
- надо каждый раз передавать грядке синхронизатор при ее добавлении

Получается лезем в тесты Юзера и деревни, чтобы добавить в конструктор этот сервис (допустим, он нужен только грядке)
То что в тестах деревни может что-то зависеть от синхронизатора, который находится в Грядке - это другой вопрос.


Последний раз редактировалось expl; 08.05.2011 в 20:20.
Старый 08.05.2011, 21:30
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 30  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
К сожалению, в реальном проекте взаимодействие между частями - это вотчина падавана (он там работает на 2 года больше меня, и мне поэтому ничего "серьезного" не доверяют... ну так вот ). На то, что там происходит без слез / смеха смотреть тяжело... Так что, как "у нас", уж наверняка лучше не делать.
Так, как я бы делал - иерархия, ребенок сообщает наверх, и не его забота кто и как обработает, даже ни на что не подписывается, когда надо будет, ему родитель "скажет" что делать.
__________________
Hell is the possibility of sanity

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

Теги
final , код , скорость , функция
Опции темы
Опции просмотра

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

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


 


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


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