Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];

Вниз

Переопределение класса.   Найти похожие ветки 

 
Pavia ©   (2014-11-01 22:33) [0]

Собственно вопрос как можно переопределить класс?
К примеру есть есть проект с большим числом классов. Скажем так это некоторый каркас(по агл. FrameWork) Хочу добавить юнит так что-бы он заменил определенные классы на свои.  Семантика сохраняется, а вот структура класса, методы, родитель меняются. Сохраняются методы которые вызываются из классов которые не заменены. Под сохранением имеется ввиду сохранность интерфейса но не обязательно реализации.  

Это вообще возможно и если да, то как?

Собственно примеры из других языков тоже приветсвуются.


 
Rouse_ ©   (2014-11-01 22:36) [1]

Это называется интерфейс, если логика иерархии класов изначально не была заточена на использование базового абстрактного класса


 
DVM ©   (2014-11-01 22:38) [2]


> Rouse_ ©   (01.11.14 22:36) [1]

если фреймворк изначально не заточен под возможность то и интерфейсы не помогут.


 
Rouse_ ©   (2014-11-01 22:42) [3]

Та вот еще, глупости какие :) все можно сделать, вопрос во времязатратах, тем более - а вдруг форма всеже реализует нужный интерфейс?


 
DVM ©   (2014-11-01 22:48) [4]


> Rouse_ ©   (01.11.14 22:42) [3]
> Та вот еще, глупости какие :) все можно сделать, вопрос
> во времязатратах

Ну и как это предполагается делать? Допустим есть два класса первый в одном модуле, второй в другом. Необходимо сделать так, чтобы класс во втором модуле используя класс из первого модуля взял реализацию не из первого модуля, а нашу. Код обоих модулей править нельзя.
Не, есть конечно всякие шаманские методы Geo и прочее, но применение их ограничено весьма.

Если время не играет роли так может переписать этот фреймворк и всего делов?


 
Rouse_ ©   (2014-11-01 23:46) [5]

А, ты про это - ну к приеру вариант грязных хаков рассматриваем? :))
Я то про интнрфейсы собсно спич вёл


 
Rouse_ ©   (2014-11-01 23:48) [6]

Пардон за очепятки - планшет глючит Периодичски


 
Eraser ©   (2014-11-02 02:51) [7]


> Pavia ©   (01.11.14 22:33) 

тогда Framework нужно разрабатывать с использованием "технологии"
class of


 
Pavia ©   (2014-11-02 08:40) [8]

Рассматриваю всё. В том числе и хаки.
Каркас я проектирую сам. Так что изменения внести можно пока не поздно.
DVM правильно сформулировал.  Чего не хотелось это переписывать файлы каркаса.
Интерфейсы вещь интересная. Множественное наследование этап будущего развития. Но хочу заложить сейчас что-бы не править потом.

У интерфейсов есть недостаток. Они не работают с полями и методами класса.
И второй это всё же наследование, а как-то спрашивал про мутацию.

"class of" -  надо подумать, но выглядит как-то сложно.


 
Юрий Зотов ©   (2014-11-02 12:46) [9]

1. Определяем нужные интерфейсы.
2. Вводим регистрацию классов.

Какой класс зарегистрирован в качестве реализатора интерфейса - тот и будет работать.


 
DVM ©   (2014-11-03 23:42) [10]


> Pavia ©   (02.11.14 08:40) [8]

Так у тебя тот фреймворк еще не написан что ли? Тогда интерфейсы помогут. В дополнение к интерфейсам надо как то реализовать внедрение зависимостей https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8


 
Pavia ©   (2014-11-05 15:50) [11]

Кажется понял. Создаем интерфейс для создания объекта. Реализуем класс по умолчанию с этим интерфейсом.
А потом если хотим подменить то меняем класс по умолчанию на новый.

Плюс понадобиться ещё интерфейс или два интерфейса на связывание. Который используют в классах выше и ниже иерархии.
А если хотим поменять интерфейсы то надо будет заменить классы выше и ниже по иерархии на свои.

Надо картинку нарисовать для наглядности.

Как по вашему новички смогут работать с таким фреймворком? Не сильно сложный и запутанный получается?


 
jack128 ©   (2014-11-05 16:00) [12]


> В дополнение к интерфейсам надо как то реализовать внедрение
> зависимостей

Все уже написано до нас. spring4d


 
Pavia ©   (2014-11-05 16:22) [13]

spring4d - я смотрел его так и не понял что это такое?


 
DVM ©   (2014-11-05 17:30) [14]


> Pavia ©   (05.11.14 16:22) [13]
> spring4d - я смотрел его так и не понял что это такое?

А это и есть библиотека для внедрения зависимостей (DI) для Delphi. Аналог NInject, Unity DI и прочих.

Суть в чем. Допустим у тебя есть класс и он должен использовать другой класс. Мы берем и делаем интерфейс для этого другого класса и передаем его например в конструктор. Например так:

TMyClass = class
public
 constructor Create(ALogger: ILogger);
end;

