webForumDet fria alternativet

Arkitektur på objekt

Programmeringur Programmering - Övrigt

32 svar · 1 261 visningar · startad av Lilly · sida 2 av 2

CompusaMedlem sedan jan. 20023 327 inlägg
#21

Gladh skrev:

compusa skrev:

Är det detta du är skeptiskt till?

Både ja och nej. Det är bra att det inte är ditt objekt i sig själv som sköter updateringen utan du har lagt ut det i någon annanstans, att du sedan wrappar det i ditt objekt är väl okej, även om jag inte tycker det behövs eller är snyggt.

Var i applikationen ser du helst att man har logiken för att skapa/ändra/ta bort/mm objekten? Jag hade den som sagt från början i mina Command objekt som min Front Controller mappar till vid klient-förfrågningar. Det fungerade väl bra men kändes inte helt optimalt, i alla fall inte med J2EE-tekniken.

Gladh skrev:

Det är inte bra att du har specifika funktioner för att skapa och spara varje objekt.

dao.getCustomerDAO();

border vara:

dao.GetAnyObjectDAO();

På detta sätt får du mindre (men mer komplex) kod. Nu är det egentligen inget problem då de flesta av dessa DAOFactorys oftas genererars från något program, men om man vill gå in och ändra något generellt för alla klasser så måste man gå in i alla GetObjectDAO() metoder och ändra i dessa istället för att bara ändra i GetAnyObjectDAO().

Min DAO är ganska strikt uppbyggd efter specifikationerna i J2EE-pattern catalog. Egentligen har jag ett interface för varje typ, dvs CustomerDAO är ett interface, och MysqlCustomerDAO skulle kunna vara en klass som implementerar detta interface. Min DAOFactory är abstrakt, men när jag anropar med dao.getCustomerDAO så görs detta mot en konktret factory, dvs något i den här stilen:

public class MysqlDAOFactory extends DAOFactory {
  public CustomerDAO getCustomerDAO() {
    // MysqlCustomerDAO implements CustomerDAO
    return new MysqlCustomerDAO();
  }

Hur ska jag kunna komma förbi detta? Varje DAO såsom CustomerDAO har ju singa egna operationer mot databasen, samt att implementationerna kan skilja sig åt mellan olika DBMS. Att ha en generell klass får jag inte riktigt ihop... Är det möjligtvis en OR-mapper du syftar på?

Gladh skrev:

lilly skrev:

För manager är väl samma sak som CustomerRepository i ovanstående länk?

Japp och och Patrik pratar om samma sak, med olika namn bara, och det är näste samma sak som Compusa pratar om, Compusa har dock spcifika Factory-klasser för varje typ av objekt som skall skapas, jag och Partik pratar om en generell factoryklass.

Tror det framkom ovan, men jag använder inte en konkret factory för varje objekt som skapas. En konktert factory för varje DBMS om så krävs. En DAO av typen CustomerDAO är en vanlig klass som implementera metoderna för att läsa/ändra data i olika varianter av DBMS.

Alltså:
DAOFactory -> kan skapa olika typer av konkreta "DBMS"-factories, OracleFactory, MysqlFactory, eller kanske en JdbcFactory etc...

Oracle, MysqlFactory -> kan skapa alla typer av DAO:s som implementerar CustomerDAO, OrderDAO och således hantera alla value-objekt såsom Customer och Order etc.

Men det framkom nog tidigare i mitt inlägg ;)

/Edit
Kanske något i denna stilen: http://www.java2s.com/Code/Java/Hibernate/GenericDaoCreate.htm

NickemannenMedlem sedan aug. 20003 575 inlägg
#22

Ahhh... caching, visst skall man bygga in caching i sin managerklasser.
Men man skall använda det med suntförnuft, eftersom det kan vara så att andra program kan gå ner och ändra i databasen för ett objekt som du har i din cache, och när du då inte hämtar upp det igen från databasen utan hämtar det från din cache, så har du inte ett korrekt data objekt, eftersom datan i databasen inte stämmer överens med den data som du har i din cache... Samt att du måste hantera möjligheten att ta bort dess objekt när minnet börjar ta slut, för du vill ju inte att din applikation skall dö bara för att du fyllt din cache med en massa objekt som du inte använder

Så cache är bra när man vet hur och när man skall använda det...

Självklart finns det problem med cachning men till alla finns det lösningar ^^.. Finns massor av consitency lösningar, precis som det finns bra algorithmer för att skyffla ut objekt t.ex. objekt som inte använts på länge eller objekt som inte används så ofta osv. :)

GladhMedlem sedan maj 20012 812 inlägg
#23

compusa skrev:

Var i applikationen ser du helst att man har logiken för att skapa/ändra/ta bort/mm objekten

Jag har denna logik i mitt business lager. Om det är samma som ditt command objekt vet jag inte.

