Làm cách nào tôi có thể quảng bá việc sử dụng mẫu Builder trong nhóm của mình?


22

Codebase của chúng tôi là những lập trình viên cũ và mới, giống như tôi, nhanh chóng học cách làm theo cách nó được thực hiện vì mục đích đồng nhất. Nghĩ rằng chúng ta phải bắt đầu ở đâu đó, tôi đã tự mình lấy nó để cấu trúc lại một lớp chủ dữ liệu như sau:

  • Đã xóa các phương thức setter và thực hiện tất cả các trường final(tôi lấy " finallà tốt" theo tiên đề). Các setters chỉ được sử dụng trong hàm tạo, vì vậy nó không có tác dụng phụ.
  • Giới thiệu một lớp Builder

Lớp Builder là cần thiết bởi vì hàm tạo (là thứ đã nhắc tái cấu trúc ở vị trí đầu tiên) kéo dài khoảng 3 dòng mã. Nó có rất nhiều thông số.

Như may mắn có được, một đồng đội của tôi đã làm việc trên một mô-đun khác và tình cờ cần các setters, bởi vì các giá trị anh ta yêu cầu đã có sẵn tại các điểm khác nhau trong dòng chảy. Do đó, mã trông như thế này:

public void foo(Bar bar){
    //do stuff
    bar.setA(stuff);
    //do more stuff
    bar.setB(moreStuff);
}

Tôi lập luận rằng anh ta nên sử dụng trình xây dựng thay thế, bởi vì việc loại bỏ setters cho phép các trường không thay đổi (họ đã nghe tôi nói về sự bất biến trước đây) và cũng vì các nhà xây dựng cho phép tạo đối tượng được giao dịch. Tôi đã phác thảo mã giả sau đây:

public void foo(Bar bar){
    try{
        bar.setA(a);
        //enter exception-throwing stuff
        bar.setB(b);
    }catch(){}
}

Nếu ngoại lệ đó kích hoạt, barsẽ có dữ liệu bị hỏng, điều mà có thể tránh được với một người xây dựng:

public Bar foo(){
        Builder builder=new Builder();
    try{
        builder.setA(a);
        //dangerous stuff;
        builder.setB(b);
        //more dangerous stuff
        builder.setC(c);
        return builder.build();
    }catch(){}
    return null;
}

Các đồng đội của tôi đã vặn lại rằng ngoại lệ trong câu hỏi sẽ không bao giờ khai hỏa, điều đó đủ công bằng cho khu vực mã cụ thể đó, nhưng tôi tin rằng đang thiếu rừng cho cây.

Sự thỏa hiệp là trở lại giải pháp cũ, cụ thể là sử dụng một hàm tạo không có tham số và đặt mọi thứ với setters khi cần. Lý do là giải pháp này tuân theo nguyên tắc KISS, mà tôi vi phạm.

Tôi mới đến công ty này (chưa đầy 6 tháng) và hoàn toàn biết rằng tôi đã mất cái này. Câu hỏi tôi có là:

  • Có một đối số khác cho việc sử dụng Nhà xây dựng thay vì "cách cũ" không?
  • Là sự thay đổi tôi đề xuất thậm chí thực sự có giá trị nó?

nhưng thực sự,

  • Bạn có bất cứ lời khuyên nào để trình bày tốt hơn những lập luận như vậy khi ủng hộ việc thử một cái gì đó mới không?

6
Builder sẽ cần thiết lập giá trị nào đó. Vì vậy, nó không giải quyết vấn đề cơ bản.
Amy Blankenship

3
Lý do những thứ (nhiều hơn / nguy hiểm / ném ngoại lệ) không thể được chuyển đến trước gọi đến setA?
yatima2975

2
Chỉ có 3 dòng tham số constructor? Điều đó không tệ.
pjc50

7
Trong bất kỳ thiết kế phần mềm nào, luôn có sự đánh đổi giữa độ phức tạp và tách rời. Mặc dù tôi nghĩ rằng tôi đồng ý với cá nhân bạn rằng nhà xây dựng là một giải pháp tốt ở đây, đồng nghiệp của bạn có quyền do dự với lý do KISS. Tôi duy trì phần mềm quá phức tạp đến mức đáng kinh ngạc, và một phần lý do là vì mỗi lần thuê mới đều lừa đảo và nói "Điều này thật ngu ngốc, tôi sẽ làm điều mới này theo cách của mình", do đó chúng tôi có 5 khung để lên lịch công việc nền và 8 phương thức để truy vấn cơ sở dữ liệu. Tất cả đều tốt trong chừng mực và không có câu trả lời đúng rõ ràng trong trường hợp như thế này.
Brandon