Теперь наш класс может использовать любые другие реализации ILogger. Но ему надо как то сообщить какую реализацию использовать. Для этого в DI библиотеках производится привязка интерфейса к реализации. Делается обычно глобально. Далее, при создании экземпляра нашего класса TMyClass, мы ему в конструктор передадим уже не экземпляр класса, а DI контейнер который создаст нужный экземпляр в соответствии с привязками.


 
картман ©   (2014-11-05 19:52) [15]

т.е. если мы нажили себе геморрой кривым проектированием, spring4d позволяет нажить еще больший?


 
DVM ©   (2014-11-05 21:47) [16]


> картман ©   (05.11.14 19:52) [15]


> т.е. если мы нажили себе геморрой кривым проектированием

Вряд ли. О внедрении зависимостей надо думать изначально. Удобная штука между прочим. Особенно удобно для тестирования.


 
картман ©   (2014-11-05 22:13) [17]


> DVM ©   (05.11.14 21:47) [16]
>
> О внедрении зависимостей надо думать изначально.
>

тогда что мешает классам просто наследовать потребный интерфейс?


 
DVM ©   (2014-11-05 22:28) [18]


> картман ©   (05.11.14 22:13) [17]

Ничто не мешает.
Ты не понял сути DI. Представь себе большой проект, все связи в нем выполнены через интерфейсы, все ок. Но, где то же в проекте должны создаваться экземпляры реализаций интерфейсов. А вот это уже узкое место. В этом месте мы связываем то, что с помощью интерфейсов пытались развязать. И как правило такие места разбросаны по коду. Весь код оказывается жестко связан.

Если мы захотим заменить одну реализацию на другую, то нам придется везде по коду исправлять те места где создается реализация интерфейса.

DI позволят решить данную проблему. Методы есть разные.


 
картман ©   (2014-11-05 22:49) [19]


> Ты не понял сути

теперь понял(каюсь, давно знал, да как-то из головы вылетело): круче использовать тонну библиотек, чем написать десяток строчек кода))


 
DVM ©   (2014-11-05 23:02) [20]


> картман ©   (05.11.14 22:49) [19]


>  круче использовать тонну библиотек, чем написать десяток
> строчек кода))

Да зачем тонну библиотек? Вовсе необязательно. DI один из видов реализации важного принципа ООП - Инверсия управления, а также широко распространенный паттерн. Его часто используют. Вот, например, в [14] типичный пример этого:


TMyClass = class
public
constructor Create(ALogger: ILogger);
end;


Библиотеки же просто шагают чуть дальше, позволяя автоматизировать создание экземпляров реализаций. В любой момент от этого можно отказаться.


 
Юрий Зотов ©   (2014-11-05 23:18) [21]

>DVM ©   (05.11.14 22:28) [18]

> Если мы захотим заменить одну реализацию на другую, то нам придется
> везде по коду исправлять те места где создается реализация интерфейса.

При плохой структурированности кода - да. При хорошей - нет. Все можно сосредоточить в одном месте. Например, так.

1. Объявления всех интерфейсов помещаем в один юнит.

2. В разделе implementation этого юнита объявляем список пар "интерфейс - реализующий_класс".

3. Заполняем этот список в разделе initialization того же юнита.

4. Очищаем этот список в разделе finalization того же юнита.

5. В том же юните пишем доступную снаружи функцию, на входе которой - интерфейс, а на выходе - реализующий класс (или его экземпляр, если так удобнее).

==============

Теперь, чтобы получить реализатор интерфейса, в любом месте кода просто дергаем эту функцию и передаем ей искомый интерфейс. Она находит в списке и возвращает класс (или экземпляр класса), реализующий этот интерфейс. А замена любого реализатора сводится к правке одной строки в заведомо известном месте (раздел initialization все того же юнита).


 
DVM ©   (2014-11-05 23:30) [22]


> Юрий Зотов ©   (05.11.14 23:18) [21]


> 1. Объявления всех интерфейсов помещаем в один юнит.

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


> 2. В разделе implementation этого юнита объявляем список
> пар "интерфейс - реализующий_класс".
>
> 3. Заполняем этот список в разделе initialization того же
> юнита.
>
> 4. Очищаем этот список в разделе finalization того же юнита.
>
>
> 5. В том же юните пишем доступную снаружи функцию, на входе
> которой - интерфейс, а на выходе - реализующий класс (или
> его экземпляр, если так удобнее).

Собственно вот и получился свой собственный DI контейнер и без всяких библиотек.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.046 c
1-1332249209
Димка На
2012-03-20 17:13
2015.09.10
Вертикальный TBitmap.ScanLine


15-1412627403
Юрий
2014-10-07 00:30
2015.09.10
С днем рождения ! 7 октября 2014 вторник


15-1422271890
alexdn
2015-01-26 14:31
2015.09.10
Требуется модератор


8-1236500354
deswan
2009-03-08 11:19
2015.09.10
Graphics32 - навигация по изображению


2-1396356964
Дмитрий
2014-04-01 16:56
2015.09.10
0,1 is not a valid BCD value





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский