Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Интерфейсы, доступ к родителю / 7 сообщений из 7, страница 1 из 1
10.08.2021, 09:20
    #40089782
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
Есть интерфейс:

Код: pascal
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.
unit interfaces;

interface

uses
  system.sysutils;

Type

  ISettings = interface
    [ '{13A6C331-7527-400D-901F-181F517B55BE}' ]
    procedure Load;
  end;

  IDataProcessor = interface
    [ '{D5FB3346-1713-4B4E-8A82-DB48596852CE}' ]
    procedure Apply;
  end;

  ICommunicator = interface
    [ '{E5B7933B-53F3-49D7-AD64-ACEABE274357}' ]
    function GetDataProcessor: IDataProcessor;
    procedure SetDataProcessor( const d: IDataProcessor );
    property DataProcessor: IDataProcessor
      read GetDataProcessor
      write SetDataProcessor;

    procedure Login;
    procedure Export;

    function GetSettings: ISettings;
    procedure SetSettings( s: ISettings );
    property Settings: ISettings
      read GetSettings write SetSettings;
  end;

implementation

end.



Его реализация:

Код: pascal
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.
unit implementations;

interface

uses
  System.sysutils,
  interfaces;

Type
  TSettings = class( TInterfacedObject, ISettings )
  public
    constructor Create;
    destructor Destroy; override;
    procedure Load;
  end;

  TDataProcessor = class( TInterfacedObject, IDataProcessor)
  public
    procedure Apply;
  end;

  TCommunicator = class( TInterfacedObject, ICommunicator )
  private
    fDataProcessor: IDataProcessor;
    fSettings: ISettings;
    function GetDataProcessor: IDataProcessor;
    procedure SetDataProcessor( const d: IDataProcessor );
  public
    constructor Create;
    destructor Destroy; override;

    procedure Login;
    procedure Export;

    property DataProcessor:IDataProcessor
      read GetDataProcessor
      write SetDataProcessor;

    function GetSettings: ISettings;
    procedure SetSettings( s: ISettings );
    property Settings: ISettings
      write SetSettings;
  end;

implementation

{ TCommunicator }
constructor TCommunicator.Create();
begin
  inherited
  //
end;

destructor TCommunicator.Destroy;
begin
  //
  inherited;
end;

function TCommunicator.GetDataProcessor: IDataProcessor;
begin
  Result := FDataProcessor;
end;

function TCommunicator.GetSettings: ISettings;
begin
  Result := FSettings;
end;

procedure TCommunicator.Login;
begin
  //
end;

procedure TCommunicator.Export;
begin
  FDataProcessor.Apply;
end;

procedure TCommunicator.SetDataProcessor(const d: IDataProcessor);
begin
  fDataProcessor := d;
end;

procedure TCommunicator.SetSettings(s: ISettings);
begin
  fSettings := s;
end;

{ TSettings }
constructor TSettings.Create;
begin
   inherited;
   //
end;

destructor TSettings.Destroy;
begin
  //
  inherited;
end;

procedure TSettings.Load;
begin
  //
end;

{ TDataProcessor }
procedure TDataProcessor.Apply;
begin
  //
end;

end.



Реrистрация Springs4D:

Код: pascal
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.
unit registrations;

interface

uses
  spring,
  spring.container;

procedure Registering( container: TContainer );

implementation

uses
  interfaces,
  implementations,
  spring.container.Common;

procedure Registering( container: TContainer );
begin
  container.RegisterType< ISettings, TSettings>;
  container.RegisterType< ICommunicator, TCommunicator>;
  container.RegisterType< IDataProcessor, TDataProcessor>;
  container.Build;
end;

end.



В отдельной форме такой код:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
....
uses
  Spring.Container,
  interfaces,
  implementations,
  registrations;

procedure TForm1.Button1Click(Sender: TObject);
var
  MySetings: ISettings;
  MyCommunicator: ICommunicator;
begin
  Registering( globalContainer );

  MySetings := GlobalContainer.Resolve< ISettings>;
  MySetings.Load;
  MyCommunicator := GlobalContainer.Resolve<ICommunicator>;
  MyCommunicator.Settings := MySetings;
  MyCommunicator.Login;
  MyCommunicator.DataProcessor := GlobalContainer.Resolve<IDataProcessor>;
  MyCommunicator.Export;
end;



Получается у объекта TCommunicator есть свойства FDataProcessor и FSettings (или методы).
Вопрос:
Как мне в методе ...
Код: pascal
1.
2.
3.
4.
procedure TDataProcessor.Apply;
begin
  //
end;


... получить доступ на уровень выше? То есть например, из FDataProcessor получить его родителя TCommunicator и прочитать его свойства, например. Или свойства его же свойства/метода FSettings?
Большое спасибо.
...
Рейтинг: 0 / 0
10.08.2021, 09:47
    #40089785
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
bzums