3
KISS là một khái niệm mờ nhạt, các đối tượng có thể sửa đổi là nguồn gốc của sự phức tạp được các nhà phát triển đánh giá thấp, chúng làm cho đa luồng, gỡ lỗi và xử lý ngoại lệ khó khăn hơn nhiều so với bất biến. Đối tượng là hợp lệ hoặc một ngoại lệ được tạo ra tại công trình (nơi nào tốt hơn để bắt ngoại lệ đó?).
Alessandro Teruzzi

Câu trả lời:


46

Nghĩ rằng chúng ta phải bắt đầu ở đâu đó, tôi đã tự mình lấy nó để cấu trúc lại một lớp giữ dữ liệu

Đây là nơi nó đã sai - bạn đã thực hiện một thay đổi kiến ​​trúc lớn cho cơ sở mã hóa sao cho nó trở nên rất khác so với những gì được mong đợi. Bạn làm đồng nghiệp ngạc nhiên. Bất ngờ chỉ tốt nếu liên quan đến một bữa tiệc, nguyên tắc ít bất ngờ nhất là vàng (ngay cả khi liên quan đến các bữa tiệc, thì tôi cũng biết mặc quần lót sạch!)

Bây giờ nếu bạn nghĩ rằng sự thay đổi này là đáng giá, thì tốt hơn hết là phác thảo mã giả cho thấy sự thay đổi và trình bày nó với các đồng nghiệp của bạn (hoặc ít nhất là bất cứ ai có vai trò gần nhất với kiến ​​trúc sư) và xem họ nghĩ gì trước khi làm bất cứ điều gì. Như nó là, bạn đã đi lừa đảo, nghĩ rằng toàn bộ cơ sở mã là của bạn để chơi với như bạn nghĩ phù hợp. Một người chơi trong đội, không phải là một người chơi trong đội!

Tôi có thể hơi khó chịu với bạn, nhưng tôi đã ở một nơi đối diện: kiểm tra một số mã và nghĩ rằng "WTF đã xảy ra ở đây?!", Chỉ để tìm chàng trai mới (gần như luôn luôn là chàng trai mới) quyết định thay đổi vô số thứ dựa trên những gì anh ta nghĩ là "đúng cách". Các ốc vít với lịch sử SCM cũng là một vấn đề lớn khác.


7
"Bất ngờ chỉ tốt nếu nó liên quan đến một bữa tiệc", điều đó không thực sự đúng với mọi người !! Tôi muốn dừng lại nói chuyện với bất kỳ người bạn như vậy gọi là ném cho tôi một ngạc nhiên bất cứ điều gì , đặc biệt một bên . Với mọi người . Ừ
Darkhogg

3
Vì vậy, nếu mọi mô hình tái cấu trúc và thiết kế, hoặc mọi quyết định như "Tôi có sử dụng accessor và mutator ở đây hay mẫu xây dựng không?" phải được sự chấp thuận của một nhóm, làm thế nào các nhà phát triển sẽ cảm thấy được trao quyền để làm điều đúng đắn? Làm thế nào bạn sẽ thực hiện thay đổi suy nghĩ về phía trước nếu mọi thứ phải được thiết kế bởi một ủy ban. Tôi đã ở trong đôi giày của OP trước khi tôi bị mắc kẹt phải duy trì mã vô nghĩa (với tư cách là người mới) mà mọi người khác đều sợ thay đổi vì nó phù hợp . Tính nhất quán là tốt và tất cả, nhưng không phải chi phí cải thiện.
Brandon

11
@Brandon không, nhưng mọi thay đổi rộng lớn sẽ ảnh hưởng đến họ nên. Nếu bạn phải sửa một lỗi, nó chỉ là một đoạn mã khác - không có vấn đề gì lớn. Nếu bạn đưa ra quyết định ảnh hưởng đến mọi người khác, thì ít nhất hãy lịch sự nói cho họ biết bạn đang làm gì. Bạn có thể nhận được sự đồng ý từ nhóm để thay đổi mã vô nghĩa của mình và sau đó các thay đổi của bạn trở thành tính nhất quán mới. Bạn chỉ cần nói chuyện với các đồng nghiệp của bạn. Không có gì xấu khi nói "Tôi sẽ thay đổi mô hình người truy cập nhảm nhí mà tất cả chúng ta đều ghét" và nghe các đồng nghiệp của bạn trả lời với "vâng, đã đến lúc ai đó xử lý vấn đề đó"
gbjbaanb

