Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> презумпция инкапсуляции, обязательное сокрытие полей класса 
:(
    Опции темы
Pawl
Дата 30.5.2014, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Каждый маленький программист, можно сказать, с молоком матери впитывает идею постоянного сокрытия данных, и, если в методах класса с модификатором public ему приходится мириться, то вот поля обязательно должны быть private или уж на крайняк protected! Со временем это переходит в ритуал, благодаря которому для простого доступа или изменения полей класса надо писать еще дополнительный код стандартных геттеров/сеттеров. Веселуха начинается при написании какого-либо java-класса PODJO типа сущностей для доступа к таблицам в БД с десятком-другим полей в каждой, или action'ов из фрэймворка Struts2. Тогда программа обрастает прям километрами кода. Честно, не понимаю, зачем для простого получения/изменения значения поля обязательно нужны некие костыли? Допускаю необходимость инкапсуляции - в разумных пределах, но писать код типа
Код

public class Point {
    private double x, y;
   
    public void setX(double x) {
        this.x = x;
    }

    public double getX() {
        return x;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double getY() {
        return y;
    }
}

и потом обращаться к х и у через point.getX() / point.setX(х) считаю явным излишеством. В этом случае гораздо проще использовать для полей модификатор public и обращаться к ним напрямую:
Код

public class Point {
    public double x, y;
}

 В С#, на сколько я знаю, для этого есть сахарные костыли, называемые свойствами, которые имитируют прямой доступ к переменной: point.х = х. Для этого класс Point надо оформить так:
Код

    class Point
    {
        public double x { get; set; }
        public double y { get; set; }
    }

Данный код выглядит значительно короче, чем в java, но по поведению также практически ничем не отличается от кода 
Код

    class Point
    {
        public double x;
        public double y;
    }

Видимо, java-сообщество просекло фишку и создало библиотеку lombok, с помощью которой можно сократить код до
Код

public class Point {
    @Getter @Setter
    private double x, y;
}

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


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Guinness
Дата 30.5.2014, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: нет
Всего: 10



Цитата(Pawl @  30.5.2014,  10:17 Найти цитируемый пост)
А насколько было бы проще жить, если не возводить инкапсуляцию данных в священную догму! 

А что если потом придётся делать некие проверки при установке или передаче этих значений? Весь код, который использует данные переменные придётся переписывать.
Цитата(Pawl @  30.5.2014,  10:17 Найти цитируемый пост)

 В С#, на сколько я знаю, для этого есть сахарные костыли, называемые свойствами, которые имитируют прямой доступ к переменной: point.х = х. 

Имхо, нихрена это не костыли. Для меня это очень большой плюс в сравнении с плюсами, к примеру, на которых я пишу большую часть кода.
PM MAIL   Вверх
Alexeis
Дата 30.5.2014, 09:49 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 14
Всего: 459



  А я не парюсь при использовании тривиальных полей, пихаю их в паблик и пошло оно все лесом. На крайняк всегда есть рефракторниг и ctr+shift+f .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Pawl
Дата 30.5.2014, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(Guinness @  30.5.2014,  09:34 Найти цитируемый пост)
А что если потом придётся делать некие проверки при установке или передаче этих значений? 

Цитата(Pawl @  30.5.2014,  09:17 Найти цитируемый пост)
Допускаю необходимость инкапсуляции - в разумных пределах,

Цитата(Guinness @  30.5.2014,  09:34 Найти цитируемый пост)
Для меня это очень большой плюс 

И в чём же плюс?


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 30.5.2014, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  30.5.2014,  11:03 Найти цитируемый пост)
И в чём же плюс?

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


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 30.5.2014, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  30.5.2014,  10:18 Найти цитируемый пост)
Возможность быстро создать пропертю, в которую потом при необходимости легко добавить, без рефакторинга и перекомпиляции, нужные проверки.

Согласен, это плюс. Но, к примеру, в классах-сущностях проверки можно осуществлять и при помощи аннотаций к полям:
Код

@Column(name = "password", unique = true, nullable = false, length = 30)



--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
diadiavova
Дата 30.5.2014, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Pawl, а чем не устраивает то объяснение, которое дается в любом пособии для начинающего программиста? smile По мере развития проекта может возникнуть ряд ситуаций, как то: 
1. При тестировании может выяснится, что некоторые значения переданные полю, приводят к некорректной работе класса. В данном случае может возникнуть необходимость либо корректировать налету полученное значение либо отклонять изменение значения.
2. Существует вероятность того, что в процессе развития проекта может возникнуть необходимость уведомлять заинтересованные стороны о том, что значение поля изменилось, либо кто-то пытается его изменить. 
3. Для оптимизации работы класса может понадобиться, к примеру, ленивая инициализация значения (то есть объект создается при первом обращении к свойству, в противном случае не создается вообще).

Во всех этих случаях прямое обращение к полю может привести к необходимости переписывать туеву хучу кода.

Цитата(Pawl @  30.5.2014,  10:17 Найти цитируемый пост)
 В С#, на сколько я знаю, для этого есть сахарные костыли, называемые свойствами, которые имитируют прямой доступ к переменной: point.х = х. Для этого класс Point надо оформить так:

