Сохранен 128
https://2ch.hk/pr/res/345679.html
Из-за проблем с продлением домена ARHIVACH.NET, с 13 октября он может перестать функционировать. В связи с этим Архивач временно переходит на использование прежнего домена ARHIVACH.NG.
Напоминаем, что сайт всегда доступен через Tor по адресу arhivachovtj2jrp.onion. Установите Tor Browser для беспрепятственного доступа!
Аноним Суб 19 Апр 2014 15:21:11  #1 №345679 
1397906471492.jpg

Задавай практические жопские и странные вопросы и задачи по ООП. Буду заглядывать сюда раз в три дня и отвечать.

Loading...
Аноним Суб 19 Апр 2014 15:27:29  #2 №345680 
1397906849546.jpg

>задачи по ООП

Wtf is this? Вопросы типа "как применять костыль "команда" и "наблюдатель" для замены ферст-класс функций и системы событий"?

Аноним Суб 19 Апр 2014 15:33:00  #3 №345681 

>>345680
Нет, практические вопросы типа "Есть один проект. Я сделал так, так и вот так, теперь я хочу поменять вот эту поебень и сломалось что-то внутри черепа".

Спектр языков максимально большой, где ООП есть, а монд нет. От C++ до псевдокода.

Аноним Суб 19 Апр 2014 16:15:22  #4 №345686 

Как реализовать в питоне комбинатор неподвижной точки?

Аноним Суб 19 Апр 2014 16:16:42  #5 №345687 

Какой из диалектов лиспа выбрать?

Аноним Суб 19 Апр 2014 16:37:08  #6 №345688 

>>345686
Возьму пики точеные, срублю хуи дроченые,
а потом проснусь же.

Аноним Суб 19 Апр 2014 16:47:26  #7 №345693 
1397911646767.jpg

Короче, как будут вопросы, задавайте.

Аноним Суб 19 Апр 2014 17:09:52  #8 №345701 

>>345693