13
@Brandon có một câu nói: "Con đường đến địa ngục được lát bằng những ý định tốt". Tính nhất quán không chỉ là tốt , nó là cần thiết ! Hãy tưởng tượng bạn đang cố gắng quản lý một nhóm các nhà phát triển quản lý chung 20 ứng dụng, mỗi ứng dụng được viết theo một phong cách và / hoặc kiến ​​trúc khác nhau bởi vì sở thích, công nghệ hiện tại, xu hướng, v.v. đã đưa ra những gì tốt nhất vào thời điểm đó. Làm cho nhóm đồng ý rằng một cái gì đó nên thay đổi có thể là sự khác biệt giữa anh chàng mới được chấp nhận vì họ đã khắc phục một vấn đề lâu dài và bị sa thải vì đi ung dung với những gì bạn nghĩ là tốt nhất.
DrewJordan

3
@Brandon - Nếu bạn định lừa đảo và sửa một cái gì đó "mà mọi người đồng ý là sai" thì có lẽ bạn sẽ thành công hơn bằng cách chọn một cái gì đó "mọi người đồng ý là sai" thay vì chọn một cái gì đó tốt nhất có các trại khác nhau chủ đề, như bất biến. Một thiết kế / kiến ​​trúc tốt làm cho chi phí cao bất biến vì thực tế không có phần thưởng. Vì vậy, trừ khi nhóm của bạn gặp sự cố vì họ đang sử dụng setters thì bạn hoàn toàn không khắc phục vấn đề. OTOH, nếu đây là nguồn gây ra lỗi thường xuyên thì có vẻ như sự phân nhánh biện minh cho quyết định của đội.
Dunk

21

Như may mắn có được, một đồng đội của tôi đã làm việc trên một mô-đun khác và tình cờ cần các setters, bởi vì các giá trị anh ta yêu cầu đã có sẵn tại các điểm khác nhau trong dòng chảy.

Theo mô tả, tôi không thấy những gì làm cho mã yêu cầu setters. Tôi có thể không biết đủ về ca sử dụng, nhưng tại sao không đợi cho đến khi tất cả các tham số được biết trước khi khởi tạo đối tượng?

Cách khác, nếu tình huống yêu cầu setters: cung cấp một cách để đóng băng mã của bạn để setters đó đưa ra lỗi xác nhận (còn gọi là lỗi lập trình viên) nếu bạn cố gắng sửa đổi các trường sau khi đối tượng đã sẵn sàng.

Tôi nghĩ loại bỏ các setters và sử dụng cuối cùng là cách làm "đúng đắn", cũng như thực thi sự bất biến, nhưng nó có thực sự là những gì bạn nên dành thời gian với?

Mẹo chung

Cũ = xấu, mới = tốt, theo cách của tôi, theo cách của bạn ... loại thảo luận này không mang tính xây dựng.

Hiện tại, cách đối tượng của bạn được sử dụng tuân theo một số quy tắc ngầm. Đây là một phần của đặc tả không được đặt mã của mã của bạn và nhóm của bạn có thể nghĩ rằng không có nhiều rủi ro cho các phần khác của mã sử dụng sai. Những gì bạn muốn làm ở đây là làm cho quy tắc rõ ràng hơn với Trình kiểm tra thời gian xây dựng và biên dịch.

Theo một cách nào đó, tái cấu trúc mã được gắn với lý thuyết Cửa sổ vỡ : bạn cảm thấy đúng khi khắc phục bất kỳ vấn đề nào khi bạn thấy nó (hoặc ghi chú cho một cuộc họp "cải thiện chất lượng" sau này) để mã luôn hoạt động dễ chịu, là an toàn và sạch sẽ. Mặc dù vậy, bạn và nhóm của bạn không có cùng một ý tưởng về những gì "đủ tốt". Những gì bạn thấy là một cơ hội để đóng góp và làm cho mã tốt hơn, với đức tin tốt, có thể được nhìn thấy khác với nhóm hiện có.

Nhân tiện, nhóm của bạn không nên được coi là nhất thiết phải chịu quán tính, thói quen xấu, thiếu giáo dục, ... điều tồi tệ nhất bạn có thể làm là chiếu hình ảnh của một người biết tất cả những người ở đó để chỉ cho họ Cách viết mã. Ví dụ, tính bất biến không phải là một cái gì đó mới , đồng nghiệp của bạn có thể đã đọc về nó nhưng chỉ vì chủ đề này đang trở nên phổ biến trong blog không đủ để thuyết phục họ dành thời gian thay đổi mã của họ.

Rốt cuộc, có vô số cách để cải thiện một cơ sở mã hiện có, nhưng nó tốn thời gian và tiền bạc. Tôi có thể nhìn vào mã của bạn, gọi nó là "cũ" và tìm những thứ cần biết. Ví dụ: không có đặc tả hình thức, chưa đủ khẳng định, có lẽ không đủ ý kiến hoặc bài kiểm tra, không đủ bảo hiểm mã, thuật toán unoptimal, quá nhiều bộ nhớ sử dụng, không sử dụng mô hình "tốt nhất" có thể thiết kế trong từng trường hợp, vv quảng cáo nauseam . Nhưng đối với hầu hết các điểm mà tôi sẽ nêu ra, bạn sẽ nghĩ: không sao, mã của tôi hoạt động, không cần phải dành nhiều thời gian hơn cho nó.