Не имитируют. То, что ты привел - это т.н. автоматически реализуемое свойство. Его объявление мало чем отличается от объявления поля, но фактически компилятор создает обычные акцессоры свойства со стандартным кодом. Для них всегда можно описать реализацию вручную с тем же успехом. Надо сказать, что автоматическая реализация - сама по себе очень крутая штука и сильно сокращает количество кода. Но, в то же время, даже когда ее не было (в шарпе она появилась в 2005-м, а в бейсике в  2008-м), свойства все равно отчасти решали описанную тобой проблему. Дело в том, что в языках, где есть свойства, инкапсуляция доступа к полям  в принципе не так критична. Несмотря на то, что во всех учебниках пишут о том, что публичные поля - зло, тем не мене, в языках со свойствами поле почти всегда можно совершенно безболезненно заменить свойством, если такая необходимость возникла(есть пара  случаев исключения, но в основном они не критичны).
Цитата(Alexeis @  30.5.2014,  10:49 Найти цитируемый пост)
 А я не парюсь при использовании тривиальных полей, пихаю их в паблик и пошло оно все лесом. На крайняк всегда есть рефракторниг и ctr+shift+f . 

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


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Pawl
Дата 30.5.2014, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(diadiavova @  30.5.2014,  11:01 Найти цитируемый пост)
а чем не устраивает то объяснение, которое дается в любом пособии для начинающего программиста? По мере развития проекта может возникнуть ряд ситуаций, как то: 

Ну так вы, можно сказать, сами и ответили на свой вопрос:
Цитата(diadiavova @  30.5.2014,  11:01 Найти цитируемый пост)
 в языках со свойствами поле почти всегда можно совершенно безболезненно заменить свойством, если такая необходимость возникла(есть пара  случаев исключения, но в основном они не критичны).

Т. е. Можно написать так:
Код

    class Point
    {
        public double x, y;
    }

и при необходимости заменить поля свойствами с необходимыми проверками. При этом доступ из других классов как был point.х, так и останется point.х, т. е. их модифицировать не понадобится.

Это сообщение отредактировал(а) Pawl - 30.5.2014, 11:18


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
diadiavova
Дата 30.5.2014, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(Pawl @  30.5.2014,  12:14 Найти цитируемый пост)
Ну так вы, можно сказать, сами и ответили на свой вопрос:

Я не задавал вопросов, а попытался ответить на твой.
Цитата(Pawl @  30.5.2014,  12:14 Найти цитируемый пост)
Т. е. Можно вначале написать так:

Ну так на C# можно. Это не будет работать при обращении к свойствам через рефлексию, а так же, если код вызывается из проекта написанного на языке, в котором нет свойств. Например был в семействе дотнет-языков такой язык как J# (на заре развития технологии с его помощью пытались привлечь ява-программистов). В нем свойств нет, и обращаться приходится к методам-акцессорам непосредственно. Но такие языки мало распространены, так что большой проблемы в этом нет. А так вообще да, свойства в принципе для этого и существуют. Когда я интересовался явой, то одной из причин, по которой я оставил эти попытки было именно отсутствие свойств, поскольку к хорошему быстро привыкаешь.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Pawl
Дата 30.5.2014, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(diadiavova @  30.5.2014,  11:20 Найти цитируемый пост)
Когда я интересовался явой, то одной из причин, по которой я оставил эти попытки было именно отсутствие свойств, поскольку к хорошему быстро привыкаешь.

Думаю теперь, когда Оракл обязался выпускать по новой версии java не  реже, чем раз в 2 года, свойства в ней тоже появятся и причины для принудительной инкапсуляции со временем исчезнут smile - с учетом того, что свойства во многих языках программирования уже реализованы, а в с++ тоже могут появиться. По крайней мере, потребность в них есть, т. к. люди извращаются, чтобы реализовать их самостоятельно.


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 30.5.2014, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(diadiavova @  30.5.2014,  12:01 Найти цитируемый пост)
Несмотря на то, что во всех учебниках пишут о том, что публичные поля - зло, тем не мене, в языках со свойствами поле почти всегда можно совершенно безболезненно заменить свойством, если такая необходимость возникла(есть пара  случаев исключения, но в основном они не критичны).

Перекомпиляция все же потребуется.


Цитата(Pawl @  30.5.2014,  11:38 Найти цитируемый пост)
Но, к примеру, в классах-сущностях проверки можно осуществлять и при помощи аннотаций к полям:

Метода акцессоры можно мокать, а вот доступ к полям фиг замокаешь.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Alexeis
Дата 30.5.2014, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 14
Всего: 459



Цитата(diadiavova @  30.5.2014,  12:01 Найти цитируемый пост)
А если ты пишешь библиотеку, которую используют десятки других разработчиков, которые обращаются к полю класса в сотне различных мест, а потом всякий раз, когда оказалось, что поле надо заменить методами, будешь предлагать и им тоже все это дело рефакторить?

  Pawl привел тривиальный случай и я, собственно, в этом контексте комментировал. То что ты описал никак нельзя назвать тривиальным случаем. Это только быдло кодеры пишут класс и не представляют себе как его потом будут использовать. При конструировании программы от простого к сложному заранее понятно, что точка это пассивный объект из 2-3 полей и из нее никто не будет строить в последствии объект с виртуальными функциями и т.д. В С++ есть даже такое понятие как POD тип Plain Old Data, т.е. тип, который устроен так как описан. На самом деле, очень здорово, когда простые вещи устроены простым образом, это делает код прозрачным. Программист, который читает такой код не вынужден каждый раз обращаться в реализации функции GetX чтобы убедиться в том, что ее реализация тривиальна. Экономиться куча времени на чтении и куча времени на компиляции.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
