Тема открыта по просьбе жителей Королевства и посвящена обсуждению вопросов оптимизации кода. Выставляйте свои лучшие и худшие тексты и не стесняйтесь их обсуждать. В споре рождается истина. Или, по крайней мере, оптимизация.
Всего в теме 737 сообщений
Добавить свое сообщение
Отслеживать это обсуждение
- Тестирование проекта. Отладка.
- Подводные камни
- Централизованная обработка ошибок
- Бета-тестирование
- Давайте учиться на ошибках.
- Почему программисты допускают ошибки?
- Автоматизированные тесты для GUI
- О системах контроля ошибок
№ 427 27-05-2008 03:56 | |
Ответ на »сообщение 426« (Бел Амор)
___________________________
Исправление ссылок:
8. При полной компиляции проекта не должно быть ни одного предупреждения. Более подробно эта тема раскрыта здесь: »сообщение 208 в теме №383 на БП«
10. Внутри процедуры переменную Result также можно использовать гораздо шире, чем это обычно делается. Вплоть до использования её в качестве переменной цикла. Но тут нужно быть очень осторожным и помнить, что переменная цикла после завершения цикла имеет неопределённое значение. Использовать переменную цикла, в качестве которой используется Result, вне цикла можно только при выходе из цикла по Exit, т.е. при выходе из процедуры нпосредственно из цикла. Этот вопрос рассматривался здесь: »сообщение 199 в теме №383 на БП«
№ 426 27-05-2008 03:38 | |
...А найти эту тему я хотел для того, чтобы ответить здесь на »вопрос КС №62346«
В нём автор попросил накидать ему побольше советов, что называется, "хороших и разных" и я посчитал, что эта тема наилучшим образом подходит для ответа на этот вопрос... Дальше последует поток сознания на самые разные темы. Очень кратенько, без особых обоснований, поскольку всё это уже неоднократно обсуждалось. Всё нижеследующее отражает моё личное мнение, с которым могут быть согласны далеко не все...
1. На время отладки включать максимальный контроль: Range checking, Overflow checking и т.д.
2. Начинать новый проект следует с отключения помещения новых форм в список автосоздаваемых. Форм - десятки, а датамодулей - единцы и их можно сделать автосоздаваемыми и вручную. Кроме того, часто имеет значение порядок их создания, поэтому может иметь смысл дата-модули создавать самому в конструкторе главной формы в нужном порядке. Написанное кодом всегда надёжнее того, что можно случайно зацепить мышкой в каком-либо списке.
3. Сразу после добавления в проект новой формы следует удалить автоматически создаваемое объявление переменной для этой формы. Во-первых, это не будет провоцировать на использование таких переменных, во-вторых, это сразу выявит факт того, что форма по какой-либо причине попала в список автосоздаваемых, и в третьих, исключит возможность использования таких переменных "по запарке" (например, вместо Self).
4. Создавать формы следует путём вызова конструктора, а не Application.CreateForm
5. Переменные типа форм либо должны быть локальными, либо можно вообще обойтись без переменной, используя конструкцию with TForm1.Create(nil) do
6. В качестве владельца коструктору формы лучше передавать nil. Это лучше, чем часто втавляемый на автомате Application тем, что если забыли освободить форму, то при контроле утечки памяти в случае использования в качестве владельца Application при завершении приложения такие формы будут автоматически освобождаться и информация о них не попадёт в отчёт. При использовании в качестве владельца nil такие формы доживут до отчёта и на них будет обращено внимание.
7. Включение выдачи отчёта об утечке памяти при завершении программы в последних версиях Delphi осуществляется, в частности, включением в код программы строчки: ReportMemoryLeaksOnShutdown := True; 8. При полной компиляции проекта не должно быть ни одного предупреждения. Более подробно эта тема раскрыта здесь: »сообщение 383 в теме №208 на БП«
9. Внутри процедуры параметр, переданный без const или var можно использовать как локальную переменную. Об этом часто забывают.
10. Внутри процедуры переменную Result также можно использовать гораздо шире, чем это обычно делается. Вплоть до использования её в качестве переменной цикла. Но тут нужно быть очень осторожным и помнить, что переменная цикла после завершения цикла имеет неопределённое значение. Использовать переменную цикла, в качестве которой используется Result, вне цикла можно только при выходе из цикла по Exit, т.е. при выходе из процедуры нпосредственно из цикла. Этот вопрос рассматривался здесь: »сообщение 383 в теме №199 на БП«
11. Часто бывают удобными вложенные процедуры.
12. Вместо отдельнолежащих процедур часто удобно использовать классовые методы (см. class methods) Пример использования можно посмотреть здес: »вопрос КС №50002« (class function CheckPassword: Boolean).
№ 425 27-05-2008 03:36 | |
Решил найти эту тему и по простоте своей душевной задал поиск 50 последних активных тем... Наивный... Оказывается, такая замечательная тема пребывает в забвении уже более года... И остановились здесь, оказывается, ещё на "Методе Geo"... Уж коли я сюда зашёл, заодно подкину идею небольшого усовершенсвования вышеупомянутого метода путём использования совместно с ним включаемых файлов: »вопрос КС №61819«
№ 424 28-02-2007 07:55 | |
Ответ на »сообщение 423« (Бел Амор)
___________________________
>>> Я присоединяюсь к неоднократно высказывавшемуся предложению написать статью на эту тему
Вообще-то у меня в планах был цикл статей по разработке и использованию собственных компонент, где я и собирался описать данный прием. Но это последнее обсуждение подтолкнуло к мысли, что не надо ждать, а надо написать небольшую статью прямо сейчас, так как очень много ценных мыслей разбросано в разных обсуждениях.
Постараюсь найти время на это.
№ 423 28-02-2007 07:40 | |
Ответ на »сообщение 422« (Geo)
___________________________
>>> Посмотрите вот это обсуждение http://delphikingdom.ru/asp/articles_forum.asp?ArticleID=1296
Спасибо за ссылку.
А вот не надо было делать: "На самом деле подменить можно не только родительский класс, а вообще любой, у которого при текущих настройках список свойств в dfm не противоречит свойствам замещающего класса" ;-) Вы шаманите,
Мы не шаманим, мы экспериментируем :)
>>> а использую позднее связывание как документированную возможность ООП и Delphi.
Речь вообще не об этом. Речь о том, что способ основан на предположении, что "дизайнер вообще не смотрит по сторонам, а занимается только тем кодим, который он сам вставил".
До определенной степени это так. Но только до определенной. В будущем это может измениться.
>>> Впрочем, смотрите обсуждение по ссылке, приведенной выше.
Посмотрел, еще раз спасибо. Я присоединяюсь к неоднократно высказывавшемуся предложению написать статью на эту тему. Она в любом случае будет полезна. Только в ней обязательно надо будет дать ссылки как минимум на вопрос 35814 и на упомянутое вами обсуждение, дабы свежий народ не бросался обсуждать одни и те-же нюансы по второму-третьему кругу.
№ 422 28-02-2007 01:47 | |
Ответ на »сообщение 421« (Бел Амор)
___________________________
>>> Возможность, которую использует этот метод, является недосмотром программистов Borland. Программисты CodeGear в любой момент могут это исправить (если еще не исправили)
Посмотрите вот это обсуждение http://delphikingdom.ru/asp/articles_forum.asp?ArticleID=1296
Там я постарался проанализировать "опасность" применения этого приемчика. Пересказывать не хочется, так как я тоам достаточно много написал.
>>> Получаем исключение: "Property BevelKind does not exist"
А вот не надо было делать: " На самом деле подменить можно не только родительский класс, а вообще любой, у которого при текущих настройках список свойств в dfm не противоречит свойствам замещающего класса" ;-) Вы шаманите, а использую позднее связывание как документированную возможность ООП и Delphi. Впрочем, смотрите обсуждение по ссылке, приведенной выше.
№ 421 27-02-2007 16:00 | |
Хотелось бы высказать несколько мыслей по поводу метода, описанного в »вопрос КС №35814«
Я не знаю, работает ли он на D2006, если кому несложно, проверьте, напишите сюда (у меня ее нет).
1. Этот способ имеет смысл применять только до Delphi 7, поскольку в дальнейших версиях он полностью перекрывается возможностями class helper'ов.
2. Возможность, которую использует этот метод, является недосмотром программистов Borland. Программисты CodeGear в любой момент могут это исправить (если еще не исправили).
3. На самом деле подменить можно не только родительский класс, а вообще любой, у которого при текущих настройках список свойств в dfm не противоречит свойствам замещающего класса. А поскольку в dfm пишутся не все свойства, а только те, значение которых не совпадают со значениями, указанными в default, то открываются широчайшие возможности для махинаций. Причем, если потом изменить значения свойств, то эти свойства могут попасть в dfm и вызвать конфликт. Приведу пример.
Делаем форму, помещеаем на нее TPanel и TStaticText (свойства не меняем).
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Unit2;
type
TForm1 = class(TForm)
Panel1: TPanel;
StaticText1: TStaticText;
end;
var
Form1: TForm1;
implementation
end.
Создаем второй модуль:
unit Unit2;
interface
Uses ExtCtrls, Classes, Graphics;
type
TStaticText = class(TPanel)
public
Constructor Create(AOwner: TComponent); override;
end;
implementation
constructor TStaticText.Create(AOwner: TComponent);
begin
inherited;
color := clRed;
end;
end.
Запускаем и получаем замечательно работающую форму с двумя панелями: обычной и красной.
Теперь ищем свойство, которое есть в TStaticText, но нет в TPanel. Например, BevelKind.
Теперь меняем в TStaticText BevelKind с bkNone на bkFlat. Запускаем... Получаем исключение: "Property BevelKind does not exist". Возвращаем его в bkNone - опять работает. Красота...
Так что цитата, приведенная Антоном Григорьевым в обсуждении вопроса 35814 кажется мне изумительно уместной :)
Способ достаточно интересный и неожиданный. По крайней мере он заслуживает того, чтобы о нем знать. Его даже можно иногда применять на старой Delphi. Но хорошо отдавая себе отчет в том, что ты делаешь. И применять его широко я бы не стал.
№ 420 27-02-2007 12:42 | |
В общем, вопрос решился следующим образом:
Во вспомогательный модуль помещаем код:
type
TRadioGroup = class(ExtCtrls.TRadioGroup)
protected
procedure Paint; override;
procedure SetEnabled(Value: Boolean); override;
end;
procedure TRadioGroup.Paint;
begin
inherited;
Canvas.Font.Style := [fsBold];
Canvas.Font.Color := IfThen(Enabled, clWindowText, clGrayText);
Canvas.TextOut(8, 0, Caption);
end;
procedure TRadioGroup.SetEnabled(Value: Boolean);
begin
inherited;
Invalidate;
end;
Подключаем в соответствующих формах, указывая этот модуль в конце Uses секции interface.
При переходе на свежую версию Delphi либо удаляем вушеуказанный код, либо преобразуем его в class helper. Так что это решение отвечает всем условиям задачи, сформулированным в »сообщение 411«.
Единственно, что человеку, не посвященному в эту тайну, будет крайне тяжело понять, откуда там берется жирный заголовок. Но комментарии еще никто не отменял...
Так что спасибо Ins'у и Geo, а также всем, принявшим участие в ломании копий, штакетника и прочего...
№ 419 27-02-2007 12:36 | |
Ответ на »сообщение 417« (Андрей Токинов)
___________________________
>>> »вопрос КС №49421« опять замкнулся на »вопрос КС №35814«
А кто-то, помнится, переживал, что вопрос 35814 где-то там затеряется и "его никто не найдет". По-моему, он идет на рекорд по цитируемости... :)
№ 418 27-02-2007 12:33 | |
Ответ на »сообщение 416« (panda)
___________________________
>>> Пример, который привел Ins, в Вашем случае будет смотреться лучше всего
Да, я считаю это оптимальным вариантом.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|