Có thể nhóm của bạn nghĩ rằng những gì bạn đề xuất đã qua thời điểm lợi nhuận giảm dần. Ngay cả khi bạn đã tìm thấy một trường hợp thực tế của một lỗi do loại ví dụ bạn hiển thị (với ngoại lệ), họ có thể sẽ chỉ sửa nó một lần và không muốn cấu trúc lại mã.

Vì vậy, câu hỏi là về cách sử dụng thời gian và năng lượng của bạn, cho rằng chúng bị hạn chế ? Có những thay đổi liên tục được thực hiện cho phần mềm nhưng nhìn chung ý tưởng của bạn bắt đầu với điểm số âm cho đến khi bạn có thể cung cấp các lập luận tốt cho nó. Ngay cả khi bạn đúng về lợi ích, bản thân nó không phải là một lý lẽ đủ, bởi vì nó sẽ kết thúc trong giỏ " Rất vui có, một ngày ... ".

Khi bạn trình bày lập luận của mình, bạn phải thực hiện một số kiểm tra "tỉnh táo": bạn đang cố gắng bán ý tưởng hay chính mình? Điều gì nếu một người khác trình bày điều này cho nhóm? Bạn sẽ tìm thấy một số sai sót trong lý luận của họ? Bạn đang cố gắng áp dụng một số thực tiễn tốt nhất chung hay bạn đã tính đến các chi tiết cụ thể của mã của bạn?

Sau đó, bạn chắc chắn sẽ không xuất hiện như thể nếu bạn đang cố gắng sửa chữa những "lỗi lầm" trong quá khứ của đội bạn. Nó giúp thể hiện rằng bạn không phải là ý tưởng của bạn nhưng có thể đưa ra phản hồi hợp lý. Bạn càng làm điều này, các đề xuất của bạn sẽ càng có cơ hội được theo dõi.


Bạn hoàn toàn đúng. Một sự phản đối nhỏ: Đó không phải là "cách cũ" so với "cách mới, siêu mới tuyệt vời của tôi". Tôi hoàn toàn biết rằng tôi có thể đang nói vô nghĩa. Vấn đề của tôi là bằng cách tiếp tục sử dụng phần mềm thực hành, mọi người trong công ty đều thấy khủng khiếp, tôi có thể trì trệ với tư cách là một nhà phát triển. Vì vậy, tôi cố gắng giới thiệu một số thay đổi, ngay cả khi tôi sai. (Nhiệm vụ được kích hoạt bởi một yêu cầu cấu trúc lại một lớp liên quan)
rath

@rath Không có cơ sở mã mới đang được phát triển?
biziclop

@biziclop Có các mô-đun mới được cắm vào cơ sở mã cũ. Tôi đã làm việc trên một gần đây. Những ngày hạnh phúc.
Rath

5
@rath Có lẽ bạn cần một dự án cá nhân mà bạn có thể làm việc trong thời gian của mình, nơi bạn có thể thúc đẩy sự phát triển của chính mình? Tôi cũng không bị thuyết phục bởi đối số mẫu "Builder" của bạn; getters / setters dường như là một giải pháp hoàn toàn OK dựa trên thông tin bạn đã cung cấp. Hãy nhớ rằng bạn có trách nhiệm với chủ nhân và nhóm của bạn; ưu tiên của bạn là đảm bảo rằng bất kỳ công việc bạn làm đều có lợi cho những người bạn có trách nhiệm.
Ben Cottrell

@rath Chà, ngay cả khi bạn không ở trong mã "cũ / mới", điều quan trọng là cách cảm nhận của người nhận, đặc biệt là nếu họ có quyền quyết định nhiều hơn bạn. Có vẻ như - nếu bạn muốn giới thiệu thay đổi vì lợi ích của riêng bạn chứ không phải cho sản phẩm bạn phát triển. Nếu mọi người trong công ty thấy việc thực hành thật kinh khủng, cuối cùng nó sẽ thay đổi, nhưng điều này có vẻ không phải là ưu tiên.
coredump

17

Làm cách nào tôi có thể quảng bá việc sử dụng mẫu Builder trong nhóm của mình?

Bạn không.

Nếu constructor của bạn có 3 dòng tham số, thì nó quá lớn và quá phức tạp. Không có mẫu thiết kế sẽ khắc phục điều đó.

Nếu bạn có một lớp có dữ liệu có sẵn tại các thời điểm khác nhau, thì đó phải là hai đối tượng khác nhau hoặc người tiêu dùng của bạn nên tổng hợp các thành phần và sau đó xây dựng đối tượng. Họ không cần một người xây dựng để làm điều đó.


Đó là một người giữ dữ liệu lớn của Strings và các nguyên thủy khác. Không có logic ở bất cứ đâu, thậm chí không kiểm tra nulls, v.v. Vì vậy, nó chỉ có kích thước tuyệt đối, không phức tạp mỗi se. Tôi nghĩ rằng làm một cái gì đó như builder.addA(a).addB(b); /*...*/ return builder.addC(c).build();sẽ dễ dàng hơn nhiều trên mắt.
Rath

8
@rath: Đó là một người giữ dữ liệu lớn của Chuỗi và các nguyên thủy khác. => sau đó bạn có vấn đề khác, hy vọng không ai quan tâm nếu trường e-mail tình cờ được chỉ định với địa chỉ bài đăng của anh chàng ...
Matthieu M.

@MatthieuM. Một vấn đề tại một thời điểm tôi cho rằng :)
Rath

@rath - Có vẻ như việc kết hợp một sơ đồ kiểm tra xác thực tốt sẽ hữu ích hơn và dễ dàng nhận được hơn là cố gắng tìm ra cách xáo trộn mẫu xây dựng vào mã đã có. Một nơi khác bạn nói bạn muốn tốt hơn cho chính mình. Học cách đạt được lợi ích tối đa cho nỗ lực và hậu quả ít nhất chắc chắn là một thuộc tính nên được phát triển.
Dunk

1
Tôi có rất nhiều nhà xây dựng với nhiều tham số hơn thế. Cần thiết trong các mẫu IoC. Khái quát xấu trong câu trả lời này.
djechlin

16

Bạn có vẻ tập trung vào việc đúng hơn là làm việc tốt với người khác. Tệ hơn nữa, bạn nhận ra rằng những gì bạn đang làm là một cuộc đấu tranh quyền lực và chưa nghĩ đến việc mọi thứ có thể cảm thấy như thế nào đối với những người có kinh nghiệm và thẩm quyền mà bạn đang thách thức.

Đảo ngược mà.

Tập trung làm việc với người khác. Khung suy nghĩ của bạn như đề xuất và ý tưởng. Yêu cầu THEM nói qua các ý tưởng CỦA HỌ trước khi đặt câu hỏi để khiến họ nghĩ về bạn. Tránh đối đầu trực tiếp, và sẵn sàng hướng ngoại để chấp nhận rằng tiếp tục làm mọi thứ theo cách của nhóm (hiện tại) sẽ hiệu quả hơn là chiến đấu trong một trận chiến khó khăn để thay đổi nhóm. (Mặc dù mang mọi thứ trở lại.) Hãy làm việc với bạn một niềm vui.

Làm điều này một cách nhất quán và bạn sẽ tạo ra ít xung đột hơn và tìm thấy nhiều ý tưởng của bạn được người khác chấp nhận. Tất cả chúng ta đều bị ảo tưởng rằng lập luận logic hoàn hảo sẽ làm cho người khác kinh ngạc và giành chiến thắng trong ngày. Và nếu nó không hoạt động theo cách đó, chúng tôi nghĩ rằng nó nên .

Nhưng đó là xung đột trực tiếp với thực tế. Hầu hết các đối số bị mất trước khi điểm logic đầu tiên được thực hiện. Ngay cả trong số những người có mục đích logic, tâm lý hơn hẳn lý do. Thuyết phục mọi người là về việc vượt qua các rào cản tâm lý để được lắng nghe đúng đắn, và không phải là có logic hoàn hảo.


2
Frame your thoughts as suggestions and ideas. Get THEM to talk through THEIR ideas before asking questions to make them think about yoursTuy nhiên, +1 cho điều đó
rath

2
@rath Hãy nhớ rằng những người khác có thể không đọc từ sách của bạn. Có thể người mà bạn đang thảo luận coi đó là cuộc đối đầu, có thể phản tác dụng với mục tiêu của bạn.
Iker

2
@rath: Không có đúng hay sai. Chỉ cần đánh đổi. Và thường xuyên hơn không phải là sự đánh đổi liên quan đến nhiều hơn một mình mã.
Marjan Venema

1
@ Dunk Tất cả những gì tồn tại là sự đánh đổi. Chúng tôi gọi họ là đúng hoặc sai khi sự đánh đổi là rõ ràng và rõ ràng ở một bên. Tuy nhiên, nhận ra khi nào sắc thái đó trở nên mơ hồ sẽ dễ dàng hơn nếu chúng ta tập trung vào chúng là sự đánh đổi ngay từ đầu.
btilly

2
Không có một chương trình "thực hành tốt nhất" nào mà tôi biết mà không có ngoại lệ khi nó không tốt nhất. Đôi khi thật khó để tìm thấy những ngoại lệ đó, nhưng chúng luôn tồn tại.
btilly

11

Có một đối số khác cho việc sử dụng Nhà xây dựng thay vì "cách cũ" không?

"Khi bạn có một cây búa mới, mọi thứ sẽ trông giống như một cái đinh". - đây là những gì tôi nghĩ khi tôi đọc câu hỏi của bạn.

Nếu tôi là đồng nghiệp của bạn, tôi sẽ hỏi bạn "tại sao không khởi tạo toàn bộ đối tượng trong hàm tạo?" Rốt cuộc đó là chức năng của nó. Tại sao sử dụng mẫu xây dựng (hoặc bất kỳ thiết kế nào khác)?

Là sự thay đổi tôi đề xuất thậm chí thực sự có giá trị nó?

Thật khó để nói từ đoạn mã nhỏ đó. Có lẽ nó là - bạn và đồng nghiệp của bạn cần phải đánh giá nó.

Bạn có bất cứ lời khuyên nào để trình bày tốt hơn những lập luận như vậy khi ủng hộ việc thử một cái gì đó mới không?

Vâng, tìm hiểu thêm về chủ đề trước khi thảo luận về nó. Trang bị cho mình những lý lẽ và lý lẽ tốt trước khi tham gia thảo luận.


7

Tôi đã ở trong tình huống mà tôi được tuyển dụng cho các kỹ năng của mình. Khi tôi phải xem mã, ồ .. nó còn kinh khủng hơn. Khi sau đó cố gắng làm sạch nó, một người nào đó đã ở đó lâu hơn luôn kìm nén những thay đổi, vì họ không thấy được lợi ích. Nghe có vẻ như một cái gì đó bạn đang mô tả. Nó đã kết thúc với việc tôi từ bỏ vị trí đó và bây giờ tôi có thể phát triển tốt hơn nhiều trong một công ty có thực tiễn tốt hơn.

Tôi không nghĩ bạn chỉ nên đóng vai trò cùng với những người khác trong đội vì họ đã ở đó lâu hơn. Nếu bạn thấy các thành viên trong nhóm của mình sử dụng các thực tiễn xấu trong các dự án bạn làm việc, đó là trách nhiệm bạn phải chỉ ra imo, như bạn có. Nếu không, thì bạn không phải là một tài nguyên rất có giá trị. Nếu bạn chỉ ra điều này nhiều lần, nhưng không ai lắng nghe, hãy yêu cầu bạn quản lý để thay thế hoặc thay đổi công việc. Điều rất quan trọng là bạn không cho phép bản thân thích nghi với những thực hành xấu.

Cho câu hỏi thực tế

Tại sao sử dụng vật bất biến? Bởi vì bạn biết những gì bạn đang đối phó.

Giả sử bạn có kết nối db được truyền xung quanh cho phép bạn thay đổi máy chủ thông qua trình cài đặt, sau đó bạn không biết kết nối đó là gì. Là bất biến, thì bạn biết.

Tuy nhiên, giả sử rằng bạn có một cấu trúc dữ liệu có thể được truy xuất từ ​​sự kiên trì và sau đó được duy trì lại với dữ liệu mới, điều đó có nghĩa là cấu trúc này không phải là bất biến. Đó là cùng một thực thể, nhưng các giá trị có thể thay đổi. Thay vào đó sử dụng các đối tượng giá trị bất biến làm đối số.

Tuy nhiên, những gì bạn đang tập trung vào câu hỏi là một mẫu xây dựng để loại bỏ các phụ thuộc trong hàm tạo. Tôi nói KHÔNG lớn chất béo này. Ví dụ rõ ràng là phức tạp rồi. Đừng cố gắng che giấu nó, sửa chữa nó!

Tl; dr

Loại bỏ các setters có thể đúng, tùy thuộc vào lớp. Mẫu xây dựng không giải quyết được vấn đề, chỉ cần ẩn nó. (Bụi bẩn dưới thảm vẫn tồn tại ngay cả khi bạn không thể nhìn thấy nó)