diadiavova
Дата 30.5.2014, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(Pawl @  30.5.2014,  13:23 Найти цитируемый пост)
Думаю теперь, когда Оракл обязался выпускать по новой версии java не  реже, чем раз в 2 года, свойства в ней тоже появятся и причины для принудительной инкапсуляции со временем исчезнут 

Автоматически реализуемые свойства вообще никаких проблем с разрастанием кода не создают, так что лучше уж их использовать, если они есть. Да и не факт, что свойства появятся. Насколько мне известно, Сан не добавлял новые фичи в язык потому, что считали все это веяниями моды и не  хотели засорять ими язык. Что будет делать Оракл - неизвестно, хотя, вроде кое-что уже сделал полезное(лямбды замыкания и прочее).

Цитата(Pawl @  30.5.2014,  13:23 Найти цитируемый пост)
 с учетом того, что свойства во многих языках программирования уже реализованы

Даже в яваскрипте есть уже smile 
Цитата(LSD @  30.5.2014,  13:45 Найти цитируемый пост)
Перекомпиляция все же потребуется.

Да. Но она обычно и так выполняется время от времени. Хотя согласен, что лучше такими заменами не злоупотреблять.

Цитата(Alexeis @  30.5.2014,  16:27 Найти цитируемый пост)
 Pawl привел тривиальный случай и я, собственно, в этом контексте комментировал. 

Он вроде там приводил пример с сущностями для доступа к объектам датабазы. Ну так такие классы обычно генерируются автоматически, а писать их руками - чистой воды извращение smile 
Цитата(Alexeis @  30.5.2014,  16:27 Найти цитируемый пост)
 Это только быдло кодеры пишут класс и не представляют себе как его потом будут использовать.

Я не об этом написал. Я написал о том, что код, который пишешь ты, возможно будут использовать другие разработчики и просить их каждый раз, чтобы они рефакторили свой код из-за того, что ты поленился описать акцессоры можно до поры до времени, но если делать это постоянно, то тебе могут устроить "тёмную" smile 
Цитата(Alexeis @  30.5.2014,  16:27 Найти цитируемый пост)
 При конструировании программы от простого к сложному заранее понятно, что точка это пассивный объект из 2-3 полей и из нее никто не будет строить в последствии объект с виртуальными функциями и т.д. В С++ есть даже такое понятие как POD тип Plain Old Data, т.е. тип, который устроен так как описан. На самом деле, очень здорово, когда простые вещи устроены простым образом, это делает код прозрачным.
 Но ты ведь в данном случае написал, что таки возникают проблемы с этим и порой приходится рефакторить. Так что простота не гарантирует отсутствия проблем в будущем.
А вообще, при наличии нормальных инструментов, тривиальный код генерируется автоматически. Думаю, что для любой ява-иде такие инструменты, которые ну по крайней мере код акцессоров генерят, найти вполне можно. Поэтому проблемы в этом не вижу.



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Alexeis
Дата 30.5.2014, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 14
Всего: 459



Цитата(diadiavova @  30.5.2014,  17:29 Найти цитируемый пост)
Но ты ведь в данном случае написал, что таки возникают проблемы с этим и порой приходится рефакторить. Так что простота не гарантирует отсутствия проблем в будущем.

   Простые классы просто рефракторятся, но этого как правило и не требуется. 
Цитата(diadiavova @  30.5.2014,  17:29 Найти цитируемый пост)
А вообще, при наличии нормальных инструментов, тривиальный код генерируется автоматически. Думаю, что для любой ява-иде такие инструменты, которые ну по крайней мере код акцессоров генерят, найти вполне можно. Поэтому проблемы в этом не вижу.

  Тебе наверное редко приходиться читать чужой код без комментов. Иногда берешь чужую прогу и хочется убить автора. Там где можно написать решение в 100 строк, обнаруживаешь 1500 вот таких вот пустых строк и вдобавок непонятные иерархии, наследования виртуальные функции и т.д. Раздувают общее решение для узкой задачи.
  Программист не должен быть заложником ООП. ООП нужен там где он нужен, а там где не нужен, то нужно писать простой компактный читабельный код, который не нуждается в документировании и даже комментариях.

Цитата(diadiavova @  30.5.2014,  17:29 Найти цитируемый пост)
Он вроде там приводил пример с сущностями для доступа к объектам датабазы. Ну так такие классы обычно генерируются автоматически, а писать их руками - чистой воды извращение 

  У меня нет проблем со скоростью печати. Пока обдумываешь решение хватает времени не то что гетеры с сетерами налепить руками, а еще сделать выравнивания, отступы пробелы и прочий марафет облегчающий восприятие кода.

Цитата(diadiavova @  30.5.2014,  17:29 Найти цитируемый пост)
 Я написал о том, что код, который пишешь ты, возможно будут использовать другие разработчики и просить их каждый раз, чтобы они рефакторили свой код из-за того, что ты поленился описать акцессоры можно до поры до времени, но если делать это постоянно, то тебе могут устроить "тёмную"

  Нетривиальный код, который будут читать другие люди, вообще желательно строить на абстрактных классах, чтобы человек видел только то что ему может понадобиться. Но в этой теме поднят вопрос целесообразности применения ООП в тривиальных ситуациях. Я поддерживаю автора. Фтопку ООП когда оно не нужно. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