(defmacro -> (val f &rest fs)
(cond ((null fs)
(cond
((listp f) `(funcall ',(car f) ,val ,@(cdr f)))
(t `(funcall ',f ,val))))
(t `(-> (-> ,val ,f) ,@fs))))

Нигде не обосрался?
sageАноним Суб 19 Апр 2014 17:13:10  #9 №345702 

>>345686
fix = lambda f: (lambda x: f (lambda y: x (x) (y))) (lambda x: f (lambda y: x (x) (y)))

Аноним Суб 19 Апр 2014 17:28:23  #10 №345709 
1397914103806.jpg

>>345701
Весь раздел заполнен только дегенератами-холиварщиками, чтоли? Ну предположим я разберусь в том, что здесь написано. Ну да, какой-то макрос. Ты даже не представляешь, как сильно мне насрать. Ты даже не задал вопрос. Не обосрался ли я. Это и есть твой вопрос? Нет, не обосрался.

Аноним Суб 19 Апр 2014 17:35:18  #11 №345713 

>>345709
Это макрос из Кложуры реализованный в Коммон лиспе, в котором нет гигиены. Из-за того, что гигиены нет при раскрытии может произойти конфуз, вот я и спрашиваю, не обосрался ли я?

Аноним Суб 19 Апр 2014 17:35:59  #12 №345714 
1397914559283.jpg

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

sageАноним Суб 19 Апр 2014 18:33:04  #13 №345725 

>>345714
Мемоизирующий комбинатор неподвижной точки позволяет удобно мемоизировать произвольную функцию.

Аноним Суб 19 Апр 2014 18:37:58  #14 №345726 
1397918278123.jpg

>>345713
Увлекался только схемой когда-то и уже всё забыл.
Мне лично не ясен синтаксис там, где funcall,
хотя я потратил некоторое время на гугление.


макрос val (f, fs = null)
{
if (fs это null)
{
if (f это ConsCell)
{
return что-то одно;
}
else
{
return [true, [что-то другое]];
}
}
else
{
return что-то третье;
}
}


Ничего не понимаю.
Именно в такие моменты я убеждаюсь, что лисп таки эзотерический язык. Почему обработка списков требует таких мучений? Зачем такой мощный reflection? Создание ИИ, не иначе же. Хотя нет. Если это макрос, значит compile-time и в написании Матрицы не поможет. И кстати, причем тут ООП?

Но внезапно ко мне пришел на ум совсем другой вопрос про ООП. Здесь много хаскелистов (или один активный), а там для построения программ используются модули, насколько мне известно. В ООП есть такой принцип как IoC (его еще называют Dependency Injection) - частный случай построения сверху вниз. В аббревиатуре SOLID для него даже выделена отдельная буква - D (Dependency inversion principle). Как разработка сверху вниз реализуется в современном функциональном программировании? Как взять огромный кусок программы и заменить его на другой равнозначный (с точки зрения использования) кусок программы одной строчкой? Например, в Хаскеле. Как это сделано в процедурном Лиспе?
Аноним Суб 19 Апр 2014 18:42:11  #15 №345728 

Написал функцию, складывающую матрицы, получилось некрасиво.
ОП, как переписать, чтобы было красиво.
Функция:
list(map(lambda x: list(x), list(map(lambda x, y: map(lambda a, b: a + b, x, y), matrix1, matrix2))))
Матрицы записываются так: [[1, 3, 4], [6, 3, 5], [9, 4, 2]]

Аноним Суб 19 Апр 2014 18:46:00  #16 №345730 

>>345728
Ах да, по поводу ООПа:
Я хочу создать класс Matrix, и перезагрузить для него сложение.
Как мне передать в метод два списка? с помощью *arg ведь только один можно передать?

Аноним Суб 19 Апр 2014 19:02:06  #17 №345732 

>>345730
list(map(lambda x: list(x), list(map(lambda x, y: map(lambda x, y: x + y, x, y), x, y))))
Переименовал аргументы, чтобы покрасивше было. Но как сделать более красивой саму структуру функции? Мне кажется, я тут делаю какие-то ненужные вызовы, которые можно сократить.
Что думаешь, ОП?
Ну и как мне передать в метод два списка?

Аноним Суб 19 Апр 2014 19:18:07  #18 №345735 
1397920687770.gif

>>345730
Проявлю себя как типичный джавист (хотя это не правда) и скажу, что что-то здесь неправильно, и излишний *arg вреден. И по закону жанра, я сразу должен сравнить программиста, текущего по синтаксису, с лингвистом.

Ты хочешь класс Matrix. С чем он должен складываться? С другой матрицей.


Matrix
-------------
конструктор(ширинаСтроки, List<Float>)
конструктор(ширинаСтроки, элемент1, элемент2...)
плюс(matrix:Matrix)

Конечно, получится слишком длинно.

Matrix m = new Matrix(3,1,2,3,4,5,6,7,8,9).plus(new Matrix(3,1,2,3,4,5,6,7,8,9));
// Если можно переопределять операторы:
Matrix m = new Matrix(3,1,2,3,4,5,6,7,8,9) + new Matrix(3,1,2,3,4,5,6,7,8,9);

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

--------

Если ты сделаешь основные методы статичными,
при этом не сделав обычных. Например так.

Matrix
-------------
конструктор(ширинаСтроки, List<Float>)
конструктор(ширинаСтроки, элемент1, элемент2...)
static sum(m1:Matrix, m2:Matrix)

Откуда потом возьмется полиморфизм? Во многих
языках в интерфейсах вообще нельзя указывать
static-методы. Они нужны только для классов
из разряда Misc.
Аноним Суб 19 Апр 2014 19:27:38  #19 №345736 

>>345735
>Matrix m = new Matrix(3,1,2,3,4,5,6,7,8,9).plus(new Matrix(3,1,2,3,4,5,6,7,8,9));
Так я и сам мог догадаться. Я спрашивал про красивое решение.

Аноним Суб 19 Апр 2014 19:33:12  #20 №345738 

>>345736
Скажи мне, в каком контексте используется этот матрицеобработчик.

Аноним Суб 19 Апр 2014 19:35:49  #21 №345739 

>>345738
Я занялся изучением питона. Сейчас читаю про перегрузку операторов. Чтобы попрактиковаться, решил написать класс для работы с матрицами, и перегрузить для него основные арифметические операторы.

Аноним Суб 19 Апр 2014 20:11:20  #22 №345747 
1397923880058.jpg

>>345739
Питон слабоват по части обучения ООП. Никогда не знаешь,
какого класса аргумент прилетел. Слышал, что там сейчас
можно указывать типы аргументов, но они
всё равно не проверяются.

Ну, вот так же красиво выглядит. Разве нет?

m = Matrix([[1,2,3],[4,5,6],[7,8,9]]) + Matrix([[1,2,3],[4,5,6],[7,8,9]]);


В какой-нибудь джаве это получилось бы очень уж многословно,
но по сути так оно и есть правильно.
конструктор(List<List<Float>>);


Я даже больше скажу.
Вот сейчас ты пишешь эту обработавалку матриц.
Типа, для всего. Просто так. Но чуть позже ты напишешь какой-то код, который будет использовать ее. Потом еще и еще. И тут внезапно ты понимаешь, что есть какой-нибудь numpy, который делает то же самое, но быстрее. А ты везде использовал свой класс Matrix и конструктор у тебя везде одинаковый, который ты придумал однажды. Неважно какой, со двумерным или одномерным списком. И чтобы использовать numpy ты разве что можешь написать для него обертку, которая выглядит в точности как твой класс, но там внутри преобразуется в numpy. Это будет мегакостыль.

И тут я плавно перехожу к необходимости фабрик и прочей поеботни в каноничном ООП. Если следовть принципам Solid, проблема решается так.

Есть обертка над numpy и есть твой класс. Причем твой класс не знает, как плюсонуть к себе numpy, а numpy не знает, как плюсануть к себе твою матрицу. Смотрим на всю эту поеботу сверху. Вот есть куски программы, которые используют матрицы. Они и создают, и плюсуют их. И что-то еще с ними делают.

Итак, делаем два интерфейса.


IMatrix
-----------------
плюс(matrix:IMatrix)
-----------------


IMatrixFactory
-----------------
get(values:List<List<Float>>) : IMatrix
get(values:List<List<Int>>) : IMatrix
-----------------

Делаем твою матрицу OneLinerMatrix и фабрику для нее OneLinerMatrixFactory, реализующие эти интерфейсы.
Теперь во всех модулях, классах программы должен быть способ централизовано внедрить зависимость. Например у тебя есть 20 классов, которые просят IMatrixFactory, и у них есть метод setMatrixFactory. В самом главном классе приложения (самый логический верх) у тебя должна быть возможность им всем внедрить один объект. Можно использовать специальные библиотеки для этого. Я иногда даже делаю такие вещи вручную. Это стоит потраченного времени. Гораздо больше времени в итоге экономится. Если тебе понадобится поменять OneLinerMatrix на NumpyMatrix, ты вместо OneLinerMatrixFactory создаешь NumpyMatrixFactory и вводишь всем нуждающимся классам в проекте.
Аноним Суб 19 Апр 2014 20:33:38  #23 №345754 
1397925218348.jpg

>>345725
Я ничего в этом не понимаю, но ты победил.
Мемоизация бывает очень полезна.
Хотя с другой стороны, можно ее сделать,
ничего не понимая в математике.
Конкретно в питоне это делается за 2 минуты
без использования мозгов вообще.


my_func_memo = dict()
def my_func(a):
def inner(a):
# здесь все расчеты
if (a in my_func_memo):
return my_func_memo[a]
else:
my_func_memo[a] = inner(a)
return my_func_memo[a]

#случай с несколькими параметрами

my_func_memo = dict()
def my_func(a,b,c):
def inner(a,b,c):
# ...
if ((a,b,c) in my_func_memo):
return my_func_memo[(a,b,c)]
else:
my_func_memo[(a,b,c)] = inner(a,b,c)
return my_func_memo[(a,b,c)]
Аноним Суб 19 Апр 2014 22:44:53  #24 №345796 

>>345679
Посоны помогите с задачкой на джаве


Исправьте ошибки: переместите методы clone в те классы, в которых они должны быть реализованы.
Лишние методы удалите.


public class Solution {
public static class A implements Serializable {
}

public static class B implements Remote {
}

public static class C extends ArrayDeque {
}

public static class D implements EventListener {
}

protected A clone() throws CloneNotSupportedException {
return (A) super.clone();
}

protected Thread clone() throws CloneNotSupportedException {
return (Thread) super.clone();
}

protected final B clone() throws CloneNotSupportedException {
return (B) super.clone();
}

protected ArrayDeque clone() throws CloneNotSupportedException {
return super.clone();
}

public C clone() {
return (C) super.clone();
}

protected D clone() throws CloneNotSupportedException {
return (D) super.clone();
}

}




Я что-то не догоняю эти интерфейсы-маркеры
Аноним Суб 19 Апр 2014 23:57:11  #25 №345809 

>>345796
Ты! Ты понимаешь, что у тебя проблема с тем, чтобы говорить? Чтобы другой человек что-то понял, ты должен сначала что-то сказать! Это нормально для имиджборд, в этом нет ничего страшного, здесь почти все такие.

Аноним Вск 20 Апр 2014 00:01:49  #26 №345810 

>>345796
Объясни, что ты пытаешься сделать и зачем.

Аноним Вск 20 Апр 2014 00:13:17  #27 №345812 

>>345796
Первый раз слышу, чтобы один класс мог иметь несколько методов clone в джаве. Метод clone - он клонирует текущий объект, который этого класса.

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

Аноним Вск 20 Апр 2014 00:23:39  #28 №345813 

Ну ёба че непонятного то? Реализации никакой нет. Код абстракция. Из 6 методов clone() нужно выкинуть все те которые не подходят ни одному из 4 классов (ABCD), а те которые подходят (логически) переместить внутрь классов. Сформулировав по-другому, если бы вам нужно было реализовать метод clone() внутри классов ABCD какие бы методы из представленных вы бы туда добавили не меняя сигнатуры классов\методов?

Аноним Вск 20 Апр 2014 00:57:50  #29 №345821 

>>345813
Не пизди. Реализации нет. Еще как есть.
У всех методов clone ты сделал реализацию. И что же там внутри? Они вызывают родительский элемент. Какой?! Ты что, ебанулся? Класс Solution не наследует никакие классы. Это во-первых. Во-вторых. Метод clone здесь использовать нельзя, т.к. у него в java другое значение. Clone - клонирует объект от которого вызывается. Это два. Возвращаемое значение в java не является частью сигнатуры метода. Т.е. если это скомпилируется, я скажу "Уау, 4 одинаковых метода! И оно работает!". Это три. И в-четвертых, ты вообще походу не понимаешь, что делаешь. Это если уж говорить не про java, а вообще.

Аноним Вск 20 Апр 2014 01:08:44  #30 №345827 

Такое чувство, что я повелся на какой-то ужасный троллинг.

Аноним Вск 20 Апр 2014 01:10:49  #31 №345829 

Такое запоздалое чувство, что это задачка из собеседований для джавистов.

Аноним Вск 20 Апр 2014 01:16:47  #32 №345832 

Написал в соседнем треде и потом только увидел этот. Вот:

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

Аноним Вск 20 Апр 2014 01:35:27  #33 №345836 

>>345832
Поэтому для полиморфизма используют интерфейсы, анон. А наследование позволяет не переписывать заново повторяющееся поведение, повторяющиеся методы.

Аноним Вск 20 Апр 2014 02:45:22  #34 №345844 

>>345836
Получается, что если мне нужен этот частный случай полиморфизма (возможность смотреть на разные объекты и видеть одну и ту же сущность), я должен обращаться к нему через интерфейс? Вот так к примеру:

List<String> list = new ArrayList<>();
list = new LinkedList<>();

Но почему, к примеру, в java.io.* те же InputStream или OutputStream не используют эту возможность? Они объявлены как абстрактные и не имеют никаких подходящих интерфейсов.
Аноним Вск 20 Апр 2014 04:38:36  #35 №345847 
1397954316566.jpg

>>345844
>я должен обращаться к нему через интерфейс?
Везде, где возможно, следует работать с объектами через интерфейсы. Если вся работа с объектом от создания до уничтожения (если таковое в языке явно указывается) идет в одном методе, нет ничего плохого, чтобы писать

ArrayList<String> list = new ArrayList<String>();
. Но если значение куда-то уходит из метода или если это наоборот аргумент метода, он должен быть обозначен интерфейсом. Это повод задуматься, если где-то не так. Я не исключаю такой возможности, что иногда нельзя не делать по-другому.

Вот один из примеров - это сущности, entities. Для базы данных или чего угодно. Объекты, которые используются только для хранения данных предметной области. Т.е. не безликие матрицы и таблицы, а конкретно Человек, Машина, Организация. Я ни разу не видел, чтобы для них использовались интерфейсы, кроме чего-то вроде Serializable.

-----

>Почему в java.io.* InputStream и OutputStream - это абстрактные классы?

Это хороший вопрос, даже не считая того, что он java-ориентированный. Дело в том, что абстрактные классы - это почти интерфейсы, а интерфейсы - это почти абстрактные классы. В интернете куча страниц на тему "в чем разница между абстрактными классами и интерфейсами". Главное сходство в том, что от абстрактного класса тоже нельзя инстанцировать объект. Но почему существуют оба? В java это скорее дань уважения истории, потому что в крестах были абстрактные классы, а они подумали, почему бы не оставить, ведь довольно полезная штука. Но в крестах, не знаю как сейчас (там так много новых стандартов последнее время), раньше не было интерфейсов. И не надо путать интерфейсы с объявлением классов в h-файлах: да, можно писать объявление и реализацию в разных файлах, но нельзя потом использовать ее с другой реализацией совсем под другим именем, если только вы не отделяете ее как-нибудь в dll, или что там используется. Так что абстрактные классы были вашим единственным выбором. А разница в действительности небольшая, только здесь можно еще и вписать повторяющиеся вещи, чтобы использовать в наследниках.

Так что абстрактный класс может использоваться, как интерфейс, и он тоже реализует полиморфизм. Однако, не следует использовать для этой цели обычные классы. Это ловушка. Кажется, что меньше строчек кода, а на самом деле - большой геморрой. Это нарушает другой принцип SOLID - буква S (принцип единственной функции на класс). Есть функция, которую класс уже выполняет, и "быть основой для наследников" - это уже вторая обязанность. И не всегда можно их органично сочетать. Так что не усложняйте себе жизнь.

И пару слов по поводу самого аргумента "но в java api не так".
Только API мертвого продукта окончательно. И никакое API, даже у мертвого продукта, не идеально. И в java api тоже вносятся изменения. В официальной документации даже есть список устаревших вещей. http://docs.oracle.com/javase/7/docs/api/deprecated-list.html
Аноним Вск 20 Апр 2014 04:46:27  #36 №345848 

>>345844

list = new LinkedList<>();

Что ты этим хотел сказать?
>и не имеют никаких подходящих интерфейсов.
Наркоман? В InputStream есть интерфейс(его public методы) и даже абстрактный метод read().
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html
Аноним Вск 20 Апр 2014 10:19:03  #37 №345861 

>>345821
Всё разобрался. Правильным решением было


public class Solution {

public static class A implements Serializable {

}

public static class B implements Remote {

}

public static class C extends ArrayDeque
{
public C clone() {
return (C) super.clone();
}
}

public static class D implements EventListener {

}

}



Т.к. только класс C имеет поля наследованные от ArrayDeque. Остальные классы наследуют пустые интерфейсы-маркеры.
Аноним Вск 20 Апр 2014 12:28:44  #38 №345873 

>>345747
Но ведь в питоне нет интерфейсов. Можно, конечно, подключить их из модулей, но хотелось бы по возможности тянуть минимальное количество зависимостей.

Аноним Вск 20 Апр 2014 14:05:50  #39 №345890 

>>345873
Плохо, что нет, на мой взгляд. Только почитай. Тут пишут, что это не Python way. Как же иначе писать большое ПО на питоне, я не знаю. http://stackoverflow.com/questions/5856963/abstract-methods-in-python

Аноним Вск 20 Апр 2014 14:08:35  #40 №345891 

Вернее как вообще писать большое ПО иначе, я не знаю.

Аноним Вск 20 Апр 2014 14:12:36  #41 №345892 

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

sageАноним Вск 20 Апр 2014 16:04:05  #42 №345909 

>>345892
А я ведь даже делал пожертвования в PyPy. Сейчас не помню сколько, тысячи три рубчинских. А сейчас обхожу стороной.

Аноним Вск 20 Апр 2014 23:05:29  #43 №346084 

>>345679
Аноны, выручайте, есть задача на Java и код:


В таблице есть колонки, по которым можно сортировать.
Пользователь имеет возможность настроить под себя список колонок, которые будут сортироваться.
Напишите public static компаратор CustomizedComparator, который будет:
1. в конструкторе принимать список компараторов
2. сортировать данные в порядке, соответствующем последовательности компараторов.
Все переданные компараторы сортируют дженерик тип Т
В конструктор передается как минимум один компаратор
*/
public class Solution {
public static class CustomizedComparator<T> implements Comparator<T>{

List<Comparator<T>> list;

public CustomizedComparator(Comparator<T> ... cmp)
{
Collections.addAll(this.list, cmp);
}

@Override
public int compare(T o1, T o2)
{
return list.indexOf(o2)-list.indexOf(o1);
}
}
}

Внимание вопрос: что я не так сделал? ибо нихуя не работает
Аноним Вск 20 Апр 2014 23:37:35  #44 №346097 

>>346084
Вот так ещё решил, всё равно не проходит:

 
public class Solution {
public static class CustomizedComparator<T>{

ArrayList<Comparator> list;

public CustomizedComparator(Comparator<T> ... cmp)
{
if (cmp.length>0) Collections.addAll(this.list, cmp);

Comparator<Comparator> compareByIndex=new Comparator<Comparator>()
{

@Override
public int compare(Comparator o1, Comparator o2)
{
return list.indexOf(o2)-list.indexOf(o1);
}
};

Collections.sort(list,compareByIndex);

}

}
Аноним Вск 20 Апр 2014 23:43:28  #45 №346100 

>>345680
>команда
Прочитал как "монада", вспомнил, что это ООП тред и проиграл.

Аноним Вск 20 Апр 2014 23:46:22  #46 №346102 
1398023182061.png

Объясни мне, что такое замыкание и dependency injection. Википедию читал, но так и не понял - то ли это что-то такое очевидное, что везде есть, все его используют, не называя это этими словами, то ли это что-то сложное, и я хуй знает, что это.

Аноним Вск 20 Апр 2014 23:46:50  #47 №346103 

>>346097
И даже так:


public class Solution {

public static class CustomizedComparator<T> implements Comparator<Comparator<T>>{

public ArrayList<Comparator<T>> list;


public CustomizedComparator(Comparator<T> ... cmp)
{
if (cmp.length>0) Collections.addAll(this.list, cmp);

}

@Override
public int compare(Comparator<T> o1, Comparator<T> o2)
{
return list.indexOf(o1)-list.indexOf(o2);
}
}

}


Как правильно реализовать подобную хуйню?
Аноним Пнд 21 Апр 2014 00:32:25  #48 №346109 

>>346100
А я комонада.

Аноним Пнд 21 Апр 2014 01:00:34  #49 №346120 

>>346109
А я goto
Знаешь свою метку?

sageАноним Пнд 21 Апр 2014 01:19:51  #50 №346121 
1398028791805.jpg

>>346102
Замыкание - это одно.
Dependency injection - это другое.

Объясню про второе. Смотри.
Ты делаешь некий класс A, которому нужен объект класса/интерфейса B.
Как поступает Ерохин, когда делает класс А? Он берет и создает внутри него (в конструкторе, допустим) объект B. Не. Я неправильно объясняю. Бля.

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

Короче, принцип выворачивание контроля (inversion of control) - это когда те объекты, которые нужны для класса, создаются не в самом классе, а потом выносятся наверх, а наоборот создаются сверху и внедряются внутрь. И отсюда название - Dependency injection - объекты, от которых зависит некоторый другой объект - они создаются не в нем, а снаружи от него, и внедряются в него (через сеттеры, например). На логическом верхе программы создаются все части программы и внедряются друг в друга, потому что они зависят друг от друга. Вот. Смотри пример http://cube54.tk/oopro/1 Здесь программа на JS разрывается на четыре куска так, что три из них сами по себе и отдельно друг от друга, а один что-то делает с html.

А за счет того, что сеттеры принимают объект как интерфейс, а не реализацию, в месте сборки можно легко поменять одну реализацию на другую. Например, у тебя есть объект, который выдает данные. Ты пишешь программы и делаешь его как заглушку - Mock-объект. Но когда приходит время писать настоящую реализацию, не обязательно удалять Mock. Ты херачишь unit-тесты, и делаешь так, что в тестовой конфигурации у тебя этот Mock и используется, а в обычной сборке подключается класс, который лезет в БД.

sageАноним Пнд 21 Апр 2014 01:22:09  #51 №346122 

>>346102
Короче это как раз очень простое и очевидное, но эту очевидность просто нужно прочувствовать.

Аноним Пнд 21 Апр 2014 01:37:27  #52 №346125 

>>345847
Спасибо большое, все понятно написал, вроде стало яснее, кроме:
>Если вся работа с объектом от создания до уничтожения идет в одном методе, нет ничего плохого, чтобы писать
>ArrayList<String> list = new ArrayList<String>();

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

>>345848
>Что ты этим хотел сказать?
Не знаю, я до Java-коллекций еще не добрался. Просто хотел показать, что так тоже можно работать с объектами.

>Наркоман? В InputStream есть интерфейс(его public методы) и даже абстрактный метод read().
Я имел ввиду интерфейс не в широком смысле, а interface в Java. А вот read()/write() методы, мне казалось, лучше вынести в отдельный interface.

Аноним Пнд 21 Апр 2014 02:25:52  #53 №346131 

ОП, расскажи, что такое проксирование и как оно связано с инкапсуляцией.

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

Аноним Пнд 21 Апр 2014 03:40:28  #54 №346137 

>>346102
>замыкание
Знаешь, что такое лямбда? Вот это почти одно и то же. Допустим, у тебя есть функция ф1, которая содержит две переменные а и б. Ты в этой функции "создаёшь" другую функцию ф2, которая содержит переменную в. В этот момент происходит то самое замыкание, функция ф2 запоминает значения а и б, и теперь может обращаться ко всем трём переменным, хотя внутри неё объявлена только одна.
>dependency injection
Допустим, ты делаешь игру. У тебя есть объект движок, и есть объект графическийДвижок, у которого есть функция нарисоватьКартинку. Обычно ты бы в конструкторе объекта движок создавал бы графическийДвижок, а потом рисовал бы им. Неплохой способ, но если тебе захочется потом поменять отрисовщик (чтобы он был на опенгл, например), то тебе придётся лезть в конструктор и менять там, а если твой движок будет в виде библиотеки, то это будет вообще невозможно (если кто-то другой захочет сменить, например). Решение - выбросить создание объекта графическийДвижок из конструктора движка, и вместо этого требовать его параметром, например, того же конструктора. Теперь пользователи могут воткнуть туда вообще всё, что угодно, до тех пор, пока оно имеет метод нарисоватьКартинку.

Аноним Пнд 21 Апр 2014 04:52:57  #55 №346141 

>>346121
Плохое объяснение.
>>346137
Хорошее объяснение.

Аноним Пнд 21 Апр 2014 05:55:57  #56 №346150 

>>346137
>функция ф2 запоминает значения а и б, и теперь может обращаться ко всем трём переменным, хотя внутри неё объявлена только одна.
То есть, получается, что каррирование — частный случай замыкания?
lambda x: lambda y: lambda z: x + y + z
Последняя лямбда замыкается на первые две, так?

Аноним Пнд 21 Апр 2014 09:26:41  #57 №346161 

>>346131
> у ООП нету четкой концепции
У мамаши твоей нету четкой концепции. Читай Б. Мейера и просвещайся, быдло.

Аноним Пнд 21 Апр 2014 09:48:33  #58 №346164 

каталог-кун пишет:
современое ООП:
толпы быдла долбятся головами об стену невидя двери -
для них выпиливают люк.
http://openpaste.org/482Efbd3
http://ideone.com/E07a2

Аноним Пнд 21 Апр 2014 11:05:18  #59 №346182 

>>345701
А as-> сможешь?

Аноним Пнд 21 Апр 2014 15:48:11  #60 №346220 

>>345686
Он там не нужен.

>>345730
Ты задания с кодакадемии решаешь?

>>345747
> Ну, вот так же красиво выглядит. Разве нет?
>
> m = Matrix([[1,2,3],[4,5,6],[7,8,9]]) + Matrix([[1,2,3],[4,5,6],[7,8,9]]);
Красиво должно выглядеть так:

m = [1 2 3; 4 5 6; 7 8 9] + [1 2 3; 4 5 6; 7 8 9]

В нампай эти matrix нинужны, но строки всё равно вставляются коряво.

>>345754
Да тебя троллят. В пайтоне Y-комбинаторы не нужны.

>>346150
Твой пример верен.

Аноним Пнд 21 Апр 2014 18:06:06  #61 №346262 

>>346182
Что за as-> ?

Аноним Пнд 21 Апр 2014 18:49:32  #62 №346283 
1398091772745.png

>>346137
Ну так это просто скоупы. Разве есть языки без этого?

Аноним Пнд 21 Апр 2014 18:55:30  #63 №346290 

>>346262
Это как -> только место куда будет вставлен аргумент в каждой форме задаётся отдельно:


(as-> "myfile.txt" x
(slurp x)
(str "[" x "]")
(read-string x))

http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as-%3E
Аноним Пнд 21 Апр 2014 19:15:57  #64 №346300 

>>346290
>>346290
Да, я думал такое запилить, с подчеркиванием в качестве названия "дырки"

Аноним Пнд 21 Апр 2014 23:58:40  #65 №346430 
1398110320309.png

>>346141
Нет, вот как надо объяснять Dependency Injection:
Потный мальчик Никита внедрил Танюше ребенка.
Но это мог быть и не Никита, а мачо-мальчик Бахтияр.
Тане неважно, она всё равно любит дитятю одинаково.

Аноним Втр 22 Апр 2014 00:18:32  #66 №346441 
1398111512052.jpg

>>346131
> ООП отдельно от языка
Вещает оп. Я считаю каноничным ООП тот, которому учили в школе, который рисуют в UML-диаграммах и защищают на дипломе. Он каноничный не потому что так изначально придумали, а потому что используется в продакшне, хуё-моё.

>проксирование, инкапсуляцией
Да шкет его разумеет. Когда проксируют что-то, его же не частями проксируют. Вот и инкапсуляция тебе. Если мы говорим об одном и том же. Вот например в Spring'е для АОП используются Прокси-объекты.

Действует это вот как. У тебя есть класс с какими-то методами, и ты пишешь какую-то херотню над ними, вроде @делаетТоТо. Эти аннотации естественно нихера не работают сами по себе. Но когда этот объект внедряется в другой объект через Autowired, внедряется на самом деле Proxy-объект, который мимикрирует под этот объект этого класса, и при вызове тех же методов делает что-то еще дополнительно. Так что это относится скорее к полиморфизму, а не к инкапсуляции.

sageАноним Втр 22 Апр 2014 01:37:24  #67 №346450 

>>346430
Ты хуже местной пхп-макаки.

Аноним Втр 22 Апр 2014 12:28:17  #68 №346504 

>>346441
>Действует это вот как. У тебя есть класс с какими-то методами, и ты пишешь какую-то херотню над ними, вроде @делаетТоТо. Эти аннотации естественно нихера не работают сами по себе. Но когда этот объект внедряется в другой объект через Autowired, внедряется на самом деле Proxy-объект, который мимикрирует под этот объект этого класса, и при вызове тех же методов делает что-то еще дополнительно. Так что это относится скорее к полиморфизму, а не к инкапсуляции.
Это относится к жалкой попытке компенсировать отсутствие макросов.

Аноним Втр 22 Апр 2014 14:18:27  #69 №346528 

>>346504
Позволю себе возразить. Макросы, хоть и нужны, чтобы читаемость улучшалось, обычно ее ухудшают. А аннотации в спринге работают предсказуемо вполне, и читаемости не вредят.

Аноним Втр 22 Апр 2014 14:19:38  #70 №346529 

>>346504
И вообще, как бы ты сделал адекватный АОП через макросы?

Аноним Втр 22 Апр 2014 14:57:29  #71 №346533 

>>346528
> Позволю себе возразить. Макросы, хоть и нужны, чтобы читаемость улучшалось, обычно ее ухудшают.
Не знаю, что ты подразумеваешь под "обычно", но все макросы в clojure.core читабельность улучшают.
> А аннотации в спринге работают предсказуемо вполне, и читаемости не вредят.
Предсказуемо, это когда прямо в репле можно сделать macroexpand и увидеть, во что преваращается код. А не когда нужно лезть в сорцы каких-то annotation processor-ов
>>346529
Ну начнём с того, что концепцию АОП развил лиспер Gregor Kiczales. Не знаю, что ты понимаешь под "адекватным АОП", но в реальном коде я натыкался только на что-то соответствующее макросам with-logging, with-transaction и т.д. Это примерно 0.01% реальной силы макросов.


Аноним Втр 22 Апр 2014 17:08:27  #72 №346570 

>>345679
Чем отличается абстрактный класс от интерфейса?
Тред не читал

Аноним Втр 22 Апр 2014 17:21:16  #73 №346576 

>>346570
В интерфейсе только заголовки методов (это практически по определению), в абстрактном классе есть реализованные члены и несколько заголовков.

Аноним Втр 22 Апр 2014 18:50:08  #74 №346596 

>>346576
ААААААА ХУЙ СОСИ ЛОШАРА
http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

sageАноним Втр 22 Апр 2014 19:05:33  #75 №346601 
1398179133916.png

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

Аноним Втр 22 Апр 2014 19:38:35  #76 №346611 

>>346601
Пельмешки, если совсем лентяй

Аноним Втр 22 Апр 2014 19:42:16  #77 №346616 

>>346601
макороны с сыром хорошо пойдут
ты слишком много жиров еш
пельмени не рекомендую

Аноним Втр 22 Апр 2014 19:45:22  #78 №346620 

>>346601
Куриные грудки и рис.

Аноним Втр 22 Апр 2014 19:47:33  #79 №346622 

>>346616
В сыре тожн жиров дохера. Пусть гречки навернет без нихуя с соевчм соусом.

sageАноним Втр 22 Апр 2014 19:50:24  #80 №346623 

>>346620>>346616>>346611
Короче, я пошел за несколькими пакетами кефира, двумя тонкими батонами "к чаю", десятком яиц, сливочным маслом, черным чаем beta, килограммом лука, может быть еще палкой говяжьей колбасы и бутылкой водки.

Аноним Втр 22 Апр 2014 19:53:56  #81 №346624 

>>346623
Водяры обязательно возьми, касатик

Аноним Втр 22 Апр 2014 20:05:02  #82 №346629 

>>346623
Ты меня разочаровал.

Аноним Втр 22 Апр 2014 20:11:22  #83 №346631 

>>346629
Он наверное первый раз без мамки живет

sageАноним Втр 22 Апр 2014 21:14:51  #84 №346663 

категория: платиновые треды /pr/

Аноним Втр 22 Апр 2014 21:46:10  #85 №346668 

>>346596
Что ты хотел этим сказать?

Аноним Втр 22 Апр 2014 22:10:23  #86 №346671 

>>346533
Читаемость улучшают только те макросы, про которые все работники знают. Так что это должна быть какой-то общепринятый набор макросов, чтобы разработка в команде была возможна. Надеюсь, тред не съедет в священовойны, так или иначе.

> в репле можно сделать macroexpand и увидеть, во что преваращается код. А не когда нужно лезть в сорцы каких-то annotation processor

В джаве код не меняется же. А понять, что происходит можно либо из дебаггера, либо во всех современных IDE жмешь по аннотации, удерживая ctrl, там стопудово приложена документация. В спринге так. Написано, иди туда, сканер там. Короче, всё это пустое, мелочи.

Аноним Втр 22 Апр 2014 22:27:26  #87 №346675 

>>346629
Гречку я тоже купил, не расстраивайся, бро, бро.

Аноним Срд 23 Апр 2014 00:28:35  #88 №346703 

>>345679
В чем разница между абстрактным классом и интерфейсом?

Аноним Срд 23 Апр 2014 00:42:49  #89 №346710 

>>346703
Я уже рассусоливал на эту тему.
Вот здесь: >>345847
После строчки
>Почему в java.io.* InputStream и OutputStream - это абстрактные классы?
В чем разница, в википедии прочитаешь, а использовать вместо интерфейса абстрактный класс можно вполне, но только когда в этом есть смысл. Лучше этого не делать.

Аноним Срд 23 Апр 2014 00:44:27  #90 №346712 

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

Аноним Срд 23 Апр 2014 00:46:16  #91 №346713 

>>346703
Абстрактный класс - это лучший способ сделать наследование без хуйни, не нарушая принцип единственной обязанности.

Аноним Срд 23 Апр 2014 01:06:46  #92 №346720 

>>345680
В некоторых ООП-языках есть first-class-функции, которые передаются как ссылки на методы объектов и статические методы. Такие языки можно воспринимать, как химеры, хотя и нет ничего противоестественного вроде. При таком подходе без сборщика мусора то не обойтись. Один из языков, по которому я последнее время угорел - Haxe3 - могёт в такие вещи, и переданные функции в нем сохраняют проверку типов. Но мне на эту фичу по большому счету класть. Понятия не имею, насколько нечитаемый код для крестов он выдает.

Аноним Срд 23 Апр 2014 01:56:45  #93 №346727 

>>346182
>>346290


(defmacro as-> (val sym f &rest fs)
(cond ((null fs)
(cond ((listp f) `(funcall ',(car f) ,@(substitute val sym (cdr f))))
(t `(funcall ',f ,val))))
(t `(as-> (as-> ,val ,sym ,f) ,sym ,@fs))))

(defmacro <_ (&rest args)
(with-gensyms (new-args)
(let ((new-args (nreverse args)))
`(as-> ,(car new-args) _ ,@(cdr new-args)))))

И как-то так используется http://ideone.com/B9nexv
лол, у них там with-gensyms есть уже
Аноним Срд 23 Апр 2014 04:03:01  #94 №346741 

>>346727
Поправил, чтоб лямбды можно было использовать http://ideone.com/7tzrB9
Наверное, все-таки стоит имена функций передавать с апострофом...

Аноним Срд 23 Апр 2014 12:02:40  #95 №346793 
1398240160923.jpg

>>346727
>>345701
Никита?

Аноним Срд 23 Апр 2014 12:36:22  #96 №346805 

>>346793
Нацуми?

Аноним Срд 23 Апр 2014 14:25:41  #97 №346842 

категория: платиновые треды /pr/

Аноним Птн 25 Апр 2014 23:37:10  #98 №347593 

>>346741
Решил, что без апострофа ебли меньше

Аноним Чтв 01 Май 2014 00:07:27  #99 №349542 

>>346703
> The most obvious difference between the two mechanisms is that abstract classes are permitted to contain implementations for some methods while interfaces are not. A more important difference is that to implement the type defined by an abstract class, a class must be a subclass of the abstract class.
Effective Java
Item 18: Prefer interfaces to abstract classes

Аноним Чтв 01 Май 2014 00:27:43  #100 №349548 

>>349542
Хуевый ответ.

Аноним Чтв 01 Май 2014 02:39:34  #101 №349570 

Key.unlock(lock) или lock.unlock(key)

Аноним Чтв 01 Май 2014 06:52:15  #102 №349584 

>>349570
KeyProviderFactory keyProviderFactory = new KeyProviderFactory();
KeyProvider keyProvider = keyProviderFactory.getKeyProvider();
Key key = keyProvider.getKey();
LockProviderFactory lockProviderFactory = new LockProviderFactory();
LockProvider lockProvider = lockProviderFactory.getLockProvider();
Lock lock = lockProvider.getLock();
OpenerManagerFactoryProvider openManagerFactoryProvider = OpenerManagerFactoryProvider.getInstance();
OpenManagerFactory openManagerFactory = openManagerFactoryProvider.getOpenManagerFactory();
OpenLockWithKeyManager openLockWithKeyManager = openManagerFactory.getManager<OpenLockWithKeyManager>( OpenLockWithKeyManager.Class );
openLockWithKeyManager.openLockWithKey( lock, key );
конечно же.

Аноним Чтв 01 Май 2014 14:31:39  #103 №349648 

>>345726
Про Dependency Injection, ты имеешь в виду заменить без перекомпиляции, как это делается в Spring?

Аноним Чтв 01 Май 2014 14:38:35  #104 №349653 

>>349570
Очевидно, второе, т.е. Lock - это наследник некой абстрактной сущности Entity, к которой можно применять предметы. В частности к Lock можно применить предмет Key.

Аноним Чтв 01 Май 2014 14:39:51  #105 №349654 

>>349653
т.е. -> т.к.

Аноним Чтв 01 Май 2014 14:58:59  #106 №349668 

>>345679
Суп, ОП. Поясни простым языком за 3 принципа ООП. И на счет интерфейсов: как правильно их использовать?

Аноним Чтв 01 Май 2014 17:32:58  #107 №349706 

>>349668
Первый принцип ООП - в 1с нет ООП.
Второй принцип ООП - что бы они не говорили, ООП не в 1с.
Третий принцип ООП - ООП 1с в не.

Аноним Чтв 01 Май 2014 19:00:28  #108 №349739 

>>349706
>{1c, нет, ООП}
Перебрал множество и радуется. Хуею с долбоеба. Поясни за принципы ООП, лалка. Может на что-то сгодишься.

Аноним Чтв 01 Май 2014 19:11:49  #109 №349742 

>>349739
наследственая полиморфизьма инкапапуляция, я принят?

Аноним Чтв 01 Май 2014 20:46:10  #110 №349764 

>>349742
>я принят?
Нет, ты долежен сначала разъяснить эти принципы простыми словами.

Аноним Птн 02 Май 2014 03:59:47  #111 №349857 

>>349764
пихание одних структур в другие, создавание отдельных функций на каждый тип данных, сокрытие реализации
хотя есть и другие способы реализовать ООП, но именно так в плюсах
Не 349742-кун

Аноним Птн 02 Май 2014 18:27:58  #112 №349947 

>>349857
мы вам перезвоним

Аноним Птн 02 Май 2014 23:10:50  #113 №350034 

>>349947
И вам тоже.

Аноним Птн 02 Май 2014 23:30:35  #114 №350038 

>>346668
Теперь в интерфейсе могут быть методы. Отличие от абстрактного класса в том, что все методы public и\или static

Аноним Суб 03 Май 2014 15:06:04  #115 №350174 

>>345679
Как реализуется ООП на МК-61?

sageАноним Суб 03 Май 2014 15:06:59  #116 №350175 

>>350174
по русски
через жопу

Аноним Суб 03 Май 2014 15:51:15  #117 №350193 

>>345679
Один крестопогромист говорил что при создании игор обычно делают рендер отдельно от самой игры. В рендере делают сцену, возможность размещать на сцене разные модельки, свет и тому подобное. Потом передают моделькам на цене реальные координаты игровых объектов. Вроде вполне решаемая задача - создаём класс модели, в нем делаем указатель на координаты, возможность передать ему ссылку на координаты игрового объекта. Но дальше проблемы появляются:
А если эта модель не привязана к игровому объекту? Тогда выделять память и создавать её личные координаты? А если захотим потом её привязать к игровому объекту? А если потом мы удалим этот игровой объект? Как оповестить модель на сцене об этом?

Это я что-то не так додумал, или это все вполне решаемо и не похоже на костыли?

Аноним Суб 03 Май 2014 16:32:27  #118 №350198 

>>350193
Что ты хочешь вообще?

У тебя есть список моделей, которые грузятся при старте игры / при старте уровня. Он заранее подготавливается игровым редактором.
Каждая графическая модель, очень грубо говоря, это кусок бинарных данных (блоб), содержащий вершины и их индексы. При загрузке эти данные заливаются в видеопамять с помощью графического Api (e.g. OpenGL ES). То есть, модель содержит в себе ИД вершинного, индексного буферов в видеопамяти, смещения от начала буферов, размер участка в вершинном/индексном буфере, принадлежащего модели, ИД текстуры и шейдера, которые используются для отрисовки.
У игрового объекта может быть ссылка на графическую модель, которая отвечает за его показ на экране, collision модель ( упрощенная модель — шар, коробка или низкополигональный выпуклый многогранник, и их иерархические комбинации ), которая используется для расчета столкновений, и многое другое.

Аноним Суб 03 Май 2014 16:35:18  #119 №350200 

>>350198
То есть данные render, collision моделей и иные игровые данные находятся всегда в памяти и загружаются/выгружаются только при смене уровня/запуске приложения. Игровой объект может ссылаться на них, чтобы его показали/просчитали столкновения, и т.д.

Аноним Суб 03 Май 2014 20:33:15  #120 №350257 

>>350200
Это то мне понятно, я хочу сделать рендер и игру не зависимыми совсем. Хочу - использую рендер напрямую без всяких игр. Хочу - с игрой. Чтобы он сам разбирался где отображать модели. Чтобы рендер про игру ничего не знал. То есть рендер знает что там-то надо одну модель нарисовать, ещё где-то другую. А так получается придётся в игровых объектах(монстрах, игроке, стенах и прочем) делать метод для получения координат, пихать все это в рендер и указывать какую модель в них рисовать. А если я захочу сделать йоба сортировку объектов, чтобы не рисовать то, чего не видит камера? Причём в самом рендере. Т.е. игра просто должна сказать рендеру что он должен сколько-то как-бы отображаемых объекта в определённых координатах создать(и внезапно это координаты существующих в игре объектов, а может и нет). Я передвинул игрока - координаты изменились, а эти же самые координаты используются отображаемым объектом. Надо как-то сказать рендеру что они поменялись. Рендер сам как-то разберется что ему с ним делать. Может ему вообще все равно, а может он проверит видит ли его камера. Зависит от того что я сделаю. А игры это не касается.

sageАноним Вск 04 Май 2014 00:32:39  #121 №350345 
[url]

>>350257
Заебал, Просто начни делать! По пути разберешься.
Держи воодушевляющую песню.

Аноним Вск 04 Май 2014 00:34:33  #122 №350346 

Ну и бамп.

Аноним Вск 04 Май 2014 01:39:31  #123 №350354 
1399153171683.jpg

>>350193
Это не только не костыли, это так и должно быть.

>>350200
Вот это уже похоже на костыли. Нахуй так жить? Вещи, которые не нужны постоянно, не должны висеть в памяти постоянно, и нахуй не нужны ссылки из физ. модели в графическую. Не проще ли сделать так:

1. Игровой объект - то, на чем основана игровая механика - персонаж, футбольный мяч, стена, шкаф, здание. Если персонаж, то со скелетом, если другой объект, с collision-моделью, наборами действий, если дом, тоже с коллижинами, стенами, дверьми. Фактически, он должен быть и основой для физики и возможностей взаимодействия предметов между собой в игровом мире (НЕ считая управления пользователя, который должен считаться просто одним из персонажей, иначе это дебилизм).
Делаешь у игровых объектов hashcode, не зависящий от состояния, вида return this.id.

2. Графический объект - только данные для отрисовки.

Мы всегда можем сделать графический из игрового. За это доллжен отвечать специальный модуль (3). Например, у тебя есть контры и терроры, как в CS. Ты можешь в этом модуле менять им скины, модели и вообще всё, касающееся внешнего вида. Естественно это работает не очень моментально. Графический объект тоже НЕ должен ссылаться на игровой, потому что это дебилизм.
Делаешь несколько видов таких штук. Например, если это person, у него наверняка есть скелет, да и не только (вибропоказатель сисек, оттопыривание правой губы), если это трава, ее колыхание нужно жестко контролиировать одним-двумя свойствами.

Слушай дальше.
Итак, у тебя есть объекты 1 и 2. Тебе нужен класс, преобразующий 1 в 2.
Делаешь его и выносишь за пределы модулей 1 и 2, встраиваешь в него кэш.
Это всё будет в модуле 3, зависимом от 1 и 2.
Чтобы кэш работал адекватно, ему нужно скармливать все камеры,
между которыми ты будешь переключаться. Если ты этого не сделаешь,
он будет всегда непредсказуемо тормозить во время игры.

У него всего один метод - getGraphicModel(gameModel).
И суть проще некуда. У gameModel есть хэш-код, а также позиция в игровом мире.
Когда ты подгружаешь graphicModel, ты можешь запихивать их в любой Map или Set.
И так же удалять по хэшкоду или по ключу, который и есть хэшкод.
Но нужен еще один метод, который будет определять, какие объекты нужно подгрузить
на основе положения камер. И это повод для раздумий.
А вот удаление сделать проще некуда. Просто сделай помимо Мэпа еще одну коллекцию,
которая будет цепью типа FIFO. Перед добавлением нового объекта, смотри,
что у нее на конце. Если там не null, удаляй этот объект из Мэпа.
Ты можешь держать под контролем количество подгруженных объектов и расход памяти,
регулируя длину цепочки.

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

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

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

-------------

Теперь подумай, что ты получаешь.
У тебя гр. модели сами по себе. Ты можешь на основе тех же классов сделать
рендер для какой угодно поеботни. Более того, ты можешь наоборот,
взять LuxRay или другой готовый рендер, и играть через него realtime с fps=0.5,
где ничего не видно. Просто потому что.

Т.е. рендер не обязан быть один. Когда я говорю про 1 и 2 - это
в первую очередь у них должен быть API, и только потом в отдельных модулях
пробная реализация.

Типа такие модули получаются.
game-api
graphics-api
game-simple-impl
graphics-simple-impl
graphics-luxray-impl
moya-super-gama // здесь Main
moy-render-dlya-kakogo-ta-govna // другая прога, другой Main

Это pros. Cons - то, что если мало памяти или тупанешь,
получится графон, как в Rage.

вещает ОП-хуй

Аноним Вск 04 Май 2014 01:53:04  #124 №350356 
1399153984686.jpg

Еще один Cons - то, что в модуле 3 может потенциально возникнуть игромедный if-elsif-elsif-elsif...
Надо этого по возможности избежать.
Должно быть мало разновидностей игровых объектов, и они все должны быть обозначены, как интерфейсы в API.


И еще раз уточню, на всякий случай.

Игровой объект.
Если на уровне сейчас 20 одинаковых зомби, у нас 20 объектов.

Графический объект.
Если на уровне сейчас 20 одинаковых зомби, нужен 1 объект.


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

Аноним Вск 04 Май 2014 07:43:51  #125 №350381 

>>350257
Укради blitz3d и напиши на нём что-нибудь простенькое, а потом подумай, как бы ты это апи реализовал. Должно ответить на почти все твои вопросы.
>>350354
>Грузить модели с диска во время игры.
топ кек

Аноним Вск 04 Май 2014 10:37:04  #126 №350398 

>>350354
Теперь примерно понял что делать, спасибо.

sageАноним Пнд 05 Май 2014 02:47:06  #127 №350588 
[url]

>>350398
Обращайся. Если клепаешь опенсорц - скидывай ссылку обязательно.
Индивидуализм иногда ни к чему.

Аноним Втр 06 Май 2014 06:10:53  #128 №350952 

бмап наперегонки

comments powered by Disqus

Отзывы и предложения