Welcome Guest Search | Active Topics | Members | Log In

Wirtualne pointery - identyfikacja wirtualnego obiektu docelowego Options · View
habela
Posted: Wednesday, April 06, 2005 8:24:29 PM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
Jeszcze jeden problem dotyczący wirtualnych pointerów. Wyszło po przymiarkach to uwzględnienia dynamicznych ról w perspektywach.
Otóż w poprzednich dyskusjach zgodziliśmy się, że definicja obiektu docelowego takiego pointera powinna być na zewnątrz perspektywy definiującej wskaźnik. Oznacza to, że w perspektywie pointera, definicja on_retrieve albo point_to mogłaby zawierać odniesienie do innej, zdefiniowanej na zewnątrz perspektywy.
Ale jeśli jesteśmy na zewnątrz tej "docelowej" perspektywy, to mamy do dyspozycji tylko te własności, którymi dysponuje programista-klient definicji owej perspektywy. Czy to nam wystarczy, aby skojarzyć odpowiednie obiekty wirtualne ze sobą?
Zastanawiam się nad następującym przykładem. Mamy źródłowe (konkretne) dane zaprojektowane w stylu relacyjnym.

Code:
class Firma{
idFirmy : integer;
nazwaFirmy : string; // nieunikalna
miasto : string; // nieunikalne itd.
}
class Pracownik {
idFirmy : integer;
idPracownika : integer;
nazwisko : string;
imie : string; // itd.
}


Chcielibyśmy za pomocą perspektyw otrzymać dane oparte na następujących interfejsach:
Code:
export Company{
  name : string retrieve;
  employs[0..*] : ref Employee inverse worksIn;
};
export Employee{
  lastName : string retrieve;
  firstName : string retrieve;
  worksIn : ref Company inverse employs update;
};


Chcemy zrealizować to przez dwie perspektywy - company i employee. Pytanie jest, co napisać w definicjach podperspektyw worksIn i employs, skoro obiektami idFirmy operujemy tylko wewnątrz obu perspektyw (w sacks)?
Oczywiście pożądane jest, aby wzorem konkretnych danych można było zadać zapytanie np. "pracownicy zatrudnieni w tej samej firmie co Jan Iksiński".

Odniosłem wrażenie, że tutaj niezbędne byłyby perspektywy parametryzowane (swoją drogą zapewne takie wprowadzimy). Ale z kolei szkoda byłoby komplikować interfejs konsumentowi tych dwóch perspektyw, skoro te parametry są potrzebne tylko celem "przerzucenia mostów" pomiędzy definicjami seed-ów w obu perspektywach.
Stąd pomysł na twór który mógłby się nazywać referrer albo selector. Stanowiłby on alternatywą definicję sack-u i służyłby wyłącznie dostępowi do wirtualnych obiektów "od kuchni", tj. przez nawigację z innych obiektów wirtualnych, potencjalnie w oparciu o dane zawarte w ziarnach tychże.
Mogłoby to wyglądać następująco (dla ułatwienia stosuję tradycyjną składnię dla sack). Oprócz (lub zamiast normalnej definicji sack-u):

Code:
... virtual objects company {firma as f} ...


mielibyśmy:

Code:
... virtual objects company {firma as f},
        referrer Company(id : integer) {(firma where idFirmy=id) as f} ...


Proszę o komentarze - może jednak da się bez tego rozszerzenia?
radamus
Posted: Wednesday, April 13, 2005 10:10:10 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Spojrzałeś na sprawę z trochę innej strony. My zakładaliśmy, że wirtualny pointer prowadzi do obiektu (rzeczywistego lub wirtualnego) i może być definiowany z wykorzystaniem tylko schematu, nazwijmy go "globalnego". Programista nie wie i nie musi wiedzieć czy ma do czynienia z obiektem wirtualnym czy rzeczywistym (przezroczystość). W tym momencie definiuje obiekt pointerowy. Jego definicja jest niezależna od definicji obiektu docelowego.

Ty założyłeś, że programista definiujący wirtualny pointer wie, że będzie on prowadził do wirtualnego obiektu i co więcej, zna definicje tej perspektywy (czyli implementacje). Czyli innymi słowy wie, jak elementy ze schematu, nazwijmy go "kontrybuyjnego", tworzą definicję wirtualnego obiektu. Dlatego proponujesz aby dać wejście od kuchni i pozwolić mu tę wiedzę wykorzystać. Fajnie, ale nie wiem czy nie jest to złamanie zasady hermetyzacji. Przypomina mi to trochę funkcje zaprzyjaźnione z C++. Bezpośredni dostęp do seed'a nie wydaje mi się najlepszym rozwiązaniem.

Proponuje inne rozwiązanie tego problemu.
Klasy jeszcze raz:
Code:
class Firma{
idFirmy : integer;
nazwaFirmy : string; // nieunikalna
miasto : string; // nieunikalne itd.
}
class Pracownik {
idFirmy : integer;
idPracownika : integer;
nazwisko : string;
imie : string; // itd.
}


