BG Development


  Reply to this topicStart new topicStart Poll

> Загадка - какво не е наред с този клас?
FidelDahan
Публикувано на: 03-07-2017, 17:26
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2297
Регистриран на: 12.06.08




CODE
public final class TimestampRecorder {

 private final Deque<String> records = new LinkedList<>();

 public List<String> getTimestamps() {
   synchronized (this.records) {
     LinkedList<String> timestamps = new LinkedList<>(this.records);
     if (isRecording()) {
       timestamps.removeLast();
     }
     return timestamps;
   }
 }

 public void start(long timestamp) {
   synchronized (this.records) {
     if (!isRecording()) {
       this.records.add(timestamp + "-");
     }
   }
 }

 public void stop(long timestamp) {
   synchronized (this.records) {
     if (isRecording()) {
       this.records.add(this.records.removeLast() + timestamp);
     }
   }
 }

 public boolean hasStarted() {
   synchronized (this.records) {
     return !this.records.isEmpty();
   }
 }

 public boolean isRecording() {
   synchronized (this.records) {
     return hasStarted() && this.records.getLast().endsWith("-");
   }
 }

}


Как може да се подобри дизайна?

А имплементацията как ще стане по-добре?
PMEmail Poster
Top
thrawn
Публикувано на: 03-07-2017, 17:50
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1489
Регистриран на: 17.01.17



А каква е целта на тоя код?

Въртиш някаква опашка, но цялата логика е концентрирана в последния елемент. Значи опашката е излишна и спокойно може да се замени с обикновен String (бих казал, че тук трябва да е някакъв обект който да предлага съответните полета а не да лепиш и парсваш стрингове).

Ако трябва да обработваш опашка, то ти трябва отделен клас който да я реализира/имплементира + логика за синхронизация и евентуална нотификация (ако ще се ползва многонишкова обработка). Трябва ти работник на който менаджерът с опашката да подава обект (последния?) и работникът да връща в опашката съответния статус.

Иначе, така единствения проблем който виждам е в start/stop. Те могат да се издънят (isRecording може да върне false) а ти няма как да обработиш подобно изключение с тоя гол void.

Това мнение е било редактирано от thrawn на 03-07-2017, 17:52
PMEmail Poster
Top
FidelDahan
Публикувано на: 03-07-2017, 17:57
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2297
Регистриран на: 12.06.08



QUOTE (thrawn @ 03-07-2017, 17:50)
А каква е целта на тоя код?

Нещо като лог за старт/стоп команди, от които се произвеждат интервали. При "старт" започва да се записва ново "парче" аудио, при "стоп" текущото парче е готово. При следващ старт започва следващото и така. Накрая public List<String> getTimestamps() връща тези интервали.

CODE
public class TimestampRecorderTest {

 private TimestampRecorder recorder;

 @Before
 public void setUp() {
   this.recorder = new TimestampRecorder();
 }

 @Test
 public void addingNoDataReturnsEmptyList() throws Exception {
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(Collections.emptyList(), timestamps);
   assertFalse(this.recorder.hasStarted());
   assertFalse(this.recorder.isRecording());
 }

 @Test
 public void addingStarttimeReturnsEmptyList() {
   this.recorder.start(1L);
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(0, timestamps.size());
   assertTrue(this.recorder.hasStarted());
   assertTrue(this.recorder.isRecording());
 }

 @Test
 public void addingTimestampPairReturnsCompletePart() {
   this.recorder.start(1L);
   this.recorder.stop(2L);
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(1, timestamps.size());
   assertEquals("1-2", timestamps.get(0));
   assertTrue(this.recorder.hasStarted());
   assertFalse(this.recorder.isRecording());
 }

 @Test
 public void imcompleteTimestampIsIgnored() {
   this.recorder.start(1L);
   this.recorder.stop(2L);
   this.recorder.start(3L);
   this.recorder.stop(4L);
   this.recorder.start(5L);
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(ImmutableList.of("1-2", "3-4"), timestamps);
 }

 @Test
 public void finalizeIncompleteListReturnsCompletePart() {
   this.recorder.start(1L);
   this.recorder.stop(2L);
   this.recorder.start(3L);
   this.recorder.stop(4L);
   this.recorder.start(5L);
   this.recorder.stop(6L);
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(ImmutableList.of("1-2", "3-4", "5-6"), timestamps);
 }

 @Test
 public void duplicatedCallsAreIgnored() {
   this.recorder.start(1L);
   this.recorder.start(2L);
   this.recorder.stop(3L);
   this.recorder.stop(4L);
   List<String> timestamps = this.recorder.getTimestamps();
   assertEquals(ImmutableList.of("1-3"), timestamps);
 }

}


QUOTE
(бих казал, че тук трябва да е някакъв обект който да предлага съответните полета а не да лепиш и парсваш стрингове)

Точно, това е проблема в дизайна със стринговете API-то е много зле.

QUOTE

Иначе, така единствения проблем който виждам е в start/stop. Те могат да се издънят (isRecording може да върне false) а ти няма как да го обработиш.

Това е проблема в имплементацията. Дефакто този обект си е стейт-машина...

Това мнение е било редактирано от FidelDahan на 03-07-2017, 17:58
PMEmail Poster
Top
Bender
Публикувано на: 03-07-2017, 18:07
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 4993
Регистриран на: 19.06.14



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. защото, който изпълни волята на Моя Отец Небесен, той Ми е брат, и сестра, и майка.



Това мнение е било редактирано от Bender на 07-01-2018, 19:56
PM
Top
bvbfan
Публикувано на: 03-07-2017, 18:28
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2569
Регистриран на: 08.12.13



Не че разбирам Java, но много лошо впечатлени ми прави конструкцията
CODE
synchronized (this.records) {
    if (isRecording()) // <--------- отново synchronized

deadlock? Mutex (Java) е single or recuirsive ?


--------------------
QUOTE (Bender @ 23-04-2015, 19:11)
Xamarin: ЛАПАЙ!
Ти: Добре...
PMEmail Poster
Top
Bender
Публикувано на: 03-07-2017, 18:29
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 4993
Регистриран на: 19.06.14



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. И Саул го попита: чий син си, момко? Давид отговори: син на твоя раб Иесея от Витлеем.



Това мнение е било редактирано от Bender на 07-01-2018, 19:56
PM
Top
stewie
Публикувано на: 03-07-2017, 19:21
Quote Post



Име:
Група: Форумен член
Ранг: Почетен член

Мнения: 3509
Регистриран на: 14.07.16



Като .нет експерт и джава дебил да попитам - synchronized върху обект работи като lock, т.е. thread sync нали ?
Чудя се колко е надеждно локването ти преди гет операция като hasStarted() - имаш един елемент в свързаният ти списък точно преди някоя нищка да влезе в този скоуп, а точно след нея чака друга на stop() да го маха.
PM
Top
thrawn
Публикувано на: 03-07-2017, 19:28
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1489
Регистриран на: 17.01.17



Ми то тая постановка така или иначе не се прави така.
Редно е да има две опашки - в едната се тъпчат обекти които трябва да се обработят, махат се от там и след обработка се мятат в друга опашка (обработени обекти).
Така ще отпадне и подозрителната функция getTimestamps (поне като логика).

Това мнение е било редактирано от thrawn на 03-07-2017, 19:32
PMEmail Poster
Top
FidelDahan
Публикувано на: 03-07-2017, 22:44
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2297
Регистриран на: 12.06.08



Утре ако ми остане време ще го рефакторизирам. От стринг към някакъв интервалов тип и с вътрешна стейт машина...
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0