Programowanie .NET i klasy POCO

9

Myślałem dziś wieczorem, zastanawiając się nad aplikacją, którą muszę zmienić i przyszło mi to do głowy. Entity Framework Entities to POCO (Plain old CLR Objects), a modele używane w ASP.NET MVC są zwykle również POCO. Zasadniczo oznacza to tylko właściwości, bez metod.

Teraz programowanie OO normalnie pozwala obiektowi obudować jego funkcjonalność, która obejmuje zarówno jego właściwości, jak i metody, co pozwala na wystąpienie polimorfizmu. Wraz ze wzrostem liczby klas POCO, wzorce projektowe, takie jak repozytoria ogólne, stały się bardziej popularne. Kiedy w przeszłości moje obiekty miały własne operacje CRUD, teraz mam je w repozytorium.

Czy to tylko ewolucja w OO, w której operacje CRUD są usuwane z obiektów, aby umożliwić ich oddzielenie, czy może operacje CRUD nie powinny być w przeszłości na poziomie obiektu, a ja się myliłem? cholera, może oba są całkowicie uzasadnione i zawsze były. To tylko spostrzeżenie, które skłoniło mnie do myślenia, więc pomyślałem, że będę szukał innych opinii.

James
źródło

Odpowiedzi:

9

Jak powiedział Wyatt, POCO i POJO w żaden sposób nie sugerują żadnych metod. Myślę, że wynika to z tego, że nie wiemy, czym jest non-POCO i non-POJO.

Pierwsze wersje technologii ORM nie były POCO i POJO tylko dlatego, że wymagały od jednostek dziedziczenia klasy bazowej z samego frameworka. W przypadku Javy Entity Beans. W przypadku Entity Framework POCO nie było możliwe w pierwszej wersji i każda jednostka musiała odziedziczyć Entityklasę podstawową.

To wymaganie stworzyło zależność twojego modelu danych od technologii trwałości, co sprawia, że ​​wiele rzeczy jest trudnych lub niemożliwych. Rzeczy takie jak testowanie jednostek wymaga wyśmiewania frameworka bean / bytu, co okazało się praktycznie niemożliwe. Nie można również używać modelu z inną technologią trwałości lub nie można używać modelu w innym kontekście, na przykład w środowisku mobilnym.

Zatem twoje założenie, że POCO dotyczy braku metod, jest błędne. POCO polega na możliwości wykorzystania modelu w oderwaniu od technologii trwałości.

To, o czym mówisz, jest prawdopodobnie zbliżone do modelu domeny anemicznej vs. właściwego modelu domeny.

Euforyk
źródło
Masz rację, to bardziej przypomina Anemiczny model domeny po przeczytaniu tego artykułu.
James
4

POCO w żaden sposób nie sugeruje, że nie ma metod - chociaż większość przykładów, które widzimy, wykorzystuje wiele funkcji automatycznego wiązania MVC, które dotyczą głównie właściwości i ignorują metody.

Posiadanie trwałości osadzonej w obiektach modelu narusza separację problemów i bardzo utrudnia wykonywanie takich rzeczy, jak testowanie jednostkowe obiektów bez stawiania bazy danych. Nie jest to funkcja obiektu modelu, ale funkcja innej klasy, takiej jak repozytorium.

Wyatt Barnett
źródło
Co? Poco całkowicie sugeruje brak metod z mojego doświadczenia - w przeciwnym razie jest to jednostka lub model lub model widoku w zależności od zastosowania.
Telastyn
2
Ostatnim razem, gdy sprawdziłem, że zwykły stary obiekt C-Sharp może mieć metody. Termin pojawił się w dawnych, niegrzecznych czasach, w których istniały rzeczy takie jak zestawy danych na maszynie lub w inny sposób obiekty modelu dziedziczyły po określonych klasach i nie były obiektami POCO.
Wyatt Barnett
Rozdzielenie obaw można osiągnąć przy zachowaniu metody na obiekcie, poprzez zaakceptowanie interfejsu przez metodę. Interfejs ten określa typ, który może obsługiwać operacje CRUD dla obiektu.
James
0

Ostatnio używam metod rozszerzeń do takich rzeczy.

POCO zawiera logikę, która ma sens tylko dla samego obiektu. Logika biznesowa lub skoordynowana logika obiektowa wchodzi w rozszerzenie BL. Dostęp do danych może przejść do warstwy dostępu do danych lub rozszerzenia dostępu do danych.

namespace MyApp
{
    public class MyClass
    {
        public string id;
        public string name;
        public int quantity;
        public decimal price;
    }   
}

namespace MyAppBL
{
    public static class MyClassBL
    {
        public static decimal PriceInCart(this MyClass myObject)
        {
            return myObject.quantity > 10 ? myObject.price * 0.9m : myObject.price;
        }
    }
}

namespace MyAppDA
{
    public static class MyClassDA
    {
        public static void Create()
        {
            …
        }

        public static void Read(string myObject)
        {
            …
        }

        public static void Update(this MyClass myObject)
        {
            …
        }

        public static void Delete(this MyClass myObject)
        {
            …
        }
    }
}

To daje bardzo miły myObject.PriceInCart()i myObject.Save()jednocześnie skupiając klasę na danych. Oczywiście w przypadku metod statycznych musisz MyAppDA.Create()zamiast tego MyApp.Create().

Jeffery Thomas
źródło