Pracuję nad aplikacją ASP.NET MVC i przyzwyczaiłem się do umieszczania w moich modelach / obiektach elementów, które wydają się przydatne i wygodne.
Na przykład:
public class Member
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string FullName
{
get { return FirstName + " " + LastName; }
}
public string FormattedPhoneNumber
{
get { return "(" + PhoneNumber.Substring(0, 3) + ") " + PhoneNumber.Substring(3, 3) + "-" + PhoneNumber.Substring(6); }
}
}
Zastanawiam się, czy ludzie myślą o FullName
i FormattedPhoneNumber
łapaczach.
Ułatwiają tworzenie znormalizowanych formatów danych w całej aplikacji i wydają się oszczędzać wiele powtarzającego się kodu, ale zdecydowanie można argumentować, że format danych jest czymś, co powinno być obsługiwane przy mapowaniu z modelu na model widoku.
W rzeczywistości pierwotnie stosowałem te formaty danych w warstwie usług, w której wykonuję mapowanie, ale ciężko było ciągle pisać formaty, a następnie stosować je w wielu różnych miejscach. Na przykład używam „Pełna nazwa” w większości widoków, a konieczność wpisywania czegoś podobnego w model.FullName = MappingUtilities.GetFullName(entity.FirstName, entity.LastName);
całym miejscu wydawała się o wiele mniej elegancka niż zwykłe pisanie model.FullName = entity.FullName
(lub, jeśli używasz czegoś takiego jak AutoMapper, potencjalnie w ogóle nic nie wpisując).
Gdzie narysujesz linię, jeśli chodzi o formatowanie danych. Czy formatowanie danych w twoim modelu jest „w porządku” czy jest to „zapach wzorowy”?
Uwaga: zdecydowanie nie mam html w moim modelu. Używam do tego pomocy HTML. Mówię ściśle o formatowaniu lub łączeniu danych (a zwłaszcza danych często używanych).
źródło
PhoneNumber
prawdopodobnie należy do własnej klasy (którą teraz zaimplementowałem). AleFullName
tak naprawdę to on zmotywował mnie do napisania pytania. Ale chcę dowiedzieć się, czy generalnie sensowne jest umieszczenie formatowania / czesania danych itp. W modelu dla rzeczy, które będą obowiązywać w całej aplikacji. Z poniższych odpowiedzi wynika, że nie jest to anty-wzór, ale decyzję należy podjąć ostrożnie.Odpowiedzi:
W twoim przykładzie podoba mi się
FullName
getter (z wszystkich podanych przez ciebie powodów), ale nie podoba mi się getter FormattedPhoneNumber. Powód jest taki: prawdopodobnie nie jest to takie łatwe (kiedy masz międzynarodowe numery telefonów itp.), A jeśli umieścisz logikę do formowania numerów telefonów w sposóbMember
, istnieje szansa, że będziesz musiał refaktoryzować (lub skopiować i wkleić kaukas ), gdy tylko potrzebuję sformatowany numer telefonuInstitution
,Vendor
itp też.EDYCJA: IMO lepiej byłoby mieć
PhoneNumber
klasę zFormatted
getterem.źródło
String
zakładam, że dla klasy) „uczysz”String
klasę formatowania numerów telefonów. Czy naprawdę obowiązkiemString
klasy jest wiedzieć o numerach telefonów? Nie wydaje mi się Stosowane w ten sposób metody rozszerzania są cukrem syntaktycznym, aby coś, co wyraźnie nie jest zorientowane obiektowo, wyglądało tak, jak było.PhoneNumber
klasy. W każdym razie planowałem to zrobić, ponieważ mam równieżPhoneType
nieruchomość.PhoneNumber
jako klasy instancji, ponieważ dane są natywniestring
. Raczej powinna to być klasa statyczna z takimi metodamipublic static string Format(string phoneNumber, PhoneNumberStyle style)
.Rzeczy, które należy wziąć pod uwagę przy pisaniu kodu: czy to prawda? Czy to jest czytelne? Czy to jest wydajne? Czy można to utrzymać? Argumentowałbym, jak wspomniał @btilly, że nie można go utrzymać z powodu formatowania specyficznego dla kultury, ale pytanie wydaje się bardziej ogólne.
Korzystanie z takich akcesoriów powoduje, że kod jest bardziej czytelny i, w zależności od tego, jak go używasz, może uczynić inne części kodu znacznie czystszymi. Moim zdaniem wcale nie pachnie. Zacznie pachnieć, jeśli będziesz mieć akcesoria do formatowania dowolnego rodzaju ciągu, który chcesz wydrukować (
public string FirstLastName; public string FullName; public string FullNameWithMiddleInitial; public string PhoneNumberWithAreaCode; public string PhoneNumberWithoutAreaCode; public string PhoneNumberWithCountryCode;
itp.)Lub, inaczej mówiąc, użycie wzorca nie powoduje automatycznie, że kod ma „zapach wzorca”. Musisz go nadużyć, jeśli chcesz zdobyć ten atrybut.
źródło
Łamie zasadę pojedynczej odpowiedzialności. Dlaczego nie stworzyć klasy numeru telefonu itp.?
źródło
FullName
zajęcia?W twoim przykładzie nie uważam tego za zbyt wielką trudność w używaniu określonych formatów. Jest to jedna lub dwie i wszystkie części aplikacji używają tego samego formatu.
Decyzja zaczyna się rozpadać, gdy te same dane trafiają do kilku różnych miejsc wymagających różnych formatów .
Gdyby tak się stało, miałbym pokusę, aby przyciągnąć
Member
klasę z powrotem do:Następnie wykonaj różne adaptery dla każdego celu. Załóżmy na przykład, że informacje były wymagane w formacie CSV:
Zawsze zakładając, że dane zostały zdezynfekowane, aby przecinki nie były w ciągach.
Adapter nie musi być metodą rozszerzenia, ale w tym przypadku, który wydaje się odpowiedni, wydaje się pasować.
źródło
over
tyle razy, to coś jest nie tak z projektem.