Các đối số có tên thay thế mô hình xây dựng?


20

Khi sử dụng ngôn ngữ hỗ trợ các đối số được đặt tên và tùy chọn, mẫu xây dựng không còn sử dụng thực tế nữa?

Người xây dựng:

new Builder(requiredA, requiredB).setOptionalA("optional").Build();

Đối số tùy chọn / được đặt tên:

new Object(requiredA, requiredB, optionalA: "optional");

3
Làm thế nào để bạn xử lý 20 đối số tùy chọn? Không có vấn đề gì mà Builder cần giải quyết cho đến khi nó trở nên lớn. Tại thời điểm bạn mô tả ở đây, bạn có hai nhà xây dựng (và tôi sẽ không xây dựng Trình tạo cho vấn đề nhỏ đó).

1
Ngay cả với các đối số tùy chọn - nếu hàm tạo có nhiều hơn 2 đối số, tôi vẫn ưu tiên sử dụng một đối tượng giá trị để đóng gói cấu hình. Điều tương tự cũng xảy ra đối với các giao diện và trình tạo chất lỏng: Bất kỳ thứ gì lớn hơn 3 sẽ được thay thế bằng một đối tượng giá trị.
Thomas Junk

Câu trả lời:


21

Nhà xây dựng là hữu ích nhất khi đối tượng của bạn cần rất nhiều đối số / phụ thuộc là hữu ích hoặc bạn muốn cho phép nhiều cách khác nhau để xây dựng đối tượng.

Ngoài đỉnh đầu, tôi có thể tưởng tượng ai đó có thể muốn "xây dựng" các vật thể trong một trò chơi 3D như thế này:

// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
                          .syncWithOtherPlayers(serverIP)
                          .compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
                          .makeDestructibleRigidBody(health, weight)
                          ...

Tôi cho rằng ví dụ này dễ đọc hơn với các phương thức xây dựng mà tôi đã tạo ra ngay bây giờ so với các tham số tùy chọn:

new Object(x, y, z, meshType: MESH.BLENDER,
                    meshPath: "./meshes/foo",
                    serverToSyncWith: serverIP,
                    vertexShader: "./shaders/foo.vert",
                    physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
                    health: health,
                    weight: weight)
                    ...

Cụ thể, thông tin được ngụ ý bởi các tên phương thức của trình xây dựng phải được thay thế bằng nhiều tham số hơn và việc quên một tham số trong một nhóm các tham số liên quan chặt chẽ sẽ dễ dàng hơn nhiều. Trong thực tế, shader mảnh bị thiếu, nhưng bạn sẽ không nhận ra điều đó trừ khi bạn biết tìm nó.


Tất nhiên, nếu đối tượng của bạn chỉ mất một đến năm đối số để xây dựng, thì không cần phải có mẫu xây dựng liên quan, cho dù bạn có tên / tham số tùy chọn hay không.


Tôi không mua đối số của bạn. Nếu tên phương thức của trình xây dựng rất tuyệt vời, bạn có thể sử dụng chúng cho tên tham số. Nếu các tham số có liên quan chặt chẽ, hãy đặt chúng vào một hàm tạo đối tượng nhỏ.
dùng949300

@ user949300 Tôi nghĩ rằng bạn đã bỏ lỡ phần quan trọng, đó là các phương thức xây dựng ở đây mô tả mối quan hệ giữa các tham số bị mất nếu bạn chỉ có một loạt các tham số tùy chọn. Trong ví dụ về trình tạo của Ixrec, "sức khỏe" và "trọng lượng" rõ ràng là một phần logic của cài đặt cơ thể có thể phá hủy, nhưng mối quan hệ đó sẽ bị mất trong phiên bản đối số tùy chọn.
Jules