compusa skrev:

Hur ska jag kunna komma förbi detta? Varje DAO såsom CustomerDAO har ju singa egna operationer mot databasen, samt att implementationerna kan skilja sig åt mellan olika DBMS. Att ha en generell klass får jag inte riktigt ihop... Är det möjligtvis en OR-mapper du syftar på?

Japp det är en OR-mapper som jag syftar på.

compusa skrev:

Tror det framkom ovan, men jag använder inte en konkret factory för varje objekt som skapas. En konktert factory för varje DBMS om så krävs. En DAO av typen CustomerDAO är en vanlig klass som implementera metoderna för att läsa/ändra data i olika varianter av DBMS.

Alltså:
DAOFactory -> kan skapa olika typer av konkreta "DBMS"-factories, OracleFactory, MysqlFactory, eller kanske en JdbcFactory etc...

Oracle, MysqlFactory -> kan skapa alla typer av DAO:s som implementerar CustomerDAO, OrderDAO och således hantera alla value-objekt såsom Customer och Order etc.

Men det framkom nog tidigare i mitt inlägg

Då missförstod jag dig. Jag tycker dock det är ett omständigt sätt att göra det på.

Jag har min ORmapper som klara av att hantera all typer av objekt som implementeras med lite metadata.

Det jag gör i min kod är följande:

[DataSource("CustomerTable")]
public class Customer{
 [Identifier]
 [DataField("Identifier")]
 private Identifier _Identifier;

 [DataField("Firstname")]
 private string _Firstname;
}

Customer customer = new EntityBroker("connectionstring").Load<Customer>(identifier);

EntityBrokern är en assembly som jag bara gör en referens till, så där behövs inte skriva något för varje specifik applikation, däremot så måste den utvigdas om man skall hanterar en lagringskälla som inte stöds just nu.

Så det som skall skrivas i varje applikation är Customer objektet med dess attributer, och dessa kan jag välja att lägga i xml-fil istället, så jag kan återanvända samma objekt i olika applikation där databastabelen eller databaskolumnerna heter annorlunda.

- M

GladhMedlem sedan maj 20012 812 inlägg
#24

[cita=nickemannen]
Finns massor av consitency lösningar,

Hur skall du implementerar detta om du inte ens vet att objektet är invalidt. Det märker du först när du försöker persisterar ner det till databasen att det inte är validt, under tiden så har du jobbat med felaktigt data...

Som jag ser det så kan man lösa det på 2 sätt. Du får en notifikation från din datakälla att ditt objekt har ändrat data, detta kräver pollingfunktionallitet mot de flesta datakällor, och då måste du ju ändå nere och prata med databasen.

Det andra är att du skapar en Single-point-of-access. Alltså en webservice som alla måste gå igenom för att hämta och spara ner dessa objekt, och där kan du sedan ha caching funktionallitet. Men då måste du ju ändå ut över nätverket, visst kan du spara lite tid här men frågan är hur mycket...

Men visst finns behovet av en cach i sin ORMapper, men man skall bara inte implementera den rakt av och alltid använda den, för någon data är mer kritiskt att den är korrekt än annan. Det avgörs av applikationen och inte ORMappern.

nickemannen skrev:

precis som det finns bra algorithmer för att skyffla ut objekt t.ex. objekt som inte använts på länge eller objekt som inte används så ofta osv

Visst kan man lägga in algoritmer, men du kan ändå råka ut för problemet med att du har objekt i din cache som du använt på 10 minuter och dessa är så många att minnet tar slut. Du måste alltså ha en separat funktion som ligger och kontrollerar hur mycket minne som finns kvar och när det börjar ta slut så skall denna funktion in i cachen och börja rensa ut objekt.

Allt går att lösa, men oftas så missar man detaljerna och allt fungerar bra ett tag tills problemen kommer i produktion ett halvår senare.

Hade precis sådant exempel här hos mig. Man hade gjort en webservicelog appender till log4net. Där man för att minska ner belastningen på nätet köa upp logmeddelandet en tid och sedan skickade iväg de i mindre klumpor, säg 100 meddelande varannan sekund. Det fungerarde fint en tid, sedan var det en applikation som hela tiden fick memory exceptions. Det visade sig att man loggade mer än de 100 meddelande varannan sekund. Säg 300 meddelande medans endast 200 skickades iväg. Nu växte kön med 100 meddelande varje sekund och efter några dagar så var minnet slut och man fick en memory out exception.... Man tänkte inte till riktigt när man byggde kön och förutsatte att alla skulle skriva rätt parameters för att skicka iväg meddelanden.

- M

CompusaMedlem sedan jan. 20023 327 inlägg
#25

Gladh skrev:

Jag har denna logik i mitt business lager. Om det är samma som ditt command objekt vet jag inte.

