Вопросы по Jave.

  • Автор темы Dymytry
  • Дата начала
L

LuMee

(1)
есть родитель class R и его дети: сlass D1,D2,D3 extends R
есть функции doSomething(D1).. doSomething(D3) для каждого типа детей...
Конкретно в таком виде красивых и удобных решений не вижу. Может, опишете задачу подробнее, глядишь, появятся хорошие идеи.

есть данные, они строятся через JFreeChart. чтобы в последнем построить график надо создать местный класс данных - dataset. получается я храню данные дважды и перегоняю их из одного места в другое. это плохо. можно попытаться унаследовать мой класс с данными от dataset, но тогда смешаются у меня классы данных и классы GUI. насколько я понимаю, это тоже плохо. как быть?
Не обязательно наследовать сам класс с данными от DataSet. Можно написать наследника DataSet'а, который внутри будет держать инстанс вашего класса с данными и по мере необходимости тягать данные из него. Такой шаблон, ЕМНИП, называется Wrapper или Adapter.

не считается ли плохим тоном:
- объявлять некоторые (временные, местные) переменные в внутри кода
- использовать конструкции с большим количеством вложений типа String a = objectName1.fieldName3.functionName5(...).fieldName8;
- использовать касты. видел на одном форуме фразу типа того что теперь (в новой 6 Jave? ) всегда можно обойти без кастов.
- в смысле, использовать локальные переменные? Само собой, это нормально, не все же данные в поля выностить
- вообще, нежелательно, читаются такие конструкции иногда неудобно
- совсем без кастов обойтись, насколько мне известно, никак, так что никакого криминала в их использовании не вижу.
 
D

Dymytry

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

Мне тут на другом форуме сказали, что я покусился на основы: моя задача является нарушением Liskov Principle, мне даже обедать расхотелось.

А задача простая и как мне кажется у всех такое встречается: есть набор все тех же что и с dataset детей-хранителей данных и функция draw(ребенок) для их рисования. Я эту функцию определяю внутри класса GUI и имею описанную проблему. Я конечно могу определить ее внутри класса-ребенка и далее запущу родитель.draw(), может и сработает, но очень не хочется этого делать т.к. класс детей относится непосредственно к данным, а функция - к рисованию данных на графике... получается я смешаю данные и их представление.
Может и тут нужен этот wrapper, правда это умножит количество классов на два.
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0



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

Dymytry

LuMee, Kmet, спасибо!

В итоге решил задачу простым getDeclaredMethods и Method.invoke. Visitor pattern - хитрая вещь.

***

Копаюсь в загадочной штуковине.
Обнаружил что мой код выдает NullPointerException в обычной работе, но НЕ ВЫДАЕТ его в режиме debugger! (Eclipse)

Строчка на которой это происходит выглядит так:
Код:
Main.settings.parentFrame.connection.getData(dCode);

В чем проблема? А проблема в том, что этот код выполняется внутри myThread.run(), а этой нити я делаю start() внутри конструктора parentFrame! То есть объект в процессе создания и в Main.settings.parentFrame еще не занесен, а я к нему уже обращаюсь изнутри его конструктора. Exception логичен, но странно то, что в debugger режим это прокатывает и соотв. переменные есть. А вот если в реальном режиме я поставлю перед этой строчкой if (parentFrame == null ), то оно выдаст что да, действительно null и далее Exception. А в дебаггере - скажет что не null.

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

***

As Usual :)

1) хочу понемногу осваивать системы планирования, сопровождения, которые используются при серьезных разработках. Первое что я бы сделал - составил для себя план вещей которые надо сделать + лист найденных багов + схему классов моей программы. Чем обычно пользуются в таких случаях? Я слышал всякие слова - UML, IDEF, ARIS, Rational - что именно лучше подойдет для джавы?

2) насколько актуально использовать arrays вообще? может везде ставить ArrayList? актуальны ли попытки экономить память в наше время?

3) скоро буду изучать взаимодействие с реляционными базами. В моих планах JDBC, Hibernate. Что-то еще актуальное и интересное?

4) может кто знает, как обычно в Jave под веб выводят генерируемые картинки, то есть - карты с занесенными на них метками, графики которые генерятся реал-тайм итд? можно, наверное, генерить SVG XML файл, но IE его вроде как не поддерживает. Вижу, что часто графики выводятся в виде JPEG файлов, но как они генерятся?
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
итоге решил задачу простым getDeclaredMethods и Method.invoke. Visitor pattern - хитрая вещь.
и зря. рефлексию стоит по возможности избегать.
чем проблема? А проблема в том, что этот код выполняется внутри myThread.run(), а этой нити я делаю start() внутри конструктора parentFrame! То есть объект в процессе создания и в Main.settings.parentFrame еще не занесен, а я к нему уже обращаюсь изнутри его конструктора. Exception логичен, но странно то, что в debugger режим это прокатывает и соотв. переменные есть. А вот если в реальном режиме я поставлю перед этой строчкой if (parentFrame == null ), то оно выдаст что да, действительно null и далее Exception. А в дебаггере - скажет что не null.

Неужели есть какие-то отличия между дебагом и реальным режимом? Я, конечно, перенес вызов из конструктора, "но осадочек-то остался"..
если есть несколько потоков в гонке за разделяемый ресурс, то нельзя делать предположения о очередности в которой потоки получать доступ к этому ресурсу. это справедливо не только для явы. на очередность будет влиять не толко дебаг, но и другие приложения, дисковая подсистема, да и просто фаза луны

Добавлено:
1) хочу понемногу осваивать системы планирования, сопровождения, которые используются при серьезных разработках. Первое что я бы сделал - составил для себя план вещей которые надо сделать + лист найденных багов + схему классов моей программы. Чем обычно пользуются в таких случаях? Я слышал всякие слова - UML, IDEF, ARIS, Rational - что именно лучше подойдет для джавы?
неважно, что нравится то и используй. начни с выбова VCS
2) насколько актуально использовать arrays вообще? может везде ставить ArrayList? актуальны ли попытки экономить память в наше время?
Premature optimization is the root of all evil in programming. выбор в перву очередь должен основываться на фцункциональности
3) скоро буду изучать взаимодействие с реляционными базами. В моих планах JDBC, Hibernate. Что-то еще актуальное и интересное?
jdbc просто обзорно просмотреть достасточно.
4) может кто знает, как обычно в Jave под веб выводят генерируемые картинки, то есть - карты с занесенными на них метками, графики которые генерятся реал-тайм итд? можно, наверное, генерить SVG XML файл, но IE его вроде как не поддерживает. Вижу, что часто графики выводятся в виде JPEG файлов, но как они генерятся?
обычно берут готорыо решение для чартов. по фразе java chart их гулится достаточно.
 
D

Dymytry

(MAIN)

Возникла интересная задача!

Мне надо в runtime ввести в программу некоторое условие отбора и далее с ним работать. То есть взять textbox, ввести туда логическое выражение, перевести это на язык функций моей программы и далее их выполнить.

Я вижу два варианта:

1) java scripting framework, который позволяет запускать код написанный на некоторых скриптовых языках. По умолчанию там javascript, можно подключить groovy etc. Можно запускать мои java функции.

2) написать свой парсер введенных в textbox логических условий.

Второй вариант мне нравится больше т.к. все таки не придется запускать этот script engine. Но во втором случае придется писать парсер, что не совсем просто.

Однако! Оба этих варианта предполагают, что мне придется запускать этот скрипт (или парсер) каждый раз когда мне потребуется проверить свое условие. А я вот думаю: можно ли как-то сделать это один раз, а потом сохранить в программе считанную логику? Наверное, это фантастика.. Еще раз на примере: человек ввел в textbox "Time > 10 Hours". И каждый раз когда юзер моей программы жмет кнопку у него проверяется этот Time. Но я хочу чтобы это проверка выполнялась без запуска script engine или logic parser, чтобы условия как-то _сохранились_ там.

Anyway, если "Однако" неосуществимо - какой вариант лучше? Есть ли другие?

(CONSEQUENCE)

Отсюда вопрос - а зачем вообще придумали этот Groovy или другие скриптовые языки? Их же куча, питоны всякие, GRails, Ruby.. Это вообще актуально или не стоит тратить время?
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
все зависит от синтаксиса выражений которые необходимо интерпретировать. если есть возможность то лучше использовать готовое, чем изобретать очередной велосипед.

Второй вариант мне нравится больше т.к. все таки не придется запускать этот script engine
чем так не нравится "этот script engine". Когда мне пришлось писать интерпретатор, я его реализовал именно как расширение к java scripting api.

из готовый решений еще можно посмотреть на и

