Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / instanceof есть сомнения / 22 сообщений из 22, страница 1 из 1
01.05.2013, 11:08:49
    #38245987
medvedko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Есть супер-пупер проект, но в нем вижу больше тысячи instanceof и полторы тысячи проверок на null.
Вопрос: можно ли уже по этим признакам перестать считать проект суперским? Или я ошибаюсь?
...
Рейтинг: 0 / 0
01.05.2013, 11:53:46
    #38246005
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
instanceof скорее всего свидетльствует о кривом дизайне. Потому что он появляется там где нужно было использовать полиморфизм. А уж если это массовый подход в десятках класса, то архитектуры у кода нет совсем.
вездесущие проверки на null - палка о двух концах. С одной стороны, да. Это тоже признак не самого лучшего кода. С другой стороны, не так много есть действительно работающих альтернатив.
...
Рейтинг: 0 / 0
01.05.2013, 12:10:45
    #38246014
medvedko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Первая моя мысль была тоже о кривой архитектуре, но какая-то нерешительная мысль, не люблю критиковать и обижать людей, всегда присутствует сомнение: может я просто не понимаю гениальной задумки архитектора? Вот и ищу подтверждения незаинтересованной публики с некоторым опытом разработки. Спасибо.
...
Рейтинг: 0 / 0
01.05.2013, 14:50:03
    #38246085
just_vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Массовые instanceof не встречал, а вот проверки на null в последнее время сам стараюсь расставлять везде, где есть хоть малейшие сомнения. А то смотришь логи продакшен сервака, а там неведомые NPE, которые непонятно откуда берутся, так что лучше явная проверка на null и выкидываем адекватное исключение, чтобы потом можно было размотать, откуда эти null'овые объекты берутся.
...
Рейтинг: 0 / 0
01.05.2013, 15:34:36
    #38246106
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Blazkowiczinstanceof скорее всего свидетльствует о кривом дизайне. Потому что он появляется там где нужно было использовать полиморфизм.
Я знаю два исключения:
1. Проект является фрейморком, в котором очень много завязано на рефлексию (правда, не уверен насчет именно instanceof);
2. Реализация паттерна visitor удобно делается через instanceof.
...
Рейтинг: 0 / 0
01.05.2013, 15:50:26
    #38246112
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Leonidv1. Проект является фрейморком, в котором очень много завязано на рефлексию (правда, не уверен насчет именно instanceof);
Это единичные случаи. Топикастер говорит о массовом использовании.

Leonidv2. Реализация паттерна visitor удобно делается через instanceof.
Покажи.
...
Рейтинг: 0 / 0
01.05.2013, 21:25:26
    #38246226
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Идея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   if (n instanceof NodeTypeA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   } else if (n instanceof NodeTypeB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
}


Насколько я понимаю, чистое ООП решение заключается в том, что каждый имет метод getType.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   switch(n.getType() {
   case NODE_TYPE_A:
       visitor.onNodeTypeA((NodeTypeA)n);
       break;
   case NODE_TYPE_B:
       visitor.onNodeTypeB((NodeTypeB)n);
       break;
 }
}
...
Рейтинг: 0 / 0
01.05.2013, 21:39:58
    #38246233
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Недоперепроектировали
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public void visit(Visitor visitor) {
  for (Node n : nodesA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   }
   for (Node n : nodesB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
...
Рейтинг: 0 / 0
02.05.2013, 07:54:08
    #38246420
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   if (n instanceof NodeTypeA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   } else if (n instanceof NodeTypeB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }
}


Насколько я понимаю, чистое ООП решение заключается в том, что каждый имет метод getType.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
   switch(n.getType() {
   case NODE_TYPE_A:
       visitor.onNodeTypeA((NodeTypeA)n);
       break;
   case NODE_TYPE_B:
       visitor.onNodeTypeB((NodeTypeB)n);
       break;
 }
}



Чистое ООП решение:

Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}



А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.

<:o)
...
Рейтинг: 0 / 0
02.05.2013, 09:12:47
    #38246435
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
либо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
...
Рейтинг: 0 / 0
02.05.2013, 09:49:08
    #38246445
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
chabapokлибо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
Вместо с даункастингом? Что-то не верится
...
Рейтинг: 0 / 0
02.05.2013, 23:10:51
    #38246864
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Blazkowiczchabapokлибо же, там высокооптимизированный код. способ с istanceof работает раз в 10 быстрей полиморфизма.
Вместо с даункастингом? Что-то не верится