Jag det är väl mer eller mindre mitt business lager tror jag. Har ältat lite om det.

Vy (Jsp-sidan) - Front Controller - Command Objects - DAO - DBsource

Command objekten såsom CustomerCommand använder sig av DAO:n för att läsa/ändra data i databasen. Value-objekten (eller om det kallas transfer) används av både Command-objekten och DAO-objekten för att enklare transportera-datan mellan lagrena. För att vyn ska få tillgång till objekten måste jag sätta request-parametrar i mitt Command-objekt stil med:

Customer cust = someCallToDAO();
request.setAttribute("customer", cust);

Om detta är att föredra framför att ha det i value-objektet så antar jag att jag gjort rätt från början. Funderar som sagt på att göra en lösningen för mina value-objekt som har denna funktionalitet. Kanske låta dessa implementera något interface i stil med PersistentBean som kräver implementering av metoderna save, update, delete. Det som gör att jag känner mig tveksam till att Command-objekten är det rätta stället är att dessa är ganska specifika för ett webb-interface, i och med att request-objekten inte används om jag skulle skapa en desktop-applikation. Då känns det bättre att låta Command-objekten anrop mina value-objekt, alternativ en annan typ av klass som anropar min DAO.

Gladh skrev:

Då missförstod jag dig. Jag tycker dock det är ett omständigt sätt att göra det på.

Japp det var nog av den anledningen som gjorde att OR-mappern uppstod, tröttsamt i längden att skapa alla dessa klasser :) Till en början ska jag nog göra detta, men tanken är att senare använda mig av Hibernate, men jag får ta det steg för steg känns det som. Så jag har förståelse för båda.

Gladh skrev:

Jag har min ORmapper som klara av att hantera all typer av objekt som implementeras med lite metadata.

Det jag gör i min kod är följande:

[DataSource("CustomerTable")]
public class Customer{
 [Identifier]
 [DataField("Identifier")]
 private Identifier _Identifier;

 [DataField("Firstname")]
 private string _Firstname;
}
Customer customer = new EntityBroker("connectionstring").Load<Customer>(identifier);

Verkar mycket smidigt och jag är övertygad om att en OR-mapper underlättar/effektiviserar utvecklingen mycket.

Jag får helt enkelt fundera vidare på var jag ska ha logiken som anropar min DAO. Ser både för och nackdelar med båda de alternativen jag listade i början av detta inlägg. Jobbigt att bestämma sig om sånt här, önskade att det fanns ett tredje alternativ som övertygade mig helt och hållet om hur jag ska göra :)

renholmMedlem sedan apr. 20012 266 inlägg
#26

Flyttad från .NET då ämnet mer rör OOP i allmänhet.

NickemannenMedlem sedan aug. 20003 575 inlägg
#27

Svar till Gladh,

Det bästa sättet enligt mig är inte att ha Ms Sql Servern direkt kopplad till klientappliaktionen utan att aha en applikation mellan sql servern och klientapplikationen som alla klienter arbetar emot. Här kan man enkelt använda sig av någon typ av observerpattern. Vilket gör att klienterna hela tiden uppdaterar sina objekt som skulle kunna bli gamla detta är ett exempel.

Detta med utrymme, man får göra som du säger ja kontrollera att det finns minne eller sätta en gräns på hur många objekt som max får finnas i cachen självklart, det var där jag tänkte att algorithmen skall hålla reda på vilka som skall kastas ut. Det var inte meningen att alhorithmen inom en viss tid skulle slänga ut objekt utan veta vilka objekt som skall ut när det är dags att kasta ut vilket är beroende på ledigt minne eller objektmängd vad man nu vill använda.

GladhMedlem sedan maj 20012 812 inlägg
#28

nickemannen skrev:

Det bästa sättet enligt mig är inte att ha Ms Sql Servern direkt kopplad till klientappliaktionen utan att aha en applikation mellan sql servern och klientapplikationen som alla klienter arbetar emot. Här kan man enkelt använda sig av någon typ av observerpattern. Vilket gör att klienterna hela tiden uppdaterar sina objekt som skulle kunna bli gamla detta är ett exempel

En lösning med single-point-of-access. Det är som sagt en väg att gå för att lösa problemen med caching, men frågan är om man inte går över ån för vatten här. Du implementerar en ganska komplexlösningen för att slippa gå i databasen för att hämta objektet, men du sparar inte speciellt mycket eftersom du ändå måste ut över nätverket, jag kan se en vinst i det om du har tunga objekt som tar tid att skapa, eller minska belastningen på en hårt belastad databas, men annars inte. Komplexiteten som du inför tycker inte jag motsvarar vinsten du får (om du ens får en, helt beroend på protkoll som du använder, en webservice är nästa förbjudet här!). IMHO...

- M