Tôi không biết chi tiết về tình huống của bạn nhưng nếu bạn đến và cố gắng thay đổi mọi thứ mà không có được sự tự tin của mọi người bằng kỹ năng của bạn hoặc không dành thời gian để tìm hiểu "tại sao" họ làm mọi thứ theo cách họ làm thì bạn đã được đối xử chính xác như bạn sẽ được đối xử ở bất kỳ công ty nào, ngay cả những công ty thực sự tốt. Trên thực tế, đặc biệt là ở những người thực sự tốt. Một khi mọi người có niềm tin vào các kỹ năng của ai đó thì đó chỉ đơn giản là vấn đề tạo ra một trường hợp hấp dẫn cho các đề xuất của bạn. Nếu bạn không thể tạo ra một trường hợp hấp dẫn thì rất có thể đề xuất của bạn không tốt cho lắm.
Dunk

1
idk những gì để trả lời cho các giả định của bạn @Dunk Tôi đã không cố gắng thay đổi mọi thứ, tôi đã cố gắng để làm sạch nó. Và không phải mọi người biết họ đang làm gì, họ tự hào tạo ra các lớp và chức năng có hàng trăm dòng mã, với idk có bao nhiêu tiểu bang, toàn cầu, v.v. cấp độ gần với imo vườn hơn. Vì vậy, tôi đứng trước tuyên bố của tôi. Không bao giờ lùi bước khi bạn nhận thấy bản thân đang ở trong một vị trí mà bạn sẽ phải chấp nhận thực hành xấu để phù hợp.
siêu anh hùng

@Dunk Cố gắng thay đổi cách mọi người viết mã thành viên nhóm không phải là điều tôi làm. Nhưng tôi nói với họ từ đầu; "Tôi sẽ không làm việc trong dự án này mà không viết lại hoàn toàn" , nếu mã là một mẩu rác. Nếu điều đó không được chiếm đoạt, thì ... thì đó là của nhau. Đó không chỉ là sự thoải mái, mà còn là sự thật rằng tôi cần có khả năng chịu trách nhiệm cho những gì tôi sản xuất. Tôi không thể làm điều đó nếu mã xung quanh trong dự án là một mớ hỗn độn.
siêu anh hùng

Bạn không phải "mãi mãi" làm việc với mã rác hoặc làm theo các thực tiễn xấu đơn giản vì đó là cách nó được thực hiện. Tuy nhiên, nếu bạn muốn thành công trong việc thay đổi mọi thứ thì tốt nhất bạn nên chứng minh uy tín của mình trước tiên là tối thiểu. Mọi nhà phát triển đều nghĩ rằng mã họ thừa kế là rác. Nếu mọi công ty chỉ đồng ý với anh chàng mới mỗi lần mà không biết mức độ kỹ năng thực sự của họ thì thùng rác sẽ biến thành bãi rác. Ngoài ra, bạn nên dành thời gian để hiểu tại sao mọi việc được thực hiện như hiện tại. Đôi khi cách "sai" là cách "đúng" cho một tình huống cụ thể.
Dunk

@Dunk Tôi thấy rằng bạn có ý kiến ​​khác thì tôi trong vấn đề này. Bạn dường như phổ biến hơn, nếu đọc từ các câu trả lời khác. Tôi không đồng ý, tại sao tôi lại viết câu trả lời này. Những gì bạn đã nêu đã không thay đổi tâm trí của tôi.
siêu anh hùng

2

Mặc dù tất cả các câu trả lời khác đều rất hữu ích (sẽ hữu ích hơn câu trả lời của tôi), có một thuộc tính của các nhà xây dựng mà bạn chưa đề cập: bằng cách biến việc tạo một đối tượng thành một quy trình, bạn có thể thực thi các ràng buộc logic phức tạp.

Bạn có thể ủy quyền ví dụ rằng các trường nhất định được đặt cùng nhau hoặc theo một thứ tự cụ thể. Bạn thậm chí có thể trả về một triển khai khác nhau của đối tượng mục tiêu tùy thuộc vào các quyết định đó.

// business objects

interface CharRange {
   public char getCharacter();
   public int getFrom();
   public int getTo();
}

class MultiCharRange implements CharRange {
   final char ch;
   final int from;
   final int to;

   public char getCharacter() { return ch; }
   public int getFrom() { return from; }
   public int getTo() { return to; }
}

class SingleCharRange implements CharRange {
   final char ch;
   final int position;

   public char getCharacter() { return ch; }
   public int getFrom() { return position; }
   public int getTo() { return position; }
}

// builders

class Builder1 {
   public Builder2 character(char ch) {
      return new Builder2(ch);
   }
}

class Builder2 {
   final char ch;
   int from;
   int to;

   public Builder2 range(int from, int to) {
      if (from > to) throw new IllegalArgumentException("from > to");
      this.from = from;
      this.to = to;
      return this;
   }

   public Builder2 zeroStartRange(int to) {
      this.from = 0;
      this.to = to;
      return this;
   }

   public CharRange build() {
      if (from == to)
         return new SingleCharRange(ch,from);
      else 
         return new MultiCharRange(ch,from,to);
   }
}