Interfejsy:

Code:
export Company{ virtual objects {Firma as f;}
  name : string retrieve;
  employs[0..*] : ref Employee inverse worksIn; {  }
};
export Employee{ virtual objects {Pracownik as p;}
  lastName : string retrieve;
  firstName : string retrieve;
  worksIn : ref Company inverse employs; virtual objects { (Firma where id == p.id) as fr; }
{
    on_navigate {return (Company)fr;}
   
}

  };



Proponuję operator rzutowania/konwersji.

Code:
q1 convert to|cast to nazwa_interfejsu
lub po prostu
Code:
(nazwa_interfejsu)q1


Operator zamienia jeden interfejs na drugi.
Semantyka (dla przypadku, gdy konwertujemy na interfejs zdefiniowany przez perspektywę):

wynikiem q1 jest bag identyfikatorów. operator wrzuca na ENVS bindery nazwa_obiektu(id). Tyle, że w przeciwieństwie do operatorów nie algebraicznych nie iteruje po wyniku q1 tylko wrzuca jednorazowo wysztkie bindery. Względem tego nowego stanu stosu ewaluowana jest procedura virtual objects z definicji interfejsu. Wynikiem jest bag identyfikatorow wirtualnych.
Dla naszego przykładu:

Code:
worksIn : ref Company inverse employs update; virtual objects { (Firma where id == p.id) as fr; }
on_navigate { return (Company)fr; }


Programista tworzy wirtualny pointer z wykorzystaniem znajomości "schematu kontrybucyjnego". Ponieważ w interfejsie zadekarowano, że zwrócony zostanie identyfikator obiektu Company (wirtualny) a nie Firma (rzeczywisty) więc dokonuje on wymaganej konwersji (w tym wypadku mogłaby ona być automatyczna).

Czyli mamy sytuację w której, tak jak chciałeś programista, może wykorzystać wiedzę o obiekcie oryginalnym jednak, tak jak my postulowaliśmy definicja obiektu wskazywanego jest zewnętrzna. To co robi programista definiujący wirtualny pointer to dostarcza obiekty, na których działać będzie procedura virtual objects (czyli paramertyzuje).

Oczywiście semantyka nie jest ograniczona do perspektyw. Może to być również konwersja z jednej roli do drugiej. np wszyscy pracownicy, którzy są jednocześnie studentami, przy założeniu, że mamy obiekt Person z opcjonalnymi rolami Student i Emp.
Code:
(Emp)Student

To jest przypadek opisany w pracy Andrzeja Jodłowskiego.

Zostaje problem aktualizacji, bo musilibyśmy założyć, że można dokonać konwersji w drugą stronę.
Code:
on_update(newCompany) { p.idFirmy = ((Firma)newCompany).id; }


Tylko semantyki tego przekształcenia nie jestem sobie jeszcze w stanie wyobrazić.
habela
Posted: Wednesday, April 13, 2005 3:48:49 PM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
radamus wrote:
Ty założyłeś, że programista definiujący wirtualny pointer wie, że będzie on prowadził do wirtualnego obiektu i co więcej, zna definicje tej perspektywy (czyli implementacje). Czyli innymi słowy wie, jak elementy ze schematu, nazwijmy go "kontrybuyjnego", tworzą definicję wirtualnego obiektu. Dlatego proponujesz aby dać wejście od kuchni i pozwolić mu tę wiedzę wykorzystać. Fajnie, ale nie wiem czy nie jest to złamanie zasady hermetyzacji. Przypomina mi to trochę funkcje zaprzyjaźnione z C++. Bezpośredni dostęp do seed'a nie wydaje mi się najlepszym rozwiązaniem.

Nie ze wszystkimi wnioskami tutaj się zgadzam:
1. Owszem, zakładam, że programista definiujący perspektywę powinien mieć możliwość (ale nie musi) odejścia od pełnej przezroczystości.
2. Tu się nie zgadzam: nie musi znać definicji tej perspektywy. Po prostu musi zostać dopuszczony do odrobinkę szerszego interfejsu, co w tym wypadku oznacza przekazanie parametru (lub parametrów), który programista perspektywy "przeciwległej" zadeklarował jako oczekiwane w wypadku definiowania doń wirtualnych wskaźników.
3. Z powiższego względu nie nazwałbym tego bezpośrednim dostępem do seed-a.
4. Złamanie hermetyzacji to może trochę zbyt mocno powiedziane, z dwóch względów:
- można przyjąć, że poza definicjami perspektywy (czyli dla zwykłych programistów) te dodatkowe klauzule nie będą dostępne (tzn. nie będą uwzględnione w interfejsie view).
- w sytuacji, gdy jest dostępne, owo rozluźnienie hermetyzacji nie stanowi niczego więcej jak dostarczenie dodatkowego kryterium selekcji w bagu zwracanym przez daną perspektywę.
5. Po pierwszym przeczytaniu posta odniosłem wrażenie, że Twoja propozycja zaatakowania tematu jest zbliżona w sensie ingerencji jaką powoduje. U mnie furtka polega na przekazaniu do view parametru, zaś u Ciebie - na "wsunięciu" pod ewaluację sacku określonej sekcji na stos środowisk.