сам был удивлен. Сейчас наверное вы попросите предоставить код, которым оно тестилось. Этот код утерян, т.к. тестил давно, но вот набросал на скору руку аналог. Полиморфизм получается вдвое дольше.

При этом если прибить класс С, то полиморфизм будет сравним по времени с instanceof, т.к. jvm умеет делать какую-то хитрую оптимизацию когда только 2 подкласса.

Код: 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.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
package javaapplication7;

public class InstanceOf {
 
	private static final int REPS = 1000000000;

 
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			System.out.println("\nRep " + i);
				testInstanceOf();
				testIsClass();
				testOO();
				testId();
		}
	}
 
    
    
    static int i;
    
    static A a = new A();
    static B b = new B();
    static C c = new C();
    
    static Base[] x = {a,b,c};
    static Base calcNextObj(){
        i++;
        if (i<0){i=0;}
        return x[i%3];
    }
    
    
	private static void testInstanceOf() {
		long start = System.currentTimeMillis();
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		for (int i = 0; i < REPS; i++) {
            
            Base base = calcNextObj();
			if (base instanceof A) {
				((A) base).doA();
			} else if (base instanceof B) {
				((B) base).doB();
			} else if (base instanceof C) {
				((C) base).doC();
			} else {
                throw new RuntimeException("wrong class");
            }
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("InstanceOf " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testOO() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			base.doSomthing();
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("OO " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testId() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			switch (base.type) {
                case A.A_TYPE:
                    ((A) base).doA();
                    break;
                case B.B_TYPE:
                    ((B) base).doB();
                    break;
                case C.C_TYPE:
                    ((C) base).doC();
                    break;

                default:
                    throw new RuntimeException();
			}
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("Id " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
	private static void testIsClass() {
        a.sum = 0;
        b.sum = 0;
        c.sum = 0;
		long start = System.currentTimeMillis();
		for (int i = 0; i < REPS; i++) {
            Base base = calcNextObj();
			if (base.getClass() == A.class) {
				((A) base).doA();
			} else if (base.getClass() == B.class) {
				((B) base).doB();
			}else if (base.getClass() == C.class) {
				((C) base).doC();
			}
		}
		long diff = System.currentTimeMillis() - start;
		System.out.println("class== " + diff + " " + a.sum+" "+b.sum+" "+c.sum);
	}
 
}


    interface IdoSome{
        void doSomthing();
    }


	class Base  implements IdoSome{
        
		int sum;
		int type;
 
		public Base(int type) {
			this.type = type;
		}
 
        @Override
		public void doSomthing(){
            sum +=1;
        }
	}
 
	class A extends Base implements IdoSome{
        final static int A_TYPE=1;
		public A() {
			super(A_TYPE);
		}
 
		public void doA() {
			sum += 2;
		}
 
		@Override
		public void doSomthing() {
			sum += 2;
		}
	}
 
	class B extends Base implements IdoSome {
        final static int B_TYPE=2;
        
		public B() {
			super(B_TYPE);
		}
 
		public void doB() {
			sum -= 2;
		}
 
		@Override
		public void doSomthing() {
			sum -= 2;
		}
	}


	class C extends Base implements IdoSome {
        final static int C_TYPE=3;
        
		public C() {
			super(C_TYPE);
		}
 
		public void doC() {
			sum -= 2;
		}
 
		@Override
		public void doSomthing() {
			sum -= 2;
		}
	}



И это оно еще быстро работает. Когда я тестил, то у меня ооп получалось раз в 10 медленей (видимо старая jvm), но этот код утерян.
...
Рейтинг: 0 / 0
02.05.2013, 23:16:29
    #38246869
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
кстати, jvm вполне может видеть (в том смысле, что я не вижу препятствий против такой оптимизации), что кастинг осуществляется внутри проверки instanceof и второй раз такую проверку не делать.
...
Рейтинг: 0 / 0
03.05.2013, 07:14:07
    #38246972
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
chabapokBlazkowiczпропущено...

Вместо с даункастингом? Что-то не верится

сам был удивлен. Сейчас наверное вы попросите предоставить код, которым оно тестилось. Этот код утерян, т.к. тестил давно, но вот набросал на скору руку аналог. Полиморфизм получается вдвое дольше.

При этом если прибить класс С, то полиморфизм будет сравним по времени с instanceof, т.к. jvm умеет делать какую-то хитрую оптимизацию когда только 2 подкласса.

И это оно еще быстро работает. Когда я тестил, то у меня ооп получалось раз в 10 медленей (видимо старая jvm), но этот код утерян.

Вопрос конечно философский, что важнее время исполнения программы или скорость модификации программы :-)
Лично я бы, вместо оптимизации выбрал бы упрощение кода.
Просто когда вдруг понадобиться добавить классы D, E, F и пр.
Причем программистами которые не с самого начала проекта (будем считать что прошло 1-2 поколения программиста), то поиск что-то вроде testInstanceOf(), testID() и testIsClass() может вылиться в увлекательное приключение как минимум на неделю.
...
Рейтинг: 0 / 0
03.05.2013, 08:44:00
    #38246991
пролетевший
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
visitor не требует instanceof или каких либо проверок типа. Все делает компилятор:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
for(Node n: nodes ) {
       node.visit(visitor);
}

class NodeA extends Node {
.............
@Override
public void visit(Visitor visitor) {
      visitor.onNodeA(this);
} 


В целом если куча instanceof, то или унаследованный с Java <1.5 код, без дженериков, или таки архитектура кривая.
Проверки на null хороши в assert на входе публичных методов, в остальных местах лучше пользоваться "специальными значениями". Например, для коллекции использовать пустую если нет результата.
...
Рейтинг: 0 / 0
03.05.2013, 09:38:29
    #38247006
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
mad_nazgulЧистое ООП решение:
Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}


А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.
<:o)
В Java так нельзя.
...
Рейтинг: 0 / 0
03.05.2013, 09:39:11
    #38247007
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
maytonНедоперепроектировали
LeonidvИдея такая:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public void visit(Visitor visitor) {
  for (Node n : nodesA) {
       visitor.onNodeTypeA((NodeTypeA)n);
   }
   for (Node n : nodesB) {
       visitor.onNodeTypeB((NodeTypeB)n);
   }
 }



Это сработает только в том случае, если порядок следования элементов в структуре нам не нужен.
...
Рейтинг: 0 / 0
03.05.2013, 09:48:54
    #38247010
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
пролетевшийvisitor не требует instanceof или каких либо проверок типа. Все делает компилятор:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
for(Node n: nodes ) {
       node.visit(visitor);
}

class NodeA extends Node {
.............
@Override
public void visit(Visitor visitor) {
      visitor.onNodeA(this);
} 



Красивое решение, спасибо. Есть недостаток, что элемент начинает заниматься еще и логикой перехода, но он не значительный и перевешывает бонусы.
...
Рейтинг: 0 / 0
03.05.2013, 10:30:32
    #38247035
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Leonidvmad_nazgulЧистое ООП решение:
Код: java
1.
2.
3.
4.
5.
public void visit(Visitor visitor) {
  for (Node n : nodes) {
       visitor.onNodeType(n);
  }
}


А какой там Тип у ноды должно быть пофиг.
Полиморфизм рулит и педалит.
<:o)
В Java так нельзя.

Странно почему?!
Во всех других ООП ЯП можно, а в Java нельзя. :-)
...
Рейтинг: 0 / 0
03.05.2013, 11:49:12
    #38247062
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
mad_nazgul,

да, я тоже чего-то не понял. Чего там в Java нельзя? Итерировать?
...
Рейтинг: 0 / 0
03.05.2013, 19:54:02
    #38247385
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
mad_nazgulВо всех других ООП ЯП можно, а в Java нельзя. :-)
Не во всех есть dynamic dispatch.
...
Рейтинг: 0 / 0
04.05.2013, 07:06:31
    #38247508
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
instanceof есть сомнения
Leonidvmad_nazgulВо всех других ООП ЯП можно, а в Java нельзя. :-)
Не во всех есть dynamic dispatch.

Например?
Просто я не встречал таких ООП ЯП.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / instanceof есть сомнения / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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