Получается у объекта TCommunicator есть свойства FDataProcessor и FSettings (или методы).
Вопрос:
Как мне в методе ...
Код: pascal
1.
2.
3.
4.
procedure TDataProcessor.Apply;
begin
  //
end;


... получить доступ на уровень выше?



Код: pascal
1.
2.
3.
4.
procedure TDataProcessor.Apply(ACommunicator: ICommunicator);
begin
  //
end;


или же
Код: pascal
1.
2.
3.
4.
5.
IDataProcessor = interface
    [ '{D5FB3346-1713-4B4E-8A82-DB48596852CE}' ]
    procedure Apply;
    function GetCommunicator: ICommunicator;
  end;
...
Рейтинг: 0 / 0
10.08.2021, 10:19
    #40089800
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
При создании или присвоении dataprocessor присваивай поле Owner. Через него выходи на communicator. Settings можно отдельно присваивать, чтобы снизить или вовсе убрать взаимную зависимость.
...
Рейтинг: 0 / 0
10.08.2021, 10:51
    #40089806
bzums
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
Параметр получается единственный вариант.
Это описание просит, чтобы обьект ICommunicator был описан выше:
Код: pascal
1.
2.
3.
4.
5.
IDataProcessor = interface
    [ '{D5FB3346-1713-4B4E-8A82-DB48596852CE}' ]
    procedure Apply;
    function GetCommunicator: ICommunicator;
  end;


Если я их поменяю местами, то здесь есть IDataProcessor, который тоже не находится (должен быть выше):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  ICommunicator = interface
    [ '{E5B7933B-53F3-49D7-AD64-ACEABE274357}' ]
    function GetDataProcessor: IDataProcessor;
    procedure SetDataProcessor( const d: IDataProcessor );
    property DataProcessor: IDataProcessor
      read GetDataProcessor
      write SetDataProcessor;

    procedure Login;
    procedure Export;

    function GetSettings: ISettings;
    procedure SetSettings( s: ISettings );
    property Settings: ISettings
      read GetSettings write SetSettings;
  end;


Замкнутый круг.
Спасибо.

Вся эта тема была поднята для того, чтобы была возможность одну настройку обьекта IDataProcessor ( потому что это по смыслу настройка и есть) вынести в ISettings. Но образаться туда из IDataProcessor. Это даже не родитель, получается. У обоих, IDataProcessor и IDataProcessor, родителем является ICommunicator.
Спасибо большое.
...
Рейтинг: 0 / 0
10.08.2021, 11:09
    #40089811
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
offtopic:

У интерфейсов методы вида
Код: pascal
1.
function DoSomething: ISomething;


являются плохой идеей по той причине, что в будущем, когда у вас появится V2, весь ваш код будет выглядеть так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
var
  Dummy: ISomethingV1; // сегодняшний ISomething
  Something: ISomething; // будущий ISomethingV2
begin
  Dummy := I.DoSomething;
  Dummy.QueryInterface(ISomething, Something);
  Something.DoSomethingElse;
end;



Вместо этого гораздо лучше делать так:
Код: pascal
1.
procedure DoSomething(const IID: TGUID; out Obj);


тогда вызывающий код будет:
Код: pascal
1.
2.
3.
4.
5.
6.
var
  Something: ISomething; // любой ISomething (ISomethingV1, ISomethingV2, ...)
begin
  I.QueryInterface(ISomething, Something);
  Something.DoSomethingElse;
end;


для любого типа ISomething - и сегодняшнего, и будущего.
...
Рейтинг: 0 / 0
10.08.2021, 11:40
    #40089821
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
bzums

Замкнутый круг.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
type
ICommunicator = interface;

IDataProcessor = interface
    [ '{D5FB3346-1713-4B4E-8A82-DB48596852CE}' ]
    procedure Apply;
    function GetCommunicator: ICommunicator;
end;

ICommunicator = interface
    [ '{E5B7933B-53F3-49D7-AD64-ACEABE274357}' ]
    function GetDataProcessor: IDataProcessor;
    procedure SetDataProcessor( const d: IDataProcessor );
    property DataProcessor: IDataProcessor read GetDataProcessor write SetDataProcessor;
end;
...
Рейтинг: 0 / 0
12.08.2021, 19:29
    #40090402
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Интерфейсы, доступ к родителю
GunSmoker
для любого типа ISomething - и сегодняшнего, и будущего.
Угу. Только хрен такое опишешь в idl. Вернее описать то можно как
Код: plaintext
1.
[out] void ** Obj

но потом нужно будет после каждого импорта править _TLB файл с
Код: pascal
1.
out Obj: Pointer

на
Код: pascal
1.
out Obj
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Интерфейсы, доступ к родителю / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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