Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Массив указателей на функции (в терминах C/С++) / 15 сообщений из 15, страница 1 из 1
10.09.2012, 17:33:26
    #37951444
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Добрый день!
Есть необходимость создать массив указателей на функции (в терминах C/С++)
Задача описывается следующим образом – имеется визуальный компонент который отображает данные, получаемые из другого потока. В зависимости от предпочтений пользователя данные показываются по разному (рассчитываются сервисом). Раньше я реализовал это с использованием кучи if'ов. Решил создать класс WidgetParams – отвечающий за хранение всех доступных параметров и способов их расчета.
Прошу обсудить мою реализацию:
Смущает функция Bundle get() - в которой пришлось через if указать список классов поддерживаемых параметров.
P.S. Android Java.

С Уважением,
Александ.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
public class WidgetParams {
	private List<ParamHash> paramsList = new ArrayList<ParamHash>();
		
	private abstract class ParamGetter	{
		String key;		
		ParamGetter(String key)	{
			this.key = key;
		}		
		abstract Object get();	
	}

	private class ParamHash	{
		String key;
		int index;
		ParamHash(String key, int index)	{
			this.key = key;
			this.index = index;
		}
	}
	
	private final ParamGetter[] paramsGetter = {
			new ParamGetter("BALANCE")	{
				@Override Object get() {
					return ...
				}
			},
			new ParamGetter("LAST_UPDATE")	{
				@Override Object get() {
					return ...
				}
			},
			...
			}
	};
	
	private boolean isExist(String param)	{
		for (ParamHash p: paramsList)
			if (p.key.equals(param))	{
				return	true;
			}
		return	false;
	}
	
	void add(String params[])	{
		for (String p: params)
			if (!isExist(p))	{
				for(int i=0; i<paramsGetter.length; i++)
					if (paramsGetter[i].key.equals(p))	{
						paramsList.add(new ParamHash(p, i));
						break;
					}
			}			
	}
		
	Bundle get()	{
		Bundle bundle = new Bundle();
		for (ParamHash p: paramsList) {
			int index = p.index;
			Object data = paramsGetter[index].get();
			if (data.getClass()==Double.class)
				bundle.putDouble(p.key, (Double)data);
			else if (data.getClass()==Long.class)
				bundle.putLong(p.key, (Long)data);
			else if (data.getClass()==Boolean.class)
				bundle.putBoolean(p.key, (Boolean)data);
			else if (data.getClass()==String.class)
				bundle.putString(p.key, (String)data);
		}
		return	bundle;
	}

}
...
Рейтинг: 0 / 0
10.09.2012, 17:52:36
    #37951483
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Если get() у каждого варианта геттера всегда одного типа, то так
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
	
private abstract class ParamGetter	{
		String key;		
		ParamGetter(String key)	{
			this.key = key;
		}		
		abstract Object get();	
                abstract void saveMyObjectToBundle(Object obj, Bundle b);
	}

new ParamGetter("BALANCE")	{
				@Overridevoid saveMyObjectToBundle(Object obj, Bundle b) {
					bundle.putString( key, (String) obj);
				}
			}...

	Bundle get()	{
		Bundle bundle = new Bundle();
		for (ParamHash p: paramsList) {
			int index = p.index;
			Object data = paramsGetter[index].get();
                        paramsGetter[index].saveMyObjectToBundle(data, bundle);
...



Ну там впринципе тогда и get() не нужен, если это за рамки текущего класса не выходит
...
Рейтинг: 0 / 0
10.09.2012, 18:04:36
    #37951507
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Лагман Спасибо!
Да, у каждого варианта геттера всегда один и тот же тип.
Предположим у меня 10 параметров типа String, получается что для 10 реализаций ParamGetter мну нужно повторить одинаковый метод
Код: java
1.
2.
3.
4.
@Overridevoid 
saveMyObjectToBundle(Object obj, Bundle b) {
	bundle.putString( key, (String) obj);
}
...
Рейтинг: 0 / 0
10.09.2012, 18:10:51
    #37951519
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Можно сделать абстрактные геттеры для типов, потом унаследовать от них.
Но тут особо палку перегибать наверное тоже не стоит, а то и до абстрактной фабрики фабрик недалеко.

А у Bundle нет случайно перегруженного метода put( с разными типами ) ?
...
Рейтинг: 0 / 0
10.09.2012, 18:19:19
    #37951537
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
авторА у Bundle нет случайно перегруженного метода put( с разными типами ) ? К сожалению нет - а то зачем "огород городить".
Был бы Bundle.putObject :(
Есть putParcelable, и putSerializable, но зачем связываться если у меня нет "сложных" параметров объектов - только примитивные типы да String.
android.os.Bundle: http://www.androidadb.com/source/pdn-slatedroid-read-only/eclair/frameworks/base/core/java/android/os/Bundle.java.html
...
Рейтинг: 0 / 0
10.09.2012, 18:27:50
    #37951545
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
А как Вы потом их получаете из Bundle - с помощью аналогичных геттеров?
...
Рейтинг: 0 / 0
10.09.2012, 18:38:27
    #37951559
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Данные передаются в другой процесс с помощью объекта Bundle
При отображении данных я знаю что в текстовом поле 1 должно быть отображено значение параметра "PARAM1", и так далее. (То есть у меня есть шаблон отображаемых данных - в терминах Android - layout xml)

Код: java
1.
2.
String s = bundle.getString("PARAM1");
remoteView.setTextViewText(getString(R.id.info), s);



R.id.info - Идентификатор текстового поля
...
Рейтинг: 0 / 0
10.09.2012, 18:40:28
    #37951563
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Так может тогда String туда и класть? Все равно тип не используется.
...
Рейтинг: 0 / 0
10.09.2012, 18:41:39
    #37951565
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Или у вас
String s = bundle.getString("PARAM1");
Double ss = bundle.getDouble("PARAM2");
...
Рейтинг: 0 / 0
10.09.2012, 18:47:35
    #37951578
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
В принципе можно, потому что все потом "конвертируется" в String
Но как же принцип - данные отдельно (в сервисе) - Отображение(форматирование) отдельно...

Передача даты(через long)
Код: java
1.
2.
3.
4.
5.
6.
	Date date;
	long updated = bundle.getLong("LAST_UPDATE", 0);
	if (updated!=0)
		date = new Date(updated);
	else
		date = new Date();
...
Рейтинг: 0 / 0
10.09.2012, 18:50:13
    #37951585
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Опоздал :)
Да Вы правы:
String s = bundle.getString("PARAM1");
Double ss = bundle.getDouble("PARAM2");

Под словом "конвертируется" я имел ввиду, что в интерфейсе я использую только TextView - remoteView.setTextViewText(id, "какой-то текст");
...
Рейтинг: 0 / 0
10.09.2012, 18:57:29
    #37951604
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
В общем, довел идиому ООП до абсурдности, увеличив код:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
	private abstract class ParamGetter	{
		String key;		
		ParamGetter(String key)	{
			this.key = key;
		}		
		abstract Object get();	
		abstract void saveObject2Bundle(Object obj, Bundle bundle);
	}

	private abstract class DoubleParamGetter extends ParamGetter...
	private abstract class LongParamGetter extends ParamGetter...
	private abstract class BooleanParamGetter extends ParamGetter...
	private abstract class StringParamGetter extends ParamGetter...

	private final ParamGetter[] paramsGetter = {
			new DoubleParamGetter("BALANCE")	{
				@Override Object get() {
					...
					return (Double)value;
				}
			},
			...
	};

	Bundle get()	{
		Bundle bundle = new Bundle();
		for (ParamHash p: paramsList) {
			int index = p.index;
			Object data = paramsGetter[index].get();
			paramsGetter[index].saveObject2Bundle(data, bundle);
		}
		return	bundle;
	}
...
Рейтинг: 0 / 0
10.09.2012, 19:09:45
    #37951615
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Вообще с if лучше было, а теперь получается у вас зависимость от Bundle в *Getter,
а если делать адаптер Bundle-Getter то там или if, или внедрять обертку котороая пишет себя в Bundle (опять зависимость). А ещё можно нагромоздить рефлексией ).
Может ъ-гуру подскажут как сделать правильно
...
Рейтинг: 0 / 0
10.09.2012, 19:12:07
    #37951617
Lisichkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
Да, забыл сказать есть параметр типа Boolean (передаваемые от сервиса к интерфейсу) который не отображается на прямую - он ответствен за то как отображается данные.
...
Рейтинг: 0 / 0
11.09.2012, 14:30:49
    #37952650
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Массив указателей на функции (в терминах C/С++)
> Есть необходимость создать массив указателей на функции (в терминах C/С++)
> Задача описывается следующим образом – имеется визуальный компонент который
> отображает данные, получаемые из другого потока. В зависимости от предпочтений
> пользователя данные показываются по разному (рассчитываются сервисом). Раньше я
> реализовал это с использованием кучи if'ов. Решил создать класс WidgetParams –
> отвечающий за хранение всех доступных параметров и способов их расчета.

> Смущает функция Bundle get() - в которой пришлось через if указать список

Это один базовый абстрактрый интерфейс (класс с одними методами)
и набор классов, реализующих этот интерфейс.
А потом массив объектов типа этой базовый класс.

Как раз позволяет уйти от такой порнографии, как у тебя в коде.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Массив указателей на функции (в терминах C/С++) / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]