radamus wrote:
export Company{ virtual objects {Firma as f;}
name : string retrieve;
employs[0..*] : ref Employee inverse worksIn; { }
};
export Employee{ virtual objects {Pracownik as p;}
lastName : string retrieve;
firstName : string retrieve;
worksIn : ref Company inverse employs; virtual objects { (Firma where id == p.id) as fr; }
{
on_navigate {return (Company)fr;}

}

};

Czy to literówka, czy rozróżnienie Firma as f oraz (Firma where id == p.id) as fr jest zamierzone?
Czy w obu miejscach powinna być ta sama nazwa?

Nie wiem, czy dobrze zrozumiałem pomysł, ale nie widzę wielkiej przepaści koncepcyjnej pomiędzy tymi dwoma rozwiązaniami.
Trudno mi w tej chwili powiedzieć, jak oba warianty sprawdzą się przy mniej trywialnych definicjach ziaren (choć wersja z parmetrem wydaje mi się w tej chwili trochę mniej zwięzła ale odporjniejsza na takie sytuacje szczególne).

Co do ról, to jak wspomniałem, dyskutowany tu problem wypłynął właśnie przy tworzeniu tego tekstu (w załączeniu szkic artykułu - zamieszczę wieczorem). Tam wyszło na to, że musi być odwzorowanie w dwie strony.

File Attachment(s):
paper_StaticAndDynamicInhVirtual.doc (291kb) downloaded 34 time(s).


KK
Posted: Wednesday, April 13, 2005 4:12:56 PM
Rank: Advanced Member

Joined: 12/7/2004
Posts: 226
Points: 30
radamus wrote:

Code:
class Firma{
idFirmy : integer;
nazwaFirmy : string; // nieunikalna
miasto : string; // nieunikalne itd.
}
class Pracownik {
idFirmy : integer;
idPracownika : integer;
nazwisko : string;
imie : string; // itd.
}

Interfejsy:
Code:
export Company{ virtual objects {Firma as f;}
  name : string retrieve;
  employs[0..*] : ref Employee inverse worksIn; {  }
};
export Employee{ virtual objects {Pracownik as p;}
  lastName : string retrieve;
  firstName : string retrieve;
  worksIn : ref Company inverse employs; virtual objects { (Firma where id == p.id) as fr; }
{
    on_navigate {return (Company)fr;}
   
}
  };


Gdy pisałeś "(Firma where id==p.id) as Fr" to chodziło Ci o: "(Firma where id==p.idFirmy) as Fr"
radamus
Posted: Wednesday, April 13, 2005 10:11:06 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
KK wrote:
Gdy pisałeś "(Firma where id==p.id) as Fr" to chodziło Ci o: "(Firma where id==p.idFirmy) as Fr"

Tak, oczywiście, przepraszam.

Habela wrote:

radamus wrote:

export Company{ virtual objects {Firma as f;}
name : string retrieve;
employs[0..*] : ref Employee inverse worksIn; { }
};
export Employee{ virtual objects {Pracownik as p;}
lastName : string retrieve;
firstName : string retrieve;
worksIn : ref Company inverse employs; virtual objects { (Firma where id == p.idFirmy) as fr; }
{
on_navigate {return (Company)fr;}

}

};

Czy to literówka, czy rozróżnienie Firma as f oraz (Firma where id == p.id) as fr jest zamierzone?
Czy w obu miejscach powinna być ta sama nazwa?


Nie musi być ta sama nazwa. To są dwie zupełnie niezależne definicje. Pierwsza definiuje wirtualne obiekty Company, druga wirtualny pointer. Wynikiem są dwa różne seed'y. Nie widzę (na razie) żadnego powodu, dla którego nazwy miałyby być takie same. W przypadku wirtualnego pointera dopiero definicja on_navigate powoduje utworzenie wirtualnych identyfikatorów Company.


Czekam na szkic artykułu o rolach ...
stencel
Posted: Thursday, April 14, 2005 12:28:01 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Znacznie bardziej podoba mi sie propozycja Radka.

Wydaje mi sie, ze problem, ktory Piotrze zidentyfikowales, wyklada sie tak:

Na zewnatrz perspektywy mamy dany seed, a chcemy miec odpowiedni obiekt wirtualny. Jak go odwzorowac?

No i rozwiazanie bylo dyskutowane na poczatku watku:

http://iolab.pjwstk.edu.pl:8081/forum/Default.aspx?g=posts&t=41

Tam byl problem taki, ze oto uzytkownik ma oid materialnego obiektu, na ktorym jest overloading view. No i trzeba ten oid zamienic na identyfikator wirtualny tej overloading view. Robi sie to w ten sposob, ze sie ten oid wklada sie na stos i zapyla sie virtual objects tej perspektywy. Cos takiego trzeba i tu zrobic. A moze dedykowana procedura?
habela
Posted: Thursday, April 14, 2005 9:15:33 AM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
Quote:
Nie musi być ta sama nazwa. To są dwie zupełnie niezależne definicje. Pierwsza definiuje wirtualne obiekty Company, druga wirtualny pointer. Wynikiem są dwa różne seed'y. Nie widzę (na razie) żadnego powodu, dla którego nazwy miałyby być takie same. W przypadku wirtualnego pointera dopiero definicja on_navigate powoduje utworzenie wirtualnych identyfikatorów Company.

Racja. Pisałem w pośpiechu i tutaj namieszałem. Myślałem nie tyle o:
virtual objects { (Firma where id == p.idFirmy) as fr;
no bo to rzeczywiście wskaźnik, ale o czymś takim:
on_navigate {return ((Company)fr) as f;}
Myślałem bowiem, że w Twojej propozycji po prostu obecność określonego bindera w lokalnym środowisku poinformuje perspektywę, aby nie odpalać virtual_objects, ale by pracować na tym, co już jest.
Ale przecież piszesz, że:
radamus wrote:
Względem tego nowego stanu stosu ewaluowana jest procedura virtual objects z definicji interfejsu. Wynikiem jest bag identyfikatorow wirtualnych.

W takim razie, skoro virtual_objects który podałeś wygląda następująco:
Code:
virtual objects {Firma as f;}

to czy on_navigate nie powinno raczej zawierać:
Code:
on_navigate {return (Firma)fr;}

albo wręcz:
Code:
on_navigate {return fr as Firma;}

nie zaś:
Code:
on_navigate {return (Company)fr;}

?
Bo niestety z opisu nie zrozumiałem, co ma zostać "podrzucone" przed ewaluacją docelowej perspektywy i w jaki sposób virtual_objects to zwiąże.

stencel wrote:
Wydaje mi sie, ze problem, ktory Piotrze zidentyfikowales, wyklada sie tak:

Na zewnatrz perspektywy mamy dany seed, a chcemy miec odpowiedni obiekt wirtualny. Jak go odwzorowac?

Tak jest, przy czym dodam do tego ważne moim zdaniem uszczegółowienie:
Obiekt wirtualny, który chcemy uzyskać w oparciu o ten seed, powinien stanowić podzbiór obiektów wirtualnych zwracanych przez docelową perspektywę.
Sądzę, że założenie to z punktu widzenia spójności jest na tyle dobrze uzasadnione, że można je uwzględnić projektując mechanizm.

Dodam, że propozycja Radka mnie też wydaje się bardziej estetyczna, ale na razie odnoszę się doń z rezerwą, bo:
- nie do końca zrozumiałem mechanizm - jakby brakowało tu nieco kodu...
- jak już zrozumiem - będę chciał zweryfikować pomysł (jego uniwersalność) na bardziej złożonym z punktu widzenia budowy ziarna scenariuszu.

stencel wrote:
Cos takiego trzeba i tu zrobic. A moze dedykowana procedura?

No więc właśnie - wydaje mi się, że coś takiego może okazać się niezbędne.
radamus
Posted: Thursday, April 14, 2005 9:30:44 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Piotr tak na prawdę pokazuje, że potrzebna jest parametryzacja perspektyw, która mnie osobiście kojarzy się z mechanizmem konstruktorów i możliwością ich przeciążania (skojarzenie jest oczywiście luźne). Procedura virtual objects definiuje sposób konstrukcji wirtualnych obiektów .

Code:
view CompanyDef {
virtual objects Company {return Firma as f;}
}

Różne sposoby tworzenia obiektów wirtualnych mogłyby być definiowane jako osobne procedury virtual objects.
Code:
view CompanyDef {
virtual objects Company {return Firma as f;}
virtual objects Company(idFirma:integer) {return Firma where id == idFirma as f;}
virtual objects Company(nFirma:string) {return Firma where nazwa == nFirma as f; }
}


Każda z tych procedur zwraca wirtualne identyfikatory obiektów Company, tyle, że w różnej liczbie. Ale to definiujący perspektywę musi zdefiniować możliwe sposoby tworzenia wirtualnych obiektów.

Moja propozycja jest pozwala na zewnetrzne okreslenie puli obiektów źródłowych, które będą wiązane w definicji pespektywy. Ale, wymaga od piszącego wiedzy o konstrukcji perspektywy (na podstawie jakich obiektów są tworzone wirtualne obiekty i jaki jest schemat źródłowych obiektów). Za to może on utworzyc obiekty wirtualne na podstawie zapytania, którego nie przewidział definiujacy perspektywę (oczywiście przy zachowaniu zgodności typologicznej).
Np.

Code:
(Company)(Firma where id == (Pracownik where name == "Poe").idFirmy);

Jest równoważne:
Code:
Company((Pracownik where name == "Poe").idFirmy);


Na poziomie semantyki różnica jest tylko w mechanizmie transportu parametrów. Przy operatorze rzutowania parametry są wyznaczane przez stan stosu, który zastanie domyślna procedura virtual objects. W drugim przypadku jest to parametr procedury.

Jeżeli, tak jak napisał Piotr przezroczystość jest cechą, którą można wykorzystać ale nie trzeba to wydaje mi się, że jedno i drugioe rozwiązanie może mieć uzasadnienie w konkretnych sytuacjach biznesowych. Parametryzacja jest mechanizmem, gdzie programista jawnie określa warunki utworzenia obiektów wirtualnych, natomiast mechanizm rzutowania możę być wykorzsytan w sytuacjach, gdy programista otrzymuje obiekty jednego typu (np. jako parametr procedury) i musi, je z jakichś powodów przekształcic na inny.





radamus
Posted: Thursday, April 14, 2005 9:54:07 AM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
habela wrote:

Ale przecież piszesz, że:
radamus wrote:
Względem tego nowego stanu stosu ewaluowana jest procedura virtual objects z definicji interfejsu. Wynikiem jest bag identyfikatorow wirtualnych.

W takim razie, skoro virtual_objects który podałeś wygląda następująco:
Code:
virtual objects {Firma as f;}

to czy on_navigate nie powinno raczej zawierać:
Code:
on_navigate {return (Firma)fr;}

albo wręcz:
Code:
on_navigate {return fr as Firma;}

nie zaś:
Code:
on_navigate {return (Company)fr;}

?
Bo niestety z opisu nie zrozumiałem, co ma zostać "podrzucone" przed ewaluacją docelowej perspektywy i w jaki sposób virtual_objects to zwiąże.



Ok. To jeszcze raz bo faktycznie wydaje mi się, że nie zrozumiałeś.

Definicja Company

Code:
export Company{    virtual objects { Firma as f; }

...
};


virtual objects ustala ziarna obiektów wirtualnych company nazwane f. Ale f jest lokalną nazwą dla procedur aktualizacyjnych oraz podperspektyw zdefiniowanych w Company.

Definicja Employee z naszym wirtualnym pointerem.

Code:
export Employee{ virtual objects {Pracownik as p;}
...
worksIn : ref Company inverse employs; virtual objects { (Firma where id == p.id) as fr; }
{
    on_navigate {return (Company)fr;}
   
}
  };


Tym razem procedura virtual objects ustala ziarna wirtualnego pointera worksIn. Fr jest lokalną nazwą ziaren wirtualnego pointera.
Procedura on_navigate jest zdefiniowana poprzez zapytanie:
Code:
(Company)fr;

Podzapytanie fr zwróci identyfikator firmy, w której pracuje nasz employee. Zgodnie z proponowaną przeze mnie semantyka na czubek stosu wrzucamy nested(id_naszego_employee) czyli otrzymamy:

________________________
Firma(id_naszego_employee)
________________________
poprzedni stan stosu
________________________

Następnie względem tego stanu ewaluowana jest procedura virtual objects perspektywy Company, która ma postać:

Code:
Firma as f;


Wynik: jedno ziarno wirtualnego obiektu Company utowrzonego na podstawie identyfikatora firmy naszego employee.

habela
Posted: Friday, April 15, 2005 11:24:16 AM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
Dzięki - teraz wszysko jasne.
Istotnie, to rozwiązanie jest zgrabniejsze składniowo, a przy tym chyba nie ogranicza mocy perspektywy (tzn. niezależnie jak złożone byłoby ziarno, zawsze można odpowiednie środowisko podstawić do jego ewaluacji).

Pozostają natomiast wątpliwości w następujących aspektach:
1. w jak dużym stopniu tak przeciążony operator rzutowania miesza nam w semantyce języka?
2. czy nie będzie powodował luki w systemie ograniczania dostępu w oparciu o zadeklarowane interfejsy?
3. (nie ulega wątpliwości, że możliwość takiego "podłożenia" srodowiska pod ewaluację perspektywy stanowi znacznie poważniejsze jej rozhermetyzowanie, niż proponowane parametry.)
4. zakładam, że ta dowolność, jak to określiłeś "utworzenia obiektów wirtualnych na podstawie zapytania, którego nie przewidział definiujacy perspektywę" pozwala na skonstruowanie obiektów wirtualnych które oryginalnie nie wchodziły w skład obiektów serwowanych przez perspektywę.
W poprzednim poście podniosłem ten argument jako kryterium estetyczne, jednak teraz zastanawiam się, czy to nie jest lekki wyłom w security. Tzn. jeśli ktoś np. skonstruowałby sobie obiekt wirtualny (identyfikowany jako pochodzący z naszej perspektywy) i jako rzekomo daną od nas przekazał dalej?

Wydaje mi się że warto, by mechanizm zapewniał, że tak wyłuskany obiekt wirtualny musi należeć do zbioru obiektów normalnie serwowanych przez daną perspektywę.
radamus
Posted: Friday, April 15, 2005 5:59:58 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
habela wrote:

1. w jak dużym stopniu tak przeciążony operator rzutowania miesza nam w semantyce języka?

Nie chcę się na razie na ten temat wypowiadać. Semantyka jest generalnie prosta, trzeba sprawdzić jak sprawowałby się ten operator w innych przypadkach. Zachowuje się on podobnie do operatora niealgebraicznego, tylko że nie iteruje po rezultacie ale wrzuca od razu wszystko na ENVS. Można założyć ograniczenie, że rzutowany może być tylko pojedynczy obiekt, ale nie wiem czy to jest dobre rozwiązanie.
habela wrote:

2. czy nie będzie powodował luki w systemie ograniczania dostępu w oparciu o zadeklarowane interfejsy?

Wszystko zależy od kontroli typologicznej. Należałoby założyć, że rzutowanie może odbywać się w zakresie zależności pomiędzy interfejsami. Tak jak rzutowanie pomiędzy rolami może się odbywać tylko pomiędzy rolami tego samego obiektu.
habela wrote:

3. (nie ulega wątpliwości, że możliwość takiego "podłożenia" srodowiska pod ewaluację perspektywy stanowi znacznie poważniejsze jej rozhermetyzowanie, niż proponowane parametry.)
4. zakładam, że ta dowolność, jak to określiłeś "utworzenia obiektów wirtualnych na podstawie zapytania, którego nie przewidział definiujacy perspektywę" pozwala na skonstruowanie obiektów wirtualnych które oryginalnie nie wchodziły w skład obiektów serwowanych przez perspektywę.

Masz rację, teraz jak nad tym myślę to może się tak zdarzyć. Ktoś mógłby napisać takie zapytanie:
(Company)((Pracownik where name == "Poe") as Firma);
Można temu zapobiec poprzez ograniczenie w semantyce. Wynikiem zapytania może być tylko identyfikator (bag identyfikatorów) a nie binder.

habela wrote:

W poprzednim poście podniosłem ten argument jako kryterium estetyczne, jednak teraz zastanawiam się, czy to nie jest lekki wyłom w security. Tzn. jeśli ktoś np. skonstruowałby sobie obiekt wirtualny (identyfikowany jako pochodzący z naszej perspektywy) i jako rzekomo daną od nas przekazał dalej?



Chodzi Ci o to, że (dla naszego przykładu) ktoś mógłby zdefiniować perspektywę serwującą obiekty Firma. Tak może być i to nie jest błąd ale tylko w przypadku perspektywy przeciążającej. Poza tym jednym nie powinno być możliwości zdefiniowania perspektywy, która serwuje obiekty o takiej samej nazwie jak istniejące w schemacie.

Reasumując nie uważam, że twoje rozwiązanie jest złe, pisałem o tym w przedostatnim poście. Może nie do końca podoba mi się sam refferer . To jest po prostu parametryzacja perspektyw. Osobny post napiszę nt. Twojego przykładu z artykułu bo mam kilka uwag.
Rzutowanie jest jednak innym mechanizmem, jest to konwersja interfejsu, w tym szczególnym przypadku na interfejs definiowany przez perspektywę. Powoduje to, że identyfikator z rzeczywistego (oczywiście niekoniecznie rzeczywistego) zamienia się na wirtualny.
radamus
Posted: Friday, April 15, 2005 6:25:25 PM

Rank: Advanced Member

Joined: 1/25/2005
Posts: 325
Points: 108
Location: Łódź
Zgodnie z obietnicą uwagi do przykładu z artykułu.
Code:
virtual student[0..*] : {univStud as st},
   referrer Student(sn : integer) : {st where ssn=sn} role of Person(s.ssn) {...}


Ten referrer nie do końca mi się podoba. Po pierwsze jak to jest z tymi dużymi i małymi literami (student i Student)
Po drugie jego semantyka jest dziwna. Ze składni wynika, że jest jedno virtual objects:
Code:
{univStud as st}

które musi być ewaluowane zawsze bo referrer odnosi się do st.
Code:
referrer Student(sn : integer) : {st where ssn=sn}

Czyli sam referrer jest ewaluowany potem. Trochę to komplikuje semantykę. Niby jest sparametryzowany virtual objects a nie jest.
Moim zdaniem powinien to być pełnoprawny sack z parametrem stanowiący alternatywny sposób tworzenia wirtualnych obiektów.

Student(sn : integer) : {univStud where ssn=sn}

Czyli stosując :
Code:
virtual student[0..*] : {univStud as st},
    Student(sn : integer) : {univStud where ssn=sn} role of Person(s.ssn) {...}


Wywolanie jest:
Code:
export virtual role Student {return Student(distinct(p.*.ssn));}

czyli mechanizm wybiera po prostu odpowiedni sack. Dla samego mechanizmu prościej (i dla recenzenta artykułu też :) ).