Đây là một ví dụ phù hợp không có ý nghĩa gì nhưng nó thể hiện cả ba thuộc tính: ký tự luôn được đặt đầu tiên, các giới hạn phạm vi luôn được đặt và xác thực cùng nhau và bạn chọn triển khai trong thời gian xây dựng.

Thật dễ dàng để thấy làm thế nào điều này có thể dẫn đến mã người dùng dễ đọc và đáng tin cậy hơn nhưng như bạn cũng có thể thấy, có một nhược điểm của nó: rất nhiều mã xây dựng (và tôi thậm chí còn bỏ qua các nhà xây dựng để rút ngắn đoạn trích). Vì vậy, bạn cố gắng tính toán đánh đổi, bằng cách đặt câu hỏi như:

  • Có phải chúng ta chỉ khởi tạo đối tượng từ một hoặc hai nơi? Điều này có khả năng thay đổi?
  • Có lẽ chúng ta nên thực thi các ràng buộc này bằng cách tái cấu trúc đối tượng ban đầu thành một thành phần của các đối tượng nhỏ hơn?
  • Cuối cùng chúng ta sẽ vượt qua trình xây dựng từ phương thức này sang phương thức khác?
  • Chúng ta có thể chỉ sử dụng một phương pháp nhà máy tĩnh thay thế?
  • Đây có phải là một phần của API bên ngoài, cần phải hoàn hảo và khéo léo nhất có thể không?
  • Khoảng bao nhiêu lỗi tồn đọng hiện tại của chúng tôi có thể tránh được nếu chúng tôi có người xây dựng?
  • Chúng ta sẽ tiết kiệm được bao nhiêu tài liệu bằng văn bản?

Các đồng nghiệp của bạn chỉ đơn giản quyết định rằng sự đánh đổi sẽ không có lợi. Bạn nên thảo luận về các lý do một cách cởi mở và trung thực, tốt nhất là không dùng đến các nguyên tắc trừu tượng, mà tập trung vào ý nghĩa thực tế của giải pháp này hoặc điều đó.


1
bằng cách biến việc tạo một đối tượng thành một quy trình, bạn có thể thực thi các ràng buộc logic phức tạp. BAM. Và tất cả những điều này ngụ ý về sự phức tạp khi nó được tổ chức thành các bước nhỏ hơn, riêng biệt, đơn giản hơn .
radarbob

2

Có vẻ như lớp này thực sự là nhiều hơn một lớp, được đặt cùng một định nghĩa tệp / lớp. Nếu đó là DTO, thì có thể khởi tạo nó ngay lập tức và cho nó là bất biến. Nếu bạn không sử dụng tất cả các trường / thuộc tính của nó trong bất kỳ một giao dịch nào, thì gần như chắc chắn sẽ phá vỡ nguyên tắc Trách nhiệm duy nhất. Có thể việc chia nó thành các lớp DTO nhỏ hơn, gắn kết hơn, bất biến có thể giúp ích. Cân nhắc đọc Mã sạch nếu bạn chưa có để bạn có thể nói rõ hơn các vấn đề và lợi ích của việc thay đổi.

Tôi không nghĩ rằng bạn có thể thiết kế mã ở cấp độ này theo ủy ban, trừ khi bạn thực sự là lập trình mob (có vẻ như bạn thuộc nhóm đó), vì vậy tôi nghĩ nên thay đổi dựa trên đánh giá tốt nhất, và sau đó đưa nó lên cằm nếu hóa ra bạn đánh giá sai.

Tuy nhiên, miễn là bạn có thể nói rõ các vấn đề tiềm ẩn với mã, thì bạn vẫn có thể tranh luận rằng cần phải có giải pháp , ngay cả khi bạn không phải là giải pháp được chấp nhận. Mọi người sau đó được tự do cung cấp các lựa chọn thay thế.

" Ý kiến ​​mạnh mẽ, yếu kém " là một nguyên tắc tốt - bạn tự tin đi trước dựa trên những gì bạn biết, nhưng nếu bạn tìm thấy một số thông tin mới phản ánh, hãy khiêm tốn và bước xuống và thảo luận về giải pháp chính xác. được. Câu trả lời sai duy nhất là để nó trở nên tồi tệ hơn.


Nó chắc chắn không được thiết kế bởi ủy ban, đó là một phần lý do tại sao mã bị hôi thối quá tệ. Tôi cho rằng quá nhiều điều tốt. Đó một DTO nhưng tôi sẽ không chia nó thành nhiều mảnh; nếu codebase xấu thì DB sẽ tệ hơn nhiều. +1 (chủ yếu) cho đoạn cuối.
Rath
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.