diadiavova
Дата 30.5.2014, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(Alexeis @  30.5.2014,  21:48 Найти цитируемый пост)
Простые классы просто рефракторятся

Да, но как я уже написал, делать это, возможно, придется не только тебе одному. А если все будут поступать так же, то работенки прибавится всем и немало.
Цитата(Alexeis @  30.5.2014,  21:48 Найти цитируемый пост)
Тебе наверное редко приходиться читать чужой код без комментов.

Я тут вообще ни при чем. В случае со мной публичное поле объявляется так
Код

Public X As Double
А публичное (по умолчанию) свойство так
Код

Property X As Double
И мне сложно представить аргументы в пользу того, чтобы отдать предпочтение первому варианту, но если они у тебя есть, то я весь - внимание.
Цитата(Alexeis @  30.5.2014,  21:48 Найти цитируемый пост)
Программист не должен быть заложником ООП. ООП нужен там где он нужен, а там где не нужен, то нужно писать простой компактный читабельный код, который не нуждается в документировании и даже комментариях.
Согласен полностью, только не знаю, при чем тут ООП. Обеспечивать доступ к данным из одного места программистов научила практика. Для случаев, когда можно быть уверенным, что никакое изменение порядка доступа к полю не потребуется, я ничего против паблик-полей не имею. Мало того, в литературе мне встречалось утверждение, что, например, в структурах паблик-поля - вообще обычное дело. В принципе догматизм - это всегда плохо, всегда надо не только знать как что сделать, но и понимать почему. Тем не менее иметь в виду возможное(но не очевидное в данный момент) изменение условий - совсем не лишняя предосторожность ибо ситуации такие не редки.

Цитата(Alexeis @  30.5.2014,  21:48 Найти цитируемый пост)
У меня нет проблем со скоростью печати. Пока обдумываешь решение хватает времени не то что гетеры с сетерами налепить руками, а еще сделать выравнивания, отступы пробелы и прочий марафет облегчающий восприятие кода.

А у меня есть, да и отступы руками делать не привык, поскольку иде с этим прекрасно справляется. И вообще, чем меньше кнопок приходится жать - тем лучше smile 
Цитата(Alexeis @  30.5.2014,  21:48 Найти цитируемый пост)
 Нетривиальный код, который будут читать другие люди

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


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Pawl
Дата 1.6.2014, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(diadiavova @  30.5.2014,  23:55 Найти цитируемый пост)
Я тут вообще ни при чем. В случае со мной публичное поле объявляется так
код VB.NET
1:

Public X As Double




А публичное (по умолчанию) свойство так
код VB.NET
1:

Property X As Double




И мне сложно представить аргументы в пользу того, чтобы отдать предпочтение первому варианту, но если они у тебя есть, то я весь - внимание.

В плане свойств да, тут безусловно большой профит, убедили! smile Возможно, пиши я изначально на C#, я бы эту тему вообще не создал. Но сейчас я согласен, что
Цитата(diadiavova @  30.5.2014,  23:55 Найти цитируемый пост)
В принципе догматизм - это всегда плохо, всегда надо не только знать как что сделать, но и понимать почему.
 Поэтому 
Цитата(Alexeis @  30.5.2014,  20:48 Найти цитируемый пост)
Фтопку ООП когда оно не нужно.
 smile 
Цитата(diadiavova @  30.5.2014,  16:29 Найти цитируемый пост)
Ну так такие классы обычно генерируются автоматически,

Цитата(diadiavova @  30.5.2014,  23:55 Найти цитируемый пост)
да и отступы руками делать не привык, поскольку иде с этим прекрасно справляется. И вообще, чем меньше кнопок приходится жать - тем лучше 

Автоматически генерируемый код - это, конечно, хорошо, но его
Цитата(Alexeis @  30.5.2014,  20:48 Найти цитируемый пост)
будут читать другие люди

А ИДЕ иногда такого нагородит, что потом сам можешь не понять, что к чему.
 smile 
Цитата(diadiavova @  30.5.2014,  23:55 Найти цитируемый пост)
Обеспечивать доступ к данным из одного места 

Не будем уточнять, из какого! smile 





Это сообщение отредактировал(а) Pawl - 1.6.2014, 09:40


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
diadiavova
Дата 1.6.2014, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(Pawl @  1.6.2014,  10:38 Найти цитируемый пост)
Поэтому 

Я уже сказал, что ООП здесь вообще ни при чем. Если ты уверен, что ситуации, в которой это может стать проблемой, не может возникнуть в принципе, то поступай как тебе удобно. Но ведь не все же от тебя зависит.
Цитата(Pawl @  1.6.2014,  10:38 Найти цитируемый пост)
А ИДЕ иногда такого нагородит, что потом сам можешь не понять, что к чему.