Однако! Оба этих варианта предполагают, что мне придется запускать этот скрипт (или парсер) каждый раз когда мне потребуется проверить свое условие. А я вот думаю: можно ли как-то сделать это один раз, а потом сохранить в программе считанную логику? Наверное, это фантастика.. Еще раз на примере: человек ввел в textbox "Time > 10 Hours". И каждый раз когда юзер моей программы жмет кнопку у него проверяется этот Time. Но я хочу чтобы это проверка выполнялась без запуска script engine или logic parser, чтобы условия как-то _сохранились_ там.
ну во общем то, да - придется, но большинство решений позволяет парсить выражение только раз, а потом "исполнять" более быстрое внутреннее представление. в принципе, можно компилировать в байткод или в машинные иснтрукции, но результат вряд ли будет стоить затраченных усилий.
Отсюда вопрос - а зачем вообще придумали этот Groovy или другие скриптовые языки? Их же куча, питоны всякие, GRails, Ruby..
наверное потому что идеального языка программирование до сих пор нет
 
D

Dymytry

(Theory Break)
(1)
Kmet,
есть такая рекомендация: при создании класса доступ извне к переменным класса должен быть через методы этого класса (может даже это называется каким-то паттерном?).
Всегда ли это правило выполняется в твоих кодах?
Можно ли сказать что не выполнять его - однозначно плохой стиль программирования?
Бывают ли исключения?

(2) что может сделать Iterator чего нельзя сделать в обычном цикле типа (element : collection_of_elements)?

(3) что такого особенного есть в enum чего нельзя сделать через Array или static ArrayList, например?
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
есть такая рекомендация: при создании класса доступ извне к переменным класса должен быть через методы этого класса
правильная рекомендация
(может даже это называется каким-то паттерном?).
нет, это не паттерн, просто следование одному из принципов OOП -
Всегда ли это правило выполняется в твоих кодах?
Да
Можно ли сказать что не выполнять его - однозначно плохой стиль программирования?
Бывают ли исключения?
Программирование - это инженерная дисциплина, здесь с однозначными ответами туго. Просто выставлять публичные поля - это хороший способ осложнить себе жизнь в будущем, когда понадобится изменить логику доступа к данным, добавить валидацию, например
(2) что может сделать Iterator чего нельзя сделать в обычном цикле типа (element : collection_of_elements)?
некорректный вопрос. Итератор - это паттерн, позволяющий перебирать все элементы коллекции без учёта её особенностей реализации. Активно используется в ообощенном программирование. Тогда как цикл это языковая конструкция, которая в приведенной тобой форме как раз и использует итератор для перебора всех элементов коллекции.

(3) что такого особенного есть в enum чего нельзя сделать через Array или static ArrayList, например?
А разве можно реализовать типо-безопастные перечисляемые типы с помощью массивов?
 
D

Dymytry

Kmet, а в какой области видимости ты используешь инкапсуляцию?

Имеется ввиду, должна ли быть инкапсуляция в пределах одного package, например?

Я столкнулся с такой проблемой:
Есть класс-родитель, классы-дети; в классе-родителе есть переменная, которая должна быть у каждого ребенка, и общие для всех детей функции, которые с этой переменной работают. Однако эта переменная должна быть private ибо инкапсуляция. Что мне делать в такой ситуации? Унаследовать private переменную или функцию которая ее возвращает я не могу. Protected откроет переменную на весь package. Неужели нужен copy-paste?

"До какого уровня" следует делать инкапсуляцию? Например, у меня ArrayList<Double>. Мне лучше делать функцию double getDouble(int i), или можно ArrayList<Double> getArrayListDouble(), второе конечно удобнее т.к. по нему можно бегать не боясь выйти за границы.
 

Kmet

Well-known member
25.05.2006
904
8
BIT
0
Есть класс-родитель, классы-дети; в классе-родителе есть переменная, которая должна быть у каждого ребенка, и общие для всех детей функции, которые с этой переменной работают. Однако эта переменная должна быть private ибо инкапсуляция. Что мне делать в такой ситуации? Унаследовать private переменную или функцию которая ее возвращает я не могу. Protected откроет переменную на весь package. Неужели нужен copy-paste?
объявить как protected нормальное решение.
еще можно обявить как private и добваить public или protected методы для доступа

"До какого уровня" следует делать инкапсуляцию? Например, у меня ArrayList<Double>. Мне лучше делать функцию double getDouble(int i), или можно ArrayList<Double> getArrayListDouble(), второе конечно удобнее т.к. по нему можно бегать не боясь выйти за границы.
идеологически верно как то так

<!--shcode--><pre><code class='java'>public class Team {


public void addPlayer(Player player){
players.add(player);
}

public void removePlayer(Player player){
players.remove(player);
}

public List<Player> getPlayers(){
return Collections.unmodifiableList(players);
}

private List<Player> players = new ArrayList<Player>();
}[/CODE]

