Ngôn ngữ OO đôi khi có thể được sử dụng thay cho ngôn ngữ cấp thấp để giao tiếp trực tiếp với máy. C ++ Chắc chắn, nhưng ngay cả đối với C # cũng có bộ điều hợp và như vậy. Mặc dù viết mã để điều khiển các bộ phận cơ học và kiểm soát phút trên bộ nhớ tốt nhất nên giữ càng gần mức thấp càng tốt. Nhưng nếu câu hỏi này liên quan đến phần mềm hướng đối tượng hiện tại như Line Of Business, ứng dụng web, IOT, Dịch vụ web và phần lớn các ứng dụng được sử dụng hàng loạt, thì ...
Trả lời, nếu có
Độc giả có thể thử làm việc với Kiến trúc hướng dịch vụ (SOA). Đó là, DDD, N-Layered, N-Tiered, Hexagonal, sao cũng được. Tôi chưa thấy một ứng dụng kinh doanh lớn sử dụng hiệu quả OO "Truyền thống" (Bản ghi hoạt động hoặc Mô hình phong phú) như được mô tả trong thập niên 70 và 80 trong thập kỷ qua +. (Xem chú thích 1)
Lỗi không phải ở OP, nhưng có một vài vấn đề với câu hỏi.
Ví dụ bạn cung cấp chỉ đơn giản là để chứng minh tính đa hình, nó không phải là mã sản xuất. Đôi khi các ví dụ chính xác như thế được thực hiện theo nghĩa đen.
Trong FP và SOA, Dữ liệu được tách ra khỏi Logic nghiệp vụ. Đó là, Dữ liệu và Logic không đi cùng nhau. Logic đi vào Dịch vụ và Dữ liệu (Mô hình miền) không có hành vi Đa hình (Xem Lưu ý 2).
Dịch vụ và chức năng có thể là đa hình. Trong FP, bạn thường xuyên truyền các hàm dưới dạng tham số cho các hàm khác thay vì các giá trị. Bạn có thể làm tương tự trong các ngôn ngữ OO với các loại như Callable hoặc Func, nhưng nó không chạy tràn lan (Xem Lưu ý 3). Trong FP và SOA, Mô hình của bạn không phải là Dạng đa hình, chỉ có Dịch vụ / Chức năng của bạn. (Xem chú thích 4)
Có một trường hợp xấu về mã hóa cứng trong ví dụ đó. Tôi không chỉ nói về chuỗi "chó sủa" màu đỏ. Tôi cũng đang nói về CatModel và DogModel. Điều gì xảy ra khi bạn muốn thêm một con cừu? Bạn phải đi vào mã của bạn và tạo mã mới? Tại sao? Trong mã sản xuất, tôi chỉ muốn thấy một AnimalModel với các thuộc tính của nó. Tệ nhất, một AmphibianModel và FowlModel nếu thuộc tính và cách xử lý của chúng quá khác nhau.
Đây là những gì tôi mong đợi sẽ thấy trong Ngôn ngữ "OO" hiện tại:
public class Animal
{
public int AnimalID { get; set; }
public int LegCount { get; set; }
public string Name { get; set; }
public string WhatISay { get; set; }
}
public class AnimalService : IManageAnimals
{
private IPersistAnimals _animalRepo;
public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }
public List<Animal> GetAnimals() => _animalRepo.GetAnimals();
public string WhatDoISay(Animal animal)
{
if (!string.IsNullOrWhiteSpace(animal.WhatISay))
return animal.WhatISay;
return _animalRepo.GetAnimalNoise(animal.AnimalID);
}
}
Làm thế nào để bạn chuyển từ các lớp trong OO sang lập trình chức năng? Như những người khác đã nói; Bạn có thể, nhưng bạn không thực sự. Quan điểm trên là để chứng minh rằng bạn thậm chí không nên sử dụng Classes (theo nghĩa truyền thống của thế giới) khi thực hiện Java và C #. Khi bạn có thể viết mã theo Kiến trúc hướng dịch vụ (DDD, Layered, Tiered, Hexagonal, bất cứ điều gì), bạn sẽ tiến gần hơn một bước đến chức năng vì bạn tách dữ liệu (Mô hình miền) khỏi các hàm logic (Dịch vụ) của bạn.
Ngôn ngữ OO một bước gần hơn với FP
Bạn thậm chí có thể đưa nó đi xa hơn một chút và chia Dịch vụ SOA của bạn thành hai loại.
Loại tùy chọn Loại 1 : Giao diện chung - Dịch vụ triển khai cho Điểm vào. Đây sẽ là các Điểm vào "không trong sạch" có thể gọi vào chức năng khác "Tinh khiết" hoặc "Không trong sạch". Đây có thể là Điểm vào của bạn từ API RESTful.
Loại tùy chọn 2 : Dịch vụ logic kinh doanh thuần túy. Đây là các lớp tĩnh có chức năng "Pure". Trong FP, "Pure" có nghĩa là không có tác dụng phụ. Nó không đặt rõ ràng Trạng thái hoặc Kiên trì ở bất cứ đâu. (Xem chú thích 5)
Vì vậy, khi bạn nghĩ về các Lớp trong Ngôn ngữ hướng đối tượng, được sử dụng trong Kiến trúc hướng dịch vụ, nó không chỉ mang lại lợi ích cho Mã OO của bạn, nó bắt đầu làm cho Lập trình hàm có vẻ rất dễ hiểu.
Ghi chú
Lưu ý 1 : Thiết kế hướng đối tượng "Giàu có" hoặc "Ghi lại hoạt động" ban đầu vẫn còn. Có rất nhiều mã kế thừa như thế khi người ta "làm đúng" một thập kỷ trở lên. Lần trước tôi đã thấy loại mã đó (được thực hiện chính xác) là từ một trò chơi video Codebase trong C ++, nơi họ đang kiểm soát bộ nhớ chính xác và có không gian rất hạn chế. Không phải nói Kiến trúc FP và hướng dịch vụ là những con thú và không nên xem xét phần cứng. Nhưng họ đặt khả năng liên tục thay đổi, được duy trì, có kích thước dữ liệu thay đổi và các khía cạnh khác là ưu tiên. Trong trò chơi video và AI máy, bạn điều khiển tín hiệu và dữ liệu rất chính xác.
Lưu ý 2 : Mô hình miền không có Hành vi đa hình, cũng không có Phụ thuộc bên ngoài. Họ là "Cô lập". Điều đó không có nghĩa là họ phải thiếu máu 100%. Họ có thể có rất nhiều logic liên quan đến việc xây dựng và thay đổi tài sản có thể thay đổi của họ, nếu điều đó được áp dụng. Xem DDD "Đối tượng giá trị" và các thực thể của Eric Evans và Mark Seemann.
Lưu ý 3 : Linq và Lambda rất phổ biến. Nhưng khi người dùng tạo một chức năng mới, họ hiếm khi sử dụng Func hoặc Callable làm tham số, trong khi ở FP, thật lạ khi thấy một ứng dụng không có các chức năng theo mẫu đó.
Lưu ý 4 : Không nhầm lẫn Đa hình với Kế thừa. Một CatModel có thể kế thừa AnimalBase để xác định Thuộc tính nào mà Động vật thường có. Nhưng như tôi chỉ ra, những Người mẫu như thế này là Mùi Mã . Nếu bạn thấy mẫu này, bạn có thể xem xét phá vỡ nó và biến nó thành dữ liệu.
Lưu ý 5 : Hàm thuần có thể (và làm) chấp nhận hàm làm tham số. Hàm đến có thể không tinh khiết, nhưng có thể là thuần túy. Đối với mục đích thử nghiệm, nó sẽ luôn luôn tinh khiết. Nhưng trong sản xuất, mặc dù được coi là nguyên chất, nhưng nó có thể chứa tác dụng phụ. Điều đó không thay đổi thực tế rằng hàm thuần túy là thuần túy. Mặc dù chức năng tham số có thể không tinh khiết. Không khó hiểu! : D