Làm cách nào để xây dựng một hệ thống có tất cả những điều sau đây :
- Sử dụng các hàm thuần túy với các đối tượng bất biến.
- Chỉ truyền vào dữ liệu hàm mà hàm cần, không còn nữa (tức là không có đối tượng trạng thái ứng dụng lớn)
- Tránh có quá nhiều đối số cho các chức năng.
- Tránh phải xây dựng các đối tượng mới chỉ nhằm mục đích đóng gói và giải nén các tham số cho các chức năng, đơn giản là để tránh quá nhiều tham số được truyền cho các chức năng. Nếu tôi sẽ đóng gói nhiều mục vào một hàm dưới dạng một đối tượng, tôi muốn đối tượng đó là chủ sở hữu của dữ liệu đó, không phải là thứ được xây dựng tạm thời
Dường như với tôi rằng đơn vị Nhà nước phá vỡ quy tắc số 2, mặc dù điều đó không rõ ràng bởi vì nó được dệt qua đơn vị.
Tôi có cảm giác tôi cần sử dụng Lenses bằng cách nào đó, nhưng rất ít được viết về nó cho các ngôn ngữ phi chức năng.
Lý lịch
Như một bài tập, tôi đang chuyển đổi một trong những ứng dụng hiện có của mình từ kiểu hướng đối tượng sang kiểu chức năng. Điều đầu tiên tôi đang cố gắng làm là tạo ra càng nhiều lõi bên trong của ứng dụng càng tốt.
Một điều tôi đã nghe là làm thế nào để quản lý "Trạng thái" bằng ngôn ngữ thuần chức năng, và đây là điều tôi tin là được thực hiện bởi các đơn vị Nhà nước, đó là về mặt logic, bạn gọi là một hàm thuần túy, "chuyển qua trạng thái của thế giới như nó là ", sau đó khi hàm trả về, nó sẽ trả về cho bạn trạng thái của thế giới khi nó thay đổi.
Để minh họa, cách bạn có thể thực hiện "thế giới xin chào" theo cách hoàn toàn có chức năng giống như, bạn chuyển qua chương trình trạng thái của màn hình và nhận lại trạng thái của màn hình với "thế giới xin chào" được in trên đó. Vì vậy, về mặt kỹ thuật, bạn đang thực hiện một cuộc gọi đến một chức năng thuần túy và không có tác dụng phụ.
Dựa vào đó, tôi đã duyệt qua ứng dụng của mình và: 1. Đầu tiên đặt tất cả trạng thái ứng dụng của tôi vào một đối tượng toàn cầu duy nhất (GameState) 2. Thứ hai, tôi đã biến GameState thành bất biến. Bạn không thể thay đổi nó. Nếu bạn cần một sự thay đổi, bạn phải xây dựng một cái mới. Tôi đã làm điều này bằng cách thêm một hàm tạo sao chép, tùy ý lấy một hoặc nhiều trường đã thay đổi. 3. Với mỗi ứng dụng, tôi chuyển vào GameState dưới dạng tham số. Trong chức năng, sau khi thực hiện những gì nó sẽ làm, nó tạo ra một GameState mới và trả về nó.
Làm cách nào tôi có lõi chức năng thuần túy và một vòng lặp ở bên ngoài cung cấp GameState đó vào vòng lặp công việc chính của ứng dụng.
Câu hỏi của tôi:
Bây giờ, vấn đề của tôi là, GameState có khoảng 15 đối tượng bất biến khác nhau. Nhiều chức năng ở mức thấp nhất chỉ hoạt động trên một vài trong số các đối tượng đó, chẳng hạn như giữ điểm. Vì vậy, giả sử tôi có một hàm tính điểm. Ngày nay, GameState được chuyển đến chức năng này, điều chỉnh điểm số bằng cách tạo GameState mới với điểm số mới.
Một cái gì đó về điều đó có vẻ sai. Hàm không cần toàn bộ GameState. Nó chỉ cần đối tượng Điểm. Vì vậy, tôi đã cập nhật nó để vượt qua Điểm và chỉ trả về Điểm.
Điều đó dường như có ý nghĩa, vì vậy tôi đã đi xa hơn với các chức năng khác. Một số chức năng sẽ yêu cầu tôi chuyển 2, 3 hoặc 4 tham số từ GameState, nhưng khi tôi sử dụng mô hình cho đến tận lõi ngoài của ứng dụng, tôi sẽ chuyển qua trạng thái ứng dụng ngày càng nhiều. Giống như, ở đầu vòng lặp công việc, tôi sẽ gọi một phương thức, sẽ gọi phương thức đó sẽ gọi một phương thức, v.v., tất cả các cách để tính điểm. Điều đó có nghĩa là điểm số hiện tại được chuyển qua tất cả các lớp đó chỉ vì một hàm ở dưới cùng sẽ tính điểm.
Vì vậy, bây giờ tôi có chức năng với đôi khi hàng chục tham số. Tôi có thể đặt các tham số đó vào một đối tượng để giảm số lượng tham số, nhưng sau đó tôi muốn lớp đó là vị trí chính của trạng thái ứng dụng trạng thái, thay vì một đối tượng được xây dựng đơn giản tại thời điểm cuộc gọi đơn giản để tránh vượt qua trong nhiều tham số, và sau đó giải nén chúng.
Vì vậy, bây giờ tôi tự hỏi nếu vấn đề tôi có là các chức năng của tôi được lồng quá sâu. Đây là kết quả của việc muốn có các hàm nhỏ, vì vậy tôi tái cấu trúc khi một hàm trở nên lớn và chia nó thành nhiều hàm nhỏ hơn. Nhưng làm điều đó tạo ra một hệ thống phân cấp sâu hơn và bất cứ thứ gì được truyền vào các hàm bên trong cần phải được truyền vào hàm bên ngoài ngay cả khi hàm ngoài không hoạt động trực tiếp trên các đối tượng đó.
Có vẻ như chỉ cần vượt qua trong GameState trên đường đi đã tránh được vấn đề này. Nhưng tôi trở lại vấn đề ban đầu là chuyển nhiều thông tin đến một chức năng hơn chức năng cần.