но, имхо, всегда инкапсулировать коллекции совсем не обязательно
 
D

Dymytry

ок, если показать private переменную нормально, то как быть c private функциями?
Допустим у меня abstract class, его дети, во всех детях должна быть совершенно одинаковая private функция. Если я ее занесу в abstract, то придется делать ее видимой всему package. Остается copy-paste.

Вообще, так ли плох copy-paste? Ведь решение, когда все private переменные и функции задаются внутри классов-детей, даже если они одинаковы для этих классов, вроде как более безупречное. И кроме того, когда класс задан целиком в своих рамках {}, то это читается проще, чем когда его часть частично реализована уровнем выше в родителе.
 
L

LuMee

Вообще, так ли плох copy-paste?
В общем случае copy-paste - зло; наследование было придумано в том числе, чтобы от этого зла избавиться. Так что если у классов с общим родителем должен быть одинаковый метод, его определенно надо выносить в родителя и делать protected.
 
D

Dymytry

В общем случае copy-paste - зло; наследование было придумано в том числе, чтобы от этого зла избавиться. Так что если у классов с общим родителем должен быть одинаковый метод, его определенно надо выносить в родителя и делать protected.

Имеется ввиду - "меньшее зло"? Потому как делать метод который private доступным всем тоже ведь не добро.
 
L

LuMee

Имеется ввиду - "меньшее зло"? Потому как делать метод который private доступным всем тоже ведь не добро.
Не меньшее ни разу. Ненужное дублирование кода еще не раз выйдет боком, когда понадобится этот код модифицировать.
В свою очередь, protected-метод виден вовсе не всем, а только наследникам и классам в пределах пакета. Если последние вас беспокоят, можно вынести базовый класс в отдельный пакет, где "чужаков" не будет.
 
D

Dymytry

OK, но тогда получается в инкапсуляции в пределах package нет смысла: половина переменных все равно будет смотреть наружу.
 
L

LuMee

OK, но тогда получается в инкапсуляции в пределах package нет смысла: половина переменных все равно будет смотреть наружу.
Почему наружу? Наружу будут смотреть только public-мемберы, они для того и public, собственно. У protected методов и полей видимость будет ограничена пакетом, в котором, по идее, "все свои", и потомками, которые, опять же, знают, как этим добром правильно пользоваться.
 
D

Dymytry

LuMee, а как бы ты организовал хранение массива объектов, для поиска которых нужен набор из 3-5 ключей, причем число ключей зависит от типа объекта.

То есть HashMap у которого Key это набор данных. HashMap<ArrayList<Object>, MyObject>, или можно как-то лучше?
 
L

LuMee

LuMee, а как бы ты организовал хранение массива объектов, для поиска которых нужен набор из 3-5 ключей, причем число ключей зависит от типа объекта.
То есть HashMap у которого Key это набор данных. HashMap<ArrayList<Object>, MyObject>, или можно как-то лучше?
Не совсем понял задачу, но можно для Key HashMap'а завести спецовый класс, содержащий возможные ключи. В этом классе переопределить equals() и hashCode(), чтобы они учитывали эти ключи. Хотя, конечно, лучше уточнить задачу, может она как-то проще решается.
 
D

Dymytry

Не совсем понял задачу, но можно для Key HashMap'а завести спецовый класс, содержащий возможные ключи. В этом классе переопределить equals() и hashCode(), чтобы они учитывали эти ключи. Хотя, конечно, лучше уточнить задачу, может она как-то проще решается.

Есть набор объектов-потомков одного родителя.
Объекты различаются по:
- собственно классу
- набору параметров с которым был запущен конструктор

Например:
Транспортные Средства: Автомобиль(Колесо = 4, цвет = белый); Мотоцикл(колесо=2, коляска = true); Телега(); Автомобиль(Колесо=6, цвет=зеленый);

Надо все это где-то хранить так, чтобы по параметрам {Класс, paramList} можно было найти. Но paramlist разный для каждого класса, и перечислить заранее все варианты параметров нельзя.

Какие варианты?
1)HashMap<ArrayList<Object>, TransportObject> где ArrayList<Object> заполняется как имя класса+параметр1+....
2)формировать int key, но зачем тогда делать спецкласс? Можно в самом TransportObject сделать int getTransportKey() = class index * 1000 + first param * 100 etc и получить таким образом int ключ.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!