Wartość DEFALTOWA pola, rozważania

0

Wyobraźmy sobie jakiś element biznesowy

class MagazynFilter {
        const string DefaultowyMagazyn = "Firma";
        
    string magazyn;
    MagazynFilter() {
           magazyn = ""; 
   }
}

natomiast wielokrotnie podczas użycia sprawdzamy, np

MagazynFilter filter;
if( filter.magazyn !=DefaultowyMagazyn )
       print("Magazyn: ""+ filter.magazyn);

Chodzi mi o to, że pole ma dwie ciekawe semantycznie wartości: uzyskaną w konstruktorze (pustą), i pewną wybraną (oczywiscie też inne, ale o nic nic ciekawego nie mówimy)
i żeby napisać

if ( ! Utils.IsDefalt(filer.magazyn) )
  print(...)

Na gruncie Javy /C# można to zadekalrować atrybutem / adnotacją

class MagazynFilter {

    @DefalutValue(DefaultowyMagazyn)    
    string magazyn;
    ...
   }
}

Czy moje myślenie jest totalnie odjechane, czy czasem ktoś myślał w ten sposób?

Świadomie mieszam Javę w C#, chodzi mi o ideę projektową a nie implementację (z tą by poradził choćby refleksją)

4

Trochę odjechane imo. W takich przypadkach magazyn nie powinien być stringiem tylko jakimś value objectem i mieć metodę isDefault(). Oczywiście tyczy się to tylko sytuacji, gdy domyślny magazyn jest predefiniowany i można go zhardcode'ować, ale w zasadzie to samo ograniczenie tyczy się adnotacji.

Twoje rozwiązanie ma pewien potencjał dla tych, którzy myślą że mniej kodu == lepiej. Dla mnie prostszy kod == lepiej.

1

Czy domyślne znaczy "mające wartość taką, jaką domyślnie uznamy, że powinno mieć, natomiast mało nas interesuje, czy coś jest domyślne czy nie"?
Np. moglibyśmy ustawić kraj domyślny jako "Polska" i traktować to tak samo jak sytuację, kiedy użytkownik sam wybierze kraj "Polska".

Czy może jednak "domyślne" znaczy "nieokreślone, niewybrane, musimy mieć możliwość sprawdzenia, czy coś jest domyślne i np. zasygnalizować to użytkownikowi".
Wtedy kraj domyślny oznaczałby pustą wartość, więc musielibyśmy spytać użytkownika, żeby wybrał kraj.

Myślę, że to dwa różne przypadki (mimo, że mogą na siebie nachodzić).

w JS pierwszy przypadek zapisałbym jako

const DEFAULT_COUNTRY = "Poland";
country = DEFAULT_COUNTRY; 

drugi przypadek natomiast mógłbym zapisać tak:

if (country === undefined) {
    country = await askUserForCountry();
}
0

if( filter.magazyn !=DefaultowyMagazyn ) albo if ( ! Utils.IsDefalt(filer.magazyn) ) to wtf. Ja bym zaczął od tego ze MagazynFilter to jakiś obiekt domenowy i masz filter.isDefault() jeśli już.

1

Patrzę sobie na kod:

ZrobieDobrze napisał(a):
MagazynFilter filter;
if( filter.magazyn !=DefaultowyMagazyn )
       print("Magazyn: ""+ filter.magazyn);

I myslę że przy takim zachowaniu to jest bardziej Option niż wartość domyślna. Nie lepiej byłoby napisać

case class MagazynFilter(magazyn: Option[String])

A potem:

filter.magazyn.map(magazyn => print("Magazyn: ""+ magazyn))

?
Z racji tego że jestem przy trzecim kieliszku nie chce mi się tego tłumaczyć na Javę i C# którego nie znam i mam cichą nadzieję że ogarniecie

2

Nie da się uciec od implementacji, bo wartości domyślne metod, w szczególności metod fabrykujących/konstruktorów, to nic innego jak code sugar zastępujący wzorzec Builder.

Zakładając, że chcesz zbudować sobie filtr do wyszukiwania ludzi, można zrobić to albo tak:

PersonFilter = PersonFilter.builder()
  .withName("Andrzej")
  .withAgeHigherThan(18)
  .build();

Gdzie build() wypełni resztę pól filtra wartościami domyślnymi typu *, albo zrobić to samo przy użyciu wartości domyślnych (tutaj Kotlin):

class PersonFilter(val name:String = "*", val lastName:String = "*", val minAge:Int = 0, val maxAge:Int = Int.MAX_VALUE)

1 użytkowników online, w tym zalogowanych: 0, gości: 1