Zastanawia mnie czy mechanizm rzutowania by tu zadziałał ale na razie wydaje mi się, że nie (ale pomyślę jeszcze nad tym). Na razie zakładam, że musi być tak jak proponujesz tylko po prostu trzeba jasno powiedzieć, że mamy parametryzowane perspektywy a nie, trochę dziwne jak dla mnie, referrery.


habela
Posted: Saturday, April 16, 2005 10:55:51 PM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
Masz rację, że opisany tam wariant jest taki mało wyrazisty.
Dwie sprawy na to wpłynęły:
1. Zakładane przez nas uniezależnienie nazwy klasy od nazwy obiektów (podanej w deklaracji odpowiedniego feature). W toczonej swego czasu dyskusji na ten temat ta opcja zdawała się przeważać. W efekcie w wielu miejscach mamy rozdzielenie tych nazw. W tym "referrerze" zaś użyłem wielkiej litery dlatego, że intencją było reagowanie na cast na nazwę roli. Tymczasem, w związku z zakładaną przez nas niezależnością instance name obiekty roli Pracownik mogłyby być np. dostępne w danym miejscu w schemacie pod nazwą np. etatowy lub dowolną inną.
Dodam, że przy rozpisywaniu takich typowych małych przykładów, niezależność instanceName od nazwy klas praktycznie się nie przydaje. Stąd bardzo powszechnie przewija się deklaracja w postaci:
nazwa[0..*] : Nazwa ..... ;
2. Zadałem sobie pytanie, czy mógłby istnieć referrer bez zwykłych virtual objects. Przyjęliśmy swego czasu, że aby dodatkowo nie komplikować, wszystkie obiekty, które w danej lokalizacji będą przechowywane będą w niej "korzeniowe", czyli że jeśli w bazie/module umieścilibyśmy:
Pracownik<->Zatrudnienie<->Dział
to można wiązać nazwy wszystkich tych obiektów (tzn. nie ma np. możliwości aby dopuścić rozpoczynanie nawigacji wyłącznie od Pracownika lub Działu).
Stąd wniosek, że (aby dla perspektyw było podobnie) zwykłe virtual objects będzie potrzebne w każdym view, zaś "referrer" - tylko czasami.
Dokładając do tego założenie, że naturalne byłoby, aby referrer zwracał podzbiór obiektów selekcjonowanych przez virtual objects, wydało mi się wygodne, aby korzystał z rezultatu virtual objects. Ale to takie połowiczne rozwiązanie, bo przecież z drugiej strony mechanizm nie wymusza (może powinien...), aby to był rzeczywiście podzbiór.
Podsumowując - też chętnie widziałbym bardziej eleganckie rozwiązanie.
(w tym konkretnym wypadku: albo wymuszenie, aby referrer dokonywał selekcji na ziarnach z virtual objects (wtedy bardziej adekwatne byłoby "selector"), albo faktycznie - uniezależnienie go od virtual objects.)
Oczywiście podtrzymuję propozycję, abyśmy przymierzyli się do artykułu (jak to sugerował Szef) o modelowaniu danych relacyjnych w środowisku obiektowym i opisać tam wirtualne wskaźniki. Jeśli czas pozwoli, to optymalne byłoby, aby w oparciu o owe pomysły zmienić/ulepszyć następnie artykuł o rolach.
habela
Posted: Sunday, April 17, 2005 7:30:57 PM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
U mnie jak na razie w tej kwestii - bez przełomowych pomysłów.
Natomiast gwoli ścisłości dwa drobne komentarze - doprecyzowania do Twojego przedostatniego postu (który początkowo przeoczyłem, bo akurat forum nie wysyłało powiadomień o nowych postach).
Quote:
Chodzi Ci o to, że (dla naszego przykładu) ktoś mógłby zdefiniować perspektywę serwującą obiekty Firma.

