Традиционное ООП подразумевает, что каждый метод находится только в одном классе, причём набор методов (и, конечно, членов) определяет класс, как таковой.
С другой стороны, объект, по отношению к которому вызван метод, это ни что иное, как первый (или нулевой) параметр функции, который передан в неё по ссылке.
То есть, понятие метода, по отношению к понятию функции, есть понятие о такой функции, у которой роль одного из параметров сильно отличается от ролей всех остальных параметров. Причём этот параметр всегда может быть только один.
С философской точки зрения совершенно непонятно, почему только один из параметров функции может играть особую роль.
Некузявость этой модели проявляется в определении оператора сложения в C++. Действительно, с одной стороны, сложение --- это одна из операций, которая может характеризовать класс (например, вектора или матрицы), то есть, это метод. С другой стороны, сложение требует двух равноправных аргументов, а, следовательно, оно не может только к одному из них относиться особенно.
Посему в Си+ сделано два способа определения таких операторов -- и как функции-члена и как функции-друга.
В Джаве операторов нет, но всё равно те же самые проблемы возникают, например, с методом Equals.
Ещё одно место, в котором возникает проблема -- документация. Обычно, все методы документированы в том классе, к которому они принадлежат. Соответственно, если какой-то метод, по логике, принадлежит к нескольким классам, то его хрен найдёшь.
Например, я сейчас пытаюсь понять, как в библиотеке HttpClient устанавливать прокси. Я нашёл класс HttpProxyHost extends HttpHost (в версии 4, я так понимаю, оставили только HttpHost). С точки зрения ООП это логично -- данные определённого вида инкапсулированы в свой объект.
И вот теперь мне надо найти, где же эта прокся устанавливается? Наверняка это один-единственный метод, в одном-единственном классе, который принимает эту HttpProxyHost. То есть, этот метод находится в особых отношениях с классом HttpProxyHost и должен был бы быть его членом... Но, он больше подошёл к другому классу и всё -- теперь не поймёшь, как устанавливать прокси...
четверг, 9 сентября 2010 г.
среда, 10 марта 2010 г.
Исключение работает в 30 тысяч раз медленнее!
Вот такой результат
Test1
Start Value: 48570986229
End Value: 48570988285
QueryPerformanceCounter minimum resolution: 1/3579545 seconds.
Increment time: 0,00057437467611107 seconds.
Test2
Start Value: 48570989868
End Value: 48627848797
QueryPerformanceCounter minimum resolution: 1/3579545 seconds.
Increment time: 15,8844012297652 seconds.
First was 27655,12 faster
Press Enter to finish ...
Выдаёт вот такая программа:
Test1
Start Value: 48570986229
End Value: 48570988285
QueryPerformanceCounter minimum resolution: 1/3579545 seconds.
Increment time: 0,00057437467611107 seconds.
Test2
Start Value: 48570989868
End Value: 48627848797
QueryPerformanceCounter minimum resolution: 1/3579545 seconds.
Increment time: 15,8844012297652 seconds.
First was 27655,12 faster
Press Enter to finish ...
Выдаёт вот такая программа:
static class Program
{
[DllImport("kernel32.dll")]
extern static short QueryPerformanceCounter(ref long x);
[DllImport("kernel32.dll")]
extern static short QueryPerformanceFrequency(ref long x);
const int count = 5000;
static bool IsEven1(int value)
{
if ((value % 2) == 0)
{
return true;
}
else
{
return false;
}
}
static void IsEven2(int value)
{
if ((value % 2) == 0)
{
return;
}
else
{
throw new Odd();
}
}
static void Test1()
{
int c1 = 0;
int c2 = 0;
for (int i = 0; i < count; ++i)
{
if (IsEven1(i))
{
c1++;
}
else
{
c2++;
}
}
}
static void Test2()
{
int c1 = 0;
int c2 = 0;
for (int i = 0; i < count; ++i)
{
try
{
IsEven2(i);
c1++;
}
catch (Odd)
{
c2++;
}
}
}
static void Main()
{
long ctr1 = 0, ctr2 = 0, freq = 0;
double itime1 = 0, itime2 = 0;
QueryPerformanceFrequency(ref freq);
Console.WriteLine("Test1");
if (QueryPerformanceCounter(ref ctr1) != 0) // Begin timing.
{
Test1();
QueryPerformanceCounter(ref ctr2); // Finish timing.
Console.WriteLine("Start Value: " + ctr1);
Console.WriteLine("End Value: " + ctr2);
Console.WriteLine("QueryPerformanceCounter minimum resolution: 1/" + freq + " seconds.");
itime1 = (ctr2 - ctr1) * 1.0 / freq;
Console.WriteLine("Increment time: " + itime1 + " seconds.");
}
else
Console.WriteLine("High-resolution counter not supported.");
Console.WriteLine("Test2");
if (QueryPerformanceCounter(ref ctr1) != 0) // Begin timing.
{
Test2();
QueryPerformanceCounter(ref ctr2); // Finish timing.
Console.WriteLine("Start Value: " + ctr1);
Console.WriteLine("End Value: " + ctr2);
Console.WriteLine("QueryPerformanceCounter minimum resolution: 1/" + freq + " seconds.");
itime2 = (ctr2 - ctr1) * 1.0 / freq;
Console.WriteLine("Increment time: " + itime2 + " seconds.");
}
else
Console.WriteLine("High-resolution counter not supported.");
Console.WriteLine("First was " + (itime2/itime1).ToString("#.00") + " faster");
// Make the console window wait.
Console.WriteLine();
Console.Write("Press Enter to finish ... ");
Console.Read();
}
}
public class Odd : Exception
{
}
Подписаться на:
Комментарии (Atom)