NickemannenMedlem sedan aug. 20003 575 inlägg
#29

Nja, vinsten blir ju om objekten inte uppdateras ofta då ligger ju cachen hos klienten och uppdateras då och då från applikationsservern.
Och om man inte har något plugin till sql servern så är datan som skickas som objekt mindre än det som skulle skickas från en sql server plus att man fortfarande inte kan vara säker på att man har det senaste.

En webservice är förbjudet ja jag hade mer tänkt mig någon teknik för distribuerade objekt där det är tvåvägskommunikation.

GladhMedlem sedan maj 20012 812 inlägg
#30

nickemannen skrev:

Nja, vinsten blir ju om objekten inte uppdateras ofta då ligger ju cachen hos klienten och uppdateras då och då från applikationsservern.

oj.. du menar alltså att förändringar pushas ut från applikationsservern till klienterna att det har skett förändringar på detta objekt, byt ut det i din lokala cahce?

Om du menar det så visst så kan du tjänna lite på att du alltid har uppdaterade objekt lokalt på din klient, men du kommer ju få en del nätverkstrafik som du inte önskar, eftersom din applikationsserver kommer skicka ut ett uppdaterat objekt till alla klienter även om dessa klienter inte ens använder detta objekt. Samt att du lagt på ytterligare komplixitivitet, och den är inte liten heller. Detta tycker jag verkligen är att gör det omständigt för sig, istället för att bara använda databasen som "applikationsserver". Men det kan ju finnas behov att ha det så, men jag tror inte du vinner så mycket prestanda på det, om din databas inte är extremt långsam, eller hårt belastad.

Webservicen är inte förbjuden, bara nästan, det vill säga att om man använder sig av webservices så får man en fet prestandahit jämfört med att hämta direkt från databasen, men samtdigt så kan ju vilket utvecklingsspråk som helst använda sig av webservicen för att kommunicera med applikationsserver. Det gör ju att även Java kan använda sig av denna applikationsserver, vilket de inte kan om du använder .NET Remoting (som stödjer eventhanteringen).

Bara för att klargöra att jag inte är emot cachen, så ja man skall cacha det man kan men inte bara göra det rakt av utan verkligen tänka sig för vad det är man cachar och varför man cachar det, och framför allt, skall man skriva cachen själv, så bör man verkligen tänka efter några gånger till, eftersom man kan förstöra mer än man vinner.

- M

NickemannenMedlem sedan aug. 20003 575 inlägg
#31

Japp, det är ändamålet som bestämmer vad och varför man skall göra saker.
I det fallet som jag sitter i just nu är det en hård belastad server med ganska mycket information. Informationen som ligger i databasen används inte över hela landet utan är ganska uppdelad. Tyvärr så kommer det inte finnas någon applikationserver som pushar upp objekten.
Tanken var ju inte att alla objekt skall pushas upp utan bara de objekt som klienten prenumrerar på så att säga.

GladhMedlem sedan maj 20012 812 inlägg
#32

nickemannen skrev:

Tanken var ju inte att alla objekt skall pushas upp utan bara de objekt som klienten prenumrerar på så att säga.

Lite bättre prestandmässigt, men oj vad mer komplext det blir...

Du ser kanske vart jag vill komma. Ibland kan prestandahiten vara helt okej att ta med tanke på att komplexititen av koden blir så mycket enklare, vilket resulterar i mindre fel och lättare underhåll... Keep it simple!

Men fy va kul det hade varit att skriva applikationsservern, där hade man kunnat grotta ner sig en stund... :)

- M

NickemannenMedlem sedan aug. 20003 575 inlägg
#33

Gladh skrev:

nickemannen skrev:

Tanken var ju inte att alla objekt skall pushas upp utan bara de objekt som klienten prenumrerar på så att säga.

Lite bättre prestandmässigt, men oj vad mer komplext det blir...

Du ser kanske vart jag vill komma. Ibland kan prestandahiten vara helt okej att ta med tanke på att komplexititen av koden blir så mycket enklare, vilket resulterar i mindre fel och lättare underhåll... Keep it simple!

Men fy va kul det hade varit att skriva applikationsservern, där hade man kunnat grotta ner sig en stund... :)

- M

Det ska vara kul.
Tja komplexa system är roliga, men det borde inte vara så svårt med en ordentlig kravspecifikation och en riktigt genomtänkt designspecifikation annars blir det nog väldigt svårt som du säger.
Det är inte direkt att sätta sig och koda direkt med första bästa ide som dyker upp i huvudet.
Man får ju gräva lite i litteraturen för att hitta dom bästa lösningarna.

516 ms totalt · 3 externa anrop · v20260731065814-full.c74b5be1
133 ms — hämta forumlista (db)
374 ms — hämta statistik (db)
139 ms — hämta tråd, inlägg och bilagor (db)