Тут есть несколько возражений:
1. Изначально мы говорили о тривиальных случаях, а с ними любой инструмент кодогенерации справляется на ура, да и читается все хорошо.
2. Читать сгенерированный код в принципе не обязательно, обычно он используется как внешняя библиотека и проблем это не создает.
3. Много зависит от того, что именно ты используешь для кодогенерации, насколько надежен инструмент и какие возможности дает тебе язык, на котором ты пишешь. К примеру в C# и VB.Net есть такая штука как partial-классы. То есть код одного класса можно описать в разных файлах. Кроме того в одном файле может быть несколько классов, среди которых могут быть и частичные. Такой подход позволяет безболезненно использовать инструменты кодогенерации, посколько автоматически генерируемый код можно легко отделить от ручного. Таким образом сгенерированные файлы вообще даже открывать не обязательно, а на их содержимое можно влиять только через визуальный дизайнер к примеру и при любом изменении в дизайнере файл переписывается полностью. Обычно это работает достаточно надежно.
Цитата(Pawl @  1.6.2014,  10:38 Найти цитируемый пост)
Не будем уточнять, из какого!

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


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Pawl
Дата 1.6.2014, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(diadiavova @  1.6.2014,  13:45 Найти цитируемый пост)
 К примеру в C# и VB.Net есть такая штука как partial-классы. То есть код одного класса можно описать в разных файлах. Кроме того в одном файле может быть несколько классов, среди которых могут быть и частичные. Такой подход позволяет безболезненно использовать инструменты кодогенерации, посколько автоматически генерируемый код можно легко отделить от ручного.

Согласен, удобная штука. Надо будет как-нить обсудить достоинства и недостатки шарпа, но не в этой теме - тут это будет оффтопик.
Цитата(diadiavova @  1.6.2014,  13:45 Найти цитируемый пост)
Читать сгенерированный код в принципе не обязательно

Цитата(diadiavova @  1.6.2014,  13:45 Найти цитируемый пост)
Таким образом сгенерированные файлы вообще даже открывать не обязательно

С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел? smile Так что тут можно и поспорить - но опять таки в другой теме (типа, надо ли читать, а тем более редактировать код, написанный твоей ИДЕ). А вот холивара из инкапсуляции чёт не получается... smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 2.6.2014, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  1.6.2014,  23:03 Найти цитируемый пост)
С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел?

Ты вот без гугла можешь сказать, хотябы как посмотреть на то, что из твоего байткода сделал JIT? (это к вопросу об отвечать за то что даже не видел)


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 2.6.2014, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  2.6.2014,  10:41 Найти цитируемый пост)
Ты вот без гугла можешь сказать, хотябы как посмотреть на то, что из твоего байткода сделал JIT? 

За это пусть Oracle отвечает.  smile И вообще, я на байт-коде не пишу! smile 

Это сообщение отредактировал(а) Pawl - 2.6.2014, 18:38


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 3.6.2014, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  2.6.2014,  19:37 Найти цитируемый пост)
За это пусть Oracle отвечает.   И вообще, я на байт-коде не пишу!

Тогда на вопрос
Цитата(Pawl @  1.6.2014,  23:03 Найти цитируемый пост)
С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел?

ответ аналогичный, это пусть <разработчик генератора кода> отвечает.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 3.6.2014, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  3.6.2014,  10:12 Найти цитируемый пост)
ответ аналогичный, это пусть <разработчик генератора кода> отвечает.

Ну и будешь в ответ на претензии к своему коду отсылать заказчиков прямо туда! smile посмотрим, как долго они это терпеть будут. smile 

Это сообщение отредактировал(а) Pawl - 3.6.2014, 16:50


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 3.6.2014, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  3.6.2014,  17:49 Найти цитируемый пост)
Ну и будешь в ответ на претензии к своему коду отсылать заказчиков прямо туда!

Туда это туда же куда тебя пошлет Оракл с твоим багов в JIT (при условии конечно что у тебя не куплен VIP саппорт)?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 3.6.2014, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  3.6.2014,  17:29 Найти цитируемый пост)
Туда это туда же куда тебя пошлет Оракл с твоим багов в JIT (при условии конечно что у тебя не куплен VIP саппорт)?

Разница тут в том, что ты можешь залезть в дебри автосгенерированного IDE java-кода, разобраться в нём, потратив n-ное количество времени, и, найдя там лажу, хлопнуть себя по лбу с воплем "Семён Семёнович!" А потом самостоятельно эту лажу исправить. А баги JDK исправить можешь?

Это сообщение отредактировал(а) Pawl - 3.6.2014, 18:00


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 3.6.2014, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  3.6.2014,  18:58 Найти цитируемый пост)
Разница тут в том, что ты можешь залезть в дебри автосгенерированного IDE java-кода, разобраться в нём, потратив n-ное количество времени, и, найдя там лажу, хлопнуть себя по лбу с воплем "Семён Семёнович!" А потом самостоятельно эту лажу исправить. А баги JDK исправить можешь?

1. Про "автосгенерированного IDE" это твоя личная фантазия, diadiavova не уточнял чем генерируется код. А так, сгенеренный код подправить то конечно можно, но как ты предлагаешь это (исправление) автоматизировать?
2. И я о том же, баги в JIT JDK имеют гораздо более серьезные последствия и устраняются на порядок сложнее, чем баги в автосгенеренном коде. Но тебя почему-то сильно пугает "автосгенерированный IDE" код, а код сгенерированный JIT не беспокоит вообще.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 3.6.2014, 20:12 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  3.6.2014,  19:17 Найти цитируемый пост)
Про "автосгенерированного IDE" это твоя личная фантазия, diadiavova не уточнял чем генерируется код. 

А чем еще при разработке может быть автосгенерирован код? smile 
Цитата(LSD @  3.6.2014,  19:17 Найти цитируемый пост)
А так, сгенеренный код подправить то конечно можно, но как ты предлагаешь это (исправление) автоматизировать?