1
không nếu một trong các tham số tùy chọn là (cơ thể:
Dest DestibleRigidBody

@Jules. Những gì Weyland nói - làm cho một nhà xây dựng có tên nhỏ cho trọng lượng và chiều cao.
dùng949300

8

Ngoài những gì Ixrec đã nói, các hàm tạo hoặc phương thức có tên là tham số sẽ không cho phép bạn đưa đối tượng của mình ở trạng thái được xây dựng trong đó nó vẫn có thể được sửa đổi trước khi xây dựng nó. Đây là nét đẹp của Builder, nơi bạn có thể ủy thác các phần xây dựng của nó cho các phương thức hoặc lớp khác nhau:

var myThingBuilder = new ThingBuilder("table");
myThingBuilder.setAttribute(Attributes.Legs, 4);

inventoryManager.setPrices(myThingBuilder);

// inventory manager
var availableCheapestMaterial = getMaterial();
myThingBuilder.setMaterial(availableCheapestMaterial);

Về cơ bản, bạn cũng có thể ném trình xây dựng của mình xung quanh hệ thống của mình cho đến khi nó sẵn sàng xây dựng đối tượng cuối cùng, cho phép bạn giảm lượng kiến ​​thức mà người xây dựng-người tiêu dùng của bạn cần phải có.


Tôi không hiểu đoạn cuối của bạn. Nếu bạn "ném trình xây dựng của mình xung quanh hệ thống cho đến khi nó sẵn sàng", nó có quá nhiều kiến thức về hệ thống. ThingBuilder của bạn biết về Thuộc tính, được InventoryManager sửa đổi một cách bí ẩn và biết về Vật liệu. Đừng xem làm thế nào mà giảm kiến ​​thức.
dùng949300

@ user949300 Hãy nghĩ về nó sẽ như thế nào nếu không có người xây dựng đi qua hệ thống. Bạn sẽ bị buộc phải có một lớp học với yếu tố fan hâm mộ khổng lồ, và điều đó chỉ cần thiết để xây dựng Điều. (Tất nhiên, giả sử lớp của bạn không tập trung tất cả kiến ​​thức, đây là điều chúng tôi muốn tránh ngay từ đầu.) Bây giờ, nếu lớp này có bất kỳ trách nhiệm nào khác, bạn đang tạo một lớp lớn, phá vỡ S trong RẮN . Nếu đó là trách nhiệm duy nhất, bạn đang tự biến mình thành ThingBuilder.
Alpha

1

Nó phụ thuộc vào những gì bạn đang làm với người xây dựng.

Nếu bạn đang sử dụng trình xây dựng chỉ để đặt (và thay đổi) các thuộc tính đối tượng và tạo đối tượng (trì hoãn), thì nó có thể được thay thế bằng các tham số đã đặt tên.

Thay thế trình xây dựng, bạn có thể có sự cân bằng về khả năng đọc / sử dụng mà @Ixrec đã đề cập (hoặc có thể không có nó, điều này phụ thuộc vào những gì bạn đang làm với trình xây dựng).

Tuy nhiên, nếu trình xây dựng của bạn không chỉ giữ các thuộc tính và mỗi bước xây dựng liên quan đến logic, thì nó không thể được thay thế.

MockBuilder là một ví dụ trong đó không thể thay thế bằng params được đặt tên. Từ trang:

Logic trên các bước tạo không thể được thay thế bằng params được đặt tên


-5

Mẫu xây dựng là rất cần thiết khi làm việc với các đối tượng bất biến. Có rất nhiều lợi ích khi làm việc với các đối tượng không thay đổi, đặc biệt là làm cho chương trình của bạn trở nên mạnh mẽ hơn khi thực thi trong một môi trường đồng thời (ví dụ: các luồng)


3
Có, Nhà xây dựng rất tuyệt khi làm việc với các đối tượng bất biến phức tạp (hoặc thậm chí là các đối tượng có thể thay đổi - bạn cần đảm bảo rằng đối tượng ở trạng thái nhất quán trước khi có thể sử dụng). Điều đó nói rằng, new Integer(42), new BigDecimal("42.000")new String("foobar")đều là những nhà xây dựng để immutables rằng ... tốt, một người thợ xây sẽ là phức tạp vô cho những trường hợp này. Vì vậy, một người xây dựng không cần thiết để làm việc với bất biến khi các nhà xây dựng cũng có thể làm việc tốt như vậy.

Có, một constructor có thể được sử dụng với các đối tượng bất biến, điều đó không bị từ chối. Nhưng câu hỏi ban đầu là liệu mẫu Builder có sử dụng thực tế nào ngoài các đối số tùy chọn không và câu trả lời của tôi là để làm rõ điều này.
codedabbler

2
Câu hỏi ban đầu không nói về những vật bất biến. Đó là hỏi về các tham số được đặt tên và mối quan hệ với chúng với Nhà xây dựng. Câu trả lời của bạn là về người xây dựng và mối quan hệ của nó với các đối tượng bất biến. Tôi có một thời gian khó khăn để xem câu trả lời của bạn trả lời câu hỏi như thế nào.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.