Chodziło mi nie tyle o zdefiniowanie nowej perspektywy o tej samej nazwie, ale o wykorzystanie perspektywy już istniejącej, do generowania danych które nie wynikają z jej oryginalnego źródła danych. Akurat skojarzyło mi się to z sytuacją, w której strona WWW wyświetla w swojej strukturze zawartość pliku podanego jako parametr, ale tworzy potężną lukę w bezpieczeństwie z powodu nie sprawdzania, czy ten plik znajduje się na lokalnym serwerze, czy nie.
Quote:
Masz rację, teraz jak nad tym myślę to może się tak zdarzyć. Ktoś mógłby napisać takie zapytanie:
(Company)((Pracownik where name == "Poe") as Firma);
Można temu zapobiec poprzez ograniczenie w semantyce. Wynikiem zapytania może być tylko identyfikator (bag identyfikatorów) a nie binder.

Myślę, że w taki czy inny sposób będzie potrzeba jakiegoś uszczelnienia...

Natomiast rzeczą, której na razie nie widzę w wariancie z rzutowaniem jest obsługa złożonych ziaren (jak np. przy fragmentacji). Ale być może to tylko syntaktyczna niezręczność tam się pojawi...
stencel
Posted: Sunday, April 17, 2005 9:31:54 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Moze troche splaszczam cala dyskusje, ale rozwiazanie z paramteryzacja funkcji "virtual objects" uwazam za najlepsze.