Никак, только тщательная проверка и правка ручками smile Поэтому я стараюсь сразу всё писать сам, а не слепо доверяться какой-то там IDE.
Цитата(LSD @  3.6.2014,  19:17 Найти цитируемый пост)
Но тебя почему-то сильно пугает "автосгенерированный IDE" код, а код сгенерированный JIT не беспокоит вообще.

Я вообще стараюсь не беспокоиться о вещах, на которые повлиять не в силах! smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
diadiavova
Дата 3.6.2014, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(LSD @  3.6.2014,  20:17 Найти цитируемый пост)
diadiavova не уточнял чем генерируется код

Я уточню. smile Все инструменты кодогенерации, с которыми мне доводилось сталкиваться(или ваять самому) можно условно разделить на три группы:

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

Код, генерируемый такими инструментами, можно и нужно не только читать, но и писать дописывать. Зачастую (как в случае со свичами) они просто создают заготовку кода и не более.

2. Инструменты визуального моделирования. Суть их состоит в том, что вся работа выполняется в дизайнере, а сохраняться результат может в том числе в виде программного кода. Наиболее очевидный пример такого генератора - инструменты для создания классов модели предметной области из сущностей базы данных. То есть в дизайнере создаются модели табличек связей и т. д. а сохраняется это в виде готовых классов.

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

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

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


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


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
LSD
Дата 4.6.2014, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  3.6.2014,  21:12 Найти цитируемый пост)
А чем еще при разработке может быть автосгенерирован код?

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


Цитата(Pawl @  3.6.2014,  21:12 Найти цитируемый пост)
Никак, только тщательная проверка и правка ручками  Поэтому я стараюсь сразу всё писать сам, а не слепо доверяться какой-то там IDE.

Я так и представляю, как ты берешь какой нибудь prtobuf, и вдумчиво читаешь все те тонны кода которые он генерирует smile 



Цитата(Pawl @  3.6.2014,  21:12 Найти цитируемый пост)
Я вообще стараюсь не беспокоиться о вещах, на которые повлиять не в силах!

А это тогда тут при чем
Цитата(Pawl @  1.6.2014,  23:03 Найти цитируемый пост)
С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел?

? Ты или "должен отвечать" и за компилятор и рантайм и автогенерацию или "не беспокоиться о вещах ...".


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 4.6.2014, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  4.6.2014,  12:10 Найти цитируемый пост)
Я так и представляю, как ты берешь какой нибудь prtobuf, и вдумчиво читаешь все те тонны кода которые он генерирует


Цитата(Pawl @  3.6.2014,  20:12 Найти цитируемый пост)
я стараюсь сразу всё писать сам


Цитата(LSD @  4.6.2014,  12:10 Найти цитируемый пост)
Цитата(Pawl @  3.6.2014,  21:12 )Я вообще стараюсь не беспокоиться о вещах, на которые повлиять не в силах!А это тогда тут при чемЦитата(Pawl @  1.6.2014,  23:03 )С этим не соглашусь: ты должен отвечать за выдаваемый тобой код, а как ты будешь отвечать за что-то, чего даже не видел?? Ты или "должен отвечать" и за компилятор и рантайм и автогенерацию или "не беспокоиться о вещах ...".

Ну, тут ты меня поймал! smile Формально оно конечно так, но вот только, когда твой начальник найдет ошибку у тебя в коде, он не будет разбираться, кто его писал - ты или IDE, а сразу лишит тебя, к примеру, премии. И будет прав. Но вот ошибку в байт-коде ни ты ни он найти не сможете, поэтому, случись что, совесть твоя будет чиста. smile 



--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 4.6.2014, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @ 4.6.2014,  16:27)
Цитата(LSD @  4.6.2014,  12:10 Найти цитируемый пост)
Я так и представляю, как ты берешь какой нибудь prtobuf, и вдумчиво читаешь все те тонны кода которые он генерирует


Цитата(Pawl @  3.6.2014,  20:12 Найти цитируемый пост)
я стараюсь сразу всё писать сам



Цитата(Pawl @ 4.6.2014,  16:27)
Ну, тут ты меня поймал! smile Формально оно конечно так, но вот только, когда твой начальник найдет ошибку у тебя в коде, он не будет разбираться, кто его писал - ты или IDE, а сразу лишит тебя, к примеру, премии. И будет прав. Но вот ошибку в байт-коде ни ты ни он найти не сможете, поэтому, случись что, совесть твоя будет чиста. smile

1. Нефиг генерированный код коммитить.
2. Хотел бы я посмтреть на реализованный тобой protobuf сериализатор/десериализатор smile 
3. Не знаю в какой *** конторе ты работаешь, но у нас за баги никого премии не лишают.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 4.6.2014, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  4.6.2014,  17:00 Найти цитируемый пост)
1. Нефиг генерированный код коммитить.

Золотые слова! smile 
Цитата(LSD @  4.6.2014,  17:00 Найти цитируемый пост)
2. Хотел бы я посмтреть на реализованный тобой protobuf сериализатор/десериализатор

Такого не делал, но, если я правильно тебя понял, самому его написать невозможно? Т. е., если его коммитить, то только в генерированном виде? А как же тогда пункт 1? Или его не коммитить? А если не коммитить, за него заплатят?  smile 
Цитата(LSD @  4.6.2014,  17:00 Найти цитируемый пост)
у нас за баги никого премии не лишают.

Ой, а к вам можно? Пожалуйста-пожалуйста, я честное слово, вам такого бажного ###кода быстро-быстро наворочу! smile smile

Это сообщение отредактировал(а) Pawl - 4.6.2014, 18:01


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 5.6.2014, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  4.6.2014,  18:58 Найти цитируемый пост)
Такого не делал, но, если я правильно тебя понял, самому его написать невозможно? Т. е., если его коммитить, то только в генерированном виде? А как же тогда пункт 1? Или его не коммитить? А если не коммитить, за него заплатят?

Имелось в виду, реализованный руками.



Цитата(Pawl @  4.6.2014,  18:58 Найти цитируемый пост)
Ой, а к вам можно? Пожалуйста-пожалуйста, я честное слово, вам такого бажного ###кода быстро-быстро наворочу!

Тебе в Люксофт. smile 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 5.6.2014, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  5.6.2014,  13:33 Найти цитируемый пост)
Имелось в виду, реализованный руками.

Так. На сколько я понимаю, есть код, реализованный руками и есть код, сгенерированный ИДE. Поправьте меня, если ошибаюсь: protobuf сериализатор/десериализатор не пишется руками и не генерится? Как же он тогда получается? smile 
Цитата(LSD @  5.6.2014,  13:33 Найти цитируемый пост)
Тебе в Люксофт.

А я хочу к вам! А то вдруг там за баги наказывают!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 6.6.2014, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  5.6.2014,  23:54 Найти цитируемый пост)
Поправьте меня, если ошибаюсь: protobuf сериализатор/десериализатор не пишется руками и не генерится? Как же он тогда получается?

У него немного другая идеология, есть язык описания доменных обхектов, на котором ты описываешь их, а дальше он генерирует классы для нужного языка (стандартно поддерживаются Java, C++, Python, и есть сторонние реализации практически для всех остальных языков).
Код

package com.example.test;

message ClientKey {
    required int32      id      = 1;
    required string     name    = 2;
    optional bool       flag    = 3 [default = false];
}

Код

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: test.proto

package com.example.test;

public final class Test {
  private Test() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  public interface ClientKeyOrBuilder
      extends com.google.protobuf.MessageOrBuilder {
    
    // required int32 id = 1;
    boolean hasId();
    int getId();
    
    // required string name = 2;
    boolean hasName();
    String getName();
    
    // optional bool flag = 3 [default = false];
    boolean hasFlag();
    boolean getFlag();
  }
  public static final class ClientKey extends
      com.google.protobuf.GeneratedMessage
      implements ClientKeyOrBuilder {
    // Use ClientKey.newBuilder() to construct.
    private ClientKey(Builder builder) {
      super(builder);
    }
    private ClientKey(boolean noInit) {}
    
    private static final ClientKey defaultInstance;
    public static ClientKey getDefaultInstance() {
      return defaultInstance;
    }
    
    public ClientKey getDefaultInstanceForType() {
      return defaultInstance;
    }
    
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return com.example.test.Test.internal_static_com_example_test_ClientKey_descriptor;
    }
    
    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return com.example.test.Test.internal_static_com_example_test_ClientKey_fieldAccessorTable;
    }
    
    private int bitField0_;
    // required int32 id = 1;
    public static final int ID_FIELD_NUMBER = 1;
    private int id_;
    public boolean hasId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public int getId() {
      return id_;
    }
    
    // required string name = 2;
    public static final int NAME_FIELD_NUMBER = 2;
    private java.lang.Object name_;
    public boolean hasName() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        if (com.google.protobuf.Internal.isValidUtf8(bs)) {
          name_ = s;
        }
        return s;
      }
    }
    private com.google.protobuf.ByteString getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8((String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    
    // optional bool flag = 3 [default = false];
    public static final int FLAG_FIELD_NUMBER = 3;
    private boolean flag_;
    public boolean hasFlag() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    public boolean getFlag() {
      return flag_;
    }
    
    private void initFields() {
      id_ = 0;
      name_ = "";
      flag_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;
      
      if (!hasId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }
    
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, id_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getNameBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, flag_);
      }
      getUnknownFields().writeTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
    
      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, id_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getNameBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, flag_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }
    
    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }
    
    public static com.example.test.Test.ClientKey parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static com.example.test.Test.ClientKey parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.example.test.Test.ClientKey parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static com.example.test.Test.ClientKey parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static com.example.test.Test.ClientKey parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    
    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(com.example.test.Test.ClientKey prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }
    
    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements com.example.test.Test.ClientKeyOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return com.example.test.Test.internal_static_com_example_test_ClientKey_descriptor;
      }
      
      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return com.example.test.Test.internal_static_com_example_test_ClientKey_fieldAccessorTable;
      }
      
      // Construct using com.example.test.Test.ClientKey.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }
      
      private Builder(BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }
      
      public Builder clear() {
        super.clear();
        id_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        flag_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      
      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }
      
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return com.example.test.Test.ClientKey.getDescriptor();
      }
      
      public com.example.test.Test.ClientKey getDefaultInstanceForType() {
        return com.example.test.Test.ClientKey.getDefaultInstance();
      }
      
      public com.example.test.Test.ClientKey build() {
        com.example.test.Test.ClientKey result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }
      
      private com.example.test.Test.ClientKey buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        com.example.test.Test.ClientKey result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }
      
      public com.example.test.Test.ClientKey buildPartial() {
        com.example.test.Test.ClientKey result = new com.example.test.Test.ClientKey(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.id_ = id_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.flag_ = flag_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }
      
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof com.example.test.Test.ClientKey) {
          return mergeFrom((com.example.test.Test.ClientKey)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }
      
      public Builder mergeFrom(com.example.test.Test.ClientKey other) {
        if (other == com.example.test.Test.ClientKey.getDefaultInstance()) return this;
        if (other.hasId()) {
          setId(other.getId());
        }
        if (other.hasName()) {
          setName(other.getName());
        }
        if (other.hasFlag()) {
          setFlag(other.getFlag());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }
      
      public final boolean isInitialized() {
        if (!hasId()) {
          
          return false;
        }
        if (!hasName()) {
          
          return false;
        }
        return true;
      }
      
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              id_ = input.readInt32();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              name_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              flag_ = input.readBool();
              break;
            }
          }
        }
      }
      
      private int bitField0_;
      
      // required int32 id = 1;
      private int id_ ;
      public boolean hasId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public int getId() {
        return id_;
      }
      public Builder setId(int value) {
        bitField0_ |= 0x00000001;
        id_ = value;
        onChanged();
        return this;
      }
      public Builder clearId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        id_ = 0;
        onChanged();
        return this;
      }
      
      // required string name = 2;
      private java.lang.Object name_ = "";
      public boolean hasName() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof String)) {
          String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
          name_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      public Builder setName(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        name_ = value;
        onChanged();
        return this;
      }
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      void setName(com.google.protobuf.ByteString value) {
        bitField0_ |= 0x00000002;
        name_ = value;
        onChanged();
      }
      
      // optional bool flag = 3 [default = false];
      private boolean flag_ ;
      public boolean hasFlag() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public boolean getFlag() {
        return flag_;
      }
      public Builder setFlag(boolean value) {
        bitField0_ |= 0x00000004;
        flag_ = value;
        onChanged();
        return this;
      }
      public Builder clearFlag() {
        bitField0_ = (bitField0_ & ~0x00000004);
        flag_ = false;
        onChanged();
        return this;
      }
      
      // @@protoc_insertion_point(builder_scope:com.example.test.ClientKey)
    }
    
    static {
      defaultInstance = new ClientKey(true);
      defaultInstance.initFields();
    }
    
    // @@protoc_insertion_point(class_scope:com.example.test.ClientKey)
  }
  
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_com_example_test_ClientKey_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_com_example_test_ClientKey_fieldAccessorTable;
  
  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\ntest.proto\022\020com.example.test\":\n\tClient" +
      "Key\022\n\n\002id\030\001 \002(\005\022\014\n\004name\030\002 \002(\t\022\023\n\004flag\030\003 " +
      "\001(\010:\005false"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_com_example_test_ClientKey_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_com_example_test_ClientKey_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_com_example_test_ClientKey_descriptor,
              new java.lang.String[] { "Id", "Name", "Flag", },
              com.example.test.Test.ClientKey.class,
              com.example.test.Test.ClientKey.Builder.class);
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }
  
  // @@protoc_insertion_point(outer_class_scope)


Вот такой кодик smile 


Цитата(Pawl @  5.6.2014,  23:54 Найти цитируемый пост)
А то вдруг там за баги наказывают!

Наказывают smile , со временем привыкнешь, а потом даже нанешь получать удовольствие smile 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 6.6.2014, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  6.6.2014,  11:05 Найти цитируемый пост)
У него немного другая идеология, есть язык описания доменных обхектов, на котором ты описываешь их,

Ага, идея понятна.
Пожалуй, я бы сам такое действительно не написал. smile 
Цитата(LSD @  6.6.2014,  11:05 Найти цитируемый пост)
Наказывают  , со временем привыкнешь, а потом даже нанешь получать удовольствие  

А как наказывают? Если не лишают премии, то что делают, порят розгами? Или подвергают моральному унижению? smile 

Это сообщение отредактировал(а) Pawl - 6.6.2014, 17:18


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 9.6.2014, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 9
Всего: 537



Цитата(Pawl @  6.6.2014,  18:18 Найти цитируемый пост)
Если не лишают премии, то что делают, порят розгами? Или подвергают моральному унижению?

Я смотрю ты уже заинтересовался smile 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 9.6.2014, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(LSD @  9.6.2014,  14:38 Найти цитируемый пост)
Я смотрю ты уже заинтересовался

Я в душе мазохист smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
diadiavova
Дата 9.6.2014, 18:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5820
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 4
Всего: 142



Цитата(Pawl @ 9.6.2014,  18:32)
Цитата(LSD @  9.6.2014,  14:38 Найти цитируемый пост)
Я смотрю ты уже заинтересовался

Я в душе мазохист smile

А когда из душа выходишь?  smile 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Pawl
Дата 10.6.2014, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: нет
Всего: 28



Цитата(diadiavova @  9.6.2014,  18:09 Найти цитируемый пост)
А когда из душа выходишь?

Тогда я программист smile 
А вообще спасибо всем откликнувшимся, благодаря вам я стал по-другому (надеюсь, более непредвзято) смотреть на некоторые вещи. smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила ведения Религиозных войн
Smartov
1. Уважайте собеседника
2. Собеседник != враг
3. Старайтесь воздерживаться от тем вида "Windows Rulez" или "Linux Rulez"

С уважением, Smartov.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Религиозные войны | Следующая тема »


 




[ Время генерации скрипта: 0.3629 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.