Mamy za zadanie odwzorowac pewna wartosc (np. seed, ale przeciez nie musi byc to seed!) na obiekt wirtualny. To wlasnie jest funkcjonalnosc konstruktora, a wiec dodajmy do perspektywy taki konstruktor (parametryzowana przeciazona funkcje virtual objects) to zalatwi problem zasygnalizowany przez Piotra po napisaniu artykulu. Oto zalety:

1. Zgodnosc z ogolnymi pojeciami obiektowymi (konstruktor).
2. To autor perspektywy decyduje, czy i jakie beda te odwzorowania.

Wada (watpliwa!):

3. Wynik odzworowania moze byc spoza tego co zwraca bezparametrowa funkcja "virtual objects".

Wada ta jest dyskusyjna, poniewaz, po pierwsze bezparametrowej funkcji virtual objects nie musi byc (dlaczego ma byc obowiazkowa? czy kazda klasa ma bezparametrowy konstruktor?). Po drugie, nawet jesli taka bezparametrowa funkcja virtual objects istnieje, to wszystko jest w rekach programisty i to on decyduje co zwracaja poszczegolne funkcje virtual objects. Moze on wcale nie chce zeby wszystko bylo podzbiorem bezparametrowej virtual objects?

Moglbym sobie wyobrazic, ze np. mamy baze danych z drzewem genealogicznym i perspektywe, ktorej virtual objects wolane bez parametrow zwraca tylko glowy rodzin (takie, ze w bazie nie ma ich przodkow). Wolanie virtual objects z parametrem, ktorym jest oid osoby, zwraca potomkow tej osoby [a wiec cos czego nie zwraca bezparametrowy virtual objects].

Niech mi teraz ktos powie, ze tak jest zle! To ja jako programista sie obrazam i nie chce uzywac Waszych perspektyw ;)

habela
Posted: Sunday, April 17, 2005 9:51:35 PM
Rank: Administration

Joined: 12/6/2004
Posts: 360
Points: 52
stencel wrote:
Moglbym sobie wyobrazic, ze np. mamy baze danych z drzewem genealogicznym i perspektywe, ktorej virtual objects wolane bez parametrow zwraca tylko glowy rodzin (takie, ze w bazie nie ma ich przodkow). Wolanie virtual objects z parametrem, ktorym jest oid osoby, zwraca potomkow tej osoby [a wiec cos czego nie zwraca bezparametrowy virtual objects].

Masz rację, że jeśli rozpatrywać parametryzowane perspektywy w całym zakresie ich potencjalnych zastosowań (a nie tylko w kontekście podniesionych przeze mnie "selectorów"/"referrerów"), to postulat "podzbiór bezparametrowej" przestaje być tak kategoryczny.
Ale co najważniejsze, programista ma możliwość to wymusić sprawdzając, jakie ziarno mu z tego parametru powstanie i czy jest ono ok, czy nie.

Co do utożsamienia takiej parametryzacji perspektywy z konstruktorem, to trudno mi się w tej chwili wypowiedzieć (może się okazać, że jak się temu bliżej przyjrzymy, to nie będzie to to samo).
Zamierzałem właśnie wkrótce odkpoać wątek on_insert vs. on_new, w którym zatrzymaliśmy się na tym, że z punktu widzenia interfejsu wystarczy jedno.
Ale nie jestem pewien:
- czy wystarczy jedno również w sensie implementacji takiej operacji;
- jak właśnie tak rozumiane "new" ma się do konstruktora i do parametryzowanej perspektywy.
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Main Forum RSS : RSS

Powered by Yet Another Forum.net version 1.9.1.6 (NET v2.0) - 11/14/2007
Copyright © 2003-2006 Yet Another Forum.net. All rights reserved.
This page was generated in 0.117 seconds.