Chúng ta có nên tránh các đối tượng tùy chỉnh như tham số?


49

Giả sử tôi có một đối tượng tùy chỉnh, Sinh viên :

public class Student{
    public int _id;
    public String name;
    public int age;
    public float score;
}

Và một lớp, Window , được sử dụng để hiển thị thông tin của Học sinh :

public class Window{
    public void showInfo(Student student);
}

Trông có vẻ khá bình thường, nhưng tôi thấy Window không hoàn toàn dễ kiểm tra riêng lẻ, vì nó cần một đối tượng Sinh viên thực sự để gọi hàm. Vì vậy, tôi cố gắng sửa đổi showInfo để nó không chấp nhận trực tiếp đối tượng Sinh viên :

public void showInfo(int _id, String name, int age, float score);

để dễ dàng kiểm tra Window riêng lẻ:

showInfo(123, "abc", 45, 6.7);

Nhưng tôi thấy phiên bản sửa đổi có một vấn đề khác:

  1. Sửa đổi Sinh viên (ví dụ: thêm thuộc tính mới) yêu cầu sửa đổi chữ ký phương thức của showInfo

  2. Nếu Sinh viên có nhiều tài sản, chữ ký phương thức của Sinh viên sẽ rất dài.

Vì vậy, sử dụng các đối tượng tùy chỉnh làm tham số hoặc chấp nhận từng thuộc tính trong các đối tượng làm tham số, cái nào dễ duy trì hơn?


40
Và 'cải tiến' của bạn showInfoyêu cầu một Chuỗi thực, một số thực và hai số thực. Làm thế nào là cung cấp một Stringđối tượng thực sự tốt hơn so với việc cung cấp một Studentđối tượng thực sự ?
Bart van Ingen Schenau

28
Một vấn đề lớn với việc truyền tham số trực tiếp: bây giờ bạn có hai inttham số. Từ trang web cuộc gọi, không có xác minh rằng bạn thực sự chuyển chúng theo đúng thứ tự. Điều gì nếu bạn trao đổi idage, firstNamelastName? Bạn đang giới thiệu một điểm tiềm năng của sự thất bại có thể rất khó phát hiện cho đến khi nó xuất hiện trên khuôn mặt của bạn và bạn đang thêm nó vào mỗi trang web cuộc gọi .
Chris Hayes

38
@ChrisHayes ah, showForm(bool, bool, bool, bool, int)phương pháp cũ - Tôi yêu những người đó ...
Boris the Spider

3
@ChrisHayes ít nhất không phải là JS ...
Jens Schauder

2
một thuộc tính được đánh giá thấp của các bài kiểm tra: nếu khó tạo / sử dụng các đối tượng của riêng bạn trong các bài kiểm tra, API của bạn có thể sử dụng một số công việc :)
Eevee

Câu trả lời:


131

Sử dụng một đối tượng tùy chỉnh để nhóm các tham số liên quan thực sự là một mẫu được khuyến nghị. Là một cấu trúc lại, nó được gọi là Đối tượng tham số giới thiệu .

Vấn đề của bạn nằm ở nơi khác. Đầu tiên, chung chung Windownên không biết gì về Sinh viên. Thay vào đó, bạn nên có một số loại StudentWindowbiết về việc chỉ hiển thị Students. Thứ hai, hoàn toàn không có vấn đề gì về việc tạo Studentcá thể để kiểm tra StudentWindowmiễn là Studentkhông chứa bất kỳ logic phức tạp nào có thể làm phức tạp hóa việc kiểm tra StudentWindow. Nếu nó có logic đó thì tạo Studentgiao diện và chế nhạo nó nên được ưu tiên.


14
Đáng cảnh báo rằng bạn có thể gặp rắc rối nếu đối tượng mới không thực sự là một nhóm hợp lý. Đừng cố gắng xỏ tất cả các tham số được đặt vào một đối tượng; quyết định theo từng trường hợp Ví dụ trong câu hỏi có vẻ khá rõ ràng là một ứng cử viên tốt cho nó. Việc Studentphân nhóm có ý nghĩa và có khả năng mọc lên trong các lĩnh vực khác của ứng dụng.
jpmc26

Nói một cách khoa học nếu bạn đã có đối tượng, ví dụ Student, đó sẽ là Bảo tồn Toàn bộ Đối tượng
abuzittin gillifirca

4
Cũng nên nhớ Luật Demeter . Có một sự cân bằng để được đánh nhưng tldr không làm a.b.cnếu phương pháp của bạn có a. Nếu phương pháp của bạn đạt đến điểm mà bạn cần có khoảng hơn 4 tham số hoặc 2 cấp độ sâu của việc gia nhập tài sản, thì có lẽ nó cần phải được đưa ra. Cũng lưu ý rằng đây là một hướng dẫn - giống như tất cả các hướng dẫn khác, nó đòi hỏi người dùng phải thận trọng. Đừng theo nó một cách mù quáng.
Dan Pantry

7
Tôi tìm thấy câu đầu tiên của câu trả lời này cực kỳ khó phân tích.
helrich

5
@Qwerky Tôi rất không đồng ý. Học sinh THỰC SỰ nghe giống như một chiếc lá trong biểu đồ đối tượng (chặn các đối tượng tầm thường khác như có thể là Tên, DateOfBirth, v.v.), chỉ đơn thuần là một vật chứa cho trạng thái của học sinh. Không có lý do gì mà Học sinh khó xây dựng, vì đó phải là một loại hồ sơ. Tạo các bài kiểm tra nhân đôi cho một học sinh nghe có vẻ như là một công thức khó để duy trì các bài kiểm tra và / hoặc phụ thuộc nặng nề vào một số khung cô lập lạ mắt.
sara

26

Bạn nói đó là

không hoàn toàn dễ dàng để kiểm tra riêng lẻ, vì nó cần một đối tượng Sinh viên thực sự để gọi hàm

Nhưng bạn chỉ có thể tạo một đối tượng sinh viên để chuyển đến cửa sổ của bạn:

showInfo(new Student(123,"abc",45,6.7));

Nó không có vẻ phức tạp hơn để gọi.


7
Vấn đề xảy ra khi Studentđề cập đến a University, trong đó đề cập đến nhiều Facultys Campus, với Professors và Buildings, không có cái nào showInfothực sự sử dụng, nhưng bạn chưa xác định bất kỳ giao diện nào cho phép các bài kiểm tra "biết" và chỉ cung cấp cho học sinh có liên quan dữ liệu, mà không xây dựng toàn bộ tổ chức. Ví dụ Studentnày là một đối tượng dữ liệu đơn giản và, như bạn nói, các bài kiểm tra sẽ rất vui khi làm việc với nó.
Steve Jessop

4
Vấn đề xảy ra khi Sinh viên đề cập đến một trường đại học, trong đó đề cập đến nhiều Khoa và Campuss, với các Giáo sư và Tòa nhà, Không có phần còn lại cho kẻ ác.
abuzittin gillifirca

1
@abuzmitillifirca, "Đối tượng mẹ" là một giải pháp, đối tượng học sinh của bạn có thể quá phức tạp. Có thể tốt hơn nếu chỉ có UniversityId và một dịch vụ (sử dụng tiêm phụ thuộc) sẽ cung cấp cho đối tượng Đại học từ UniversityId.
Ian

12
Nếu Học sinh rất phức tạp hoặc khó khởi tạo, hãy chế giễu nó. Việc kiểm tra mạnh mẽ hơn nhiều với các khung như Mockito hoặc các ngôn ngữ tương đương khác.
Borjab

4
Nếu showInfo không quan tâm đến Đại học, thì đơn giản đặt nó thành null. Nulls là khủng khiếp trong sản xuất và gửi một bài kiểm tra thần. Có thể chỉ định một tham số là null trong các thử nghiệm truyền đạt ý định và nói rằng "điều này không cần thiết ở đây". Mặc dù tôi cũng xem xét việc tạo một số loại sinh viên modelfor xem chỉ chứa dữ liệu có liên quan, xem xét rằng showInfo nghe giống như một phương thức trong lớp UI.
sara

22

Trong điều khoản của Giáo dân:

  • Những gì bạn gọi là "đối tượng tùy chỉnh" thường được gọi đơn giản là một đối tượng.
  • Bạn không thể tránh truyền các đối tượng làm tham số khi thiết kế bất kỳ chương trình hoặc API không tầm thường nào hoặc sử dụng bất kỳ API hoặc thư viện không tầm thường nào.
  • Hoàn toàn ổn khi truyền các đối tượng làm tham số. Hãy xem API Java và bạn sẽ thấy rất nhiều giao diện nhận các đối tượng làm tham số.
  • Các lớp trong thư viện bạn sử dụng được viết bởi những người bình thường như bạn và tôi, vì vậy những lớp chúng tôi viết không phải là "tùy chỉnh" , chúng chỉ là như vậy.

Biên tập:

Như @ Tom.Bowen89 nói rằng việc kiểm tra phương thức showInfo không phức tạp hơn nhiều:

showInfo(new Student(8812372,"Peter Parker",16,8.9));

3
  1. Trong ví dụ sinh viên của bạn, tôi cho rằng việc gọi hàm tạo Sinh viên để tạo một sinh viên truyền vào showInfo là chuyện nhỏ. Vì vậy, không có vấn đề.
  2. Giả sử ví dụ Học sinh cố tình tầm thường hóa cho câu hỏi này và khó xây dựng hơn, thì bạn có thể sử dụng bài kiểm tra gấp đôi . Có một số tùy chọn cho các bài kiểm tra nhân đôi, giả, sơ khai, vv được nói đến trong bài viết của Martin Fowler để lựa chọn.
  3. Nếu bạn muốn làm cho hàm showInfo trở nên chung chung hơn, bạn có thể lặp lại các biến công khai hoặc có thể các bộ truy cập công khai của đối tượng được truyền vào và thực hiện logic hiển thị cho tất cả chúng. Sau đó, bạn có thể vượt qua trong bất kỳ đối tượng phù hợp với hợp đồng đó và nó sẽ hoạt động như mong đợi. Đây sẽ là một nơi tốt để sử dụng một giao diện. Ví dụ: truyền một đối tượng Showable hoặc ShowInfoable cho hàm showInfo có thể hiển thị không chỉ thông tin sinh viên mà bất kỳ thông tin nào của đối tượng thực hiện giao diện (rõ ràng các giao diện đó cần tên tốt hơn tùy thuộc vào mức độ cụ thể hoặc chung chung mà bạn muốn đối tượng bạn có thể truyền vào được và những gì một Học sinh là một lớp học phụ).
  4. Việc chuyển qua các nguyên thủy thường dễ dàng hơn và đôi khi cần thiết cho hiệu năng, nhưng bạn càng có thể nhóm các khái niệm tương tự lại với nhau thì mã của bạn sẽ càng dễ hiểu hơn. Điều duy nhất để đề phòng là cố gắng không làm quá và kết thúc với fizzbuzz doanh nghiệp .

3

Steve McConnell trong Code Complete đã giải quyết chính vấn đề này, thảo luận về những lợi ích và hạn chế của việc truyền các đối tượng vào các phương thức thay vì sử dụng các thuộc tính.

Hãy tha thứ cho tôi nếu tôi nhận được một số chi tiết sai, đang làm việc từ bộ nhớ vì đã hơn một năm kể từ khi tôi có quyền truy cập vào cuốn sách:

Ông đi đến kết luận rằng bạn tốt hơn hết là không sử dụng một đối tượng, thay vào đó chỉ gửi những thuộc tính đó hoàn toàn cần thiết cho phương thức. Phương thức không cần phải biết bất cứ điều gì về đối tượng bên ngoài các thuộc tính mà nó sẽ sử dụng như một phần của hoạt động. Ngoài ra, theo thời gian, nếu đối tượng bị thay đổi, điều này có thể gây ra hậu quả không lường trước cho phương thức sử dụng đối tượng.

Ngoài ra, ông giải quyết rằng nếu bạn kết thúc với một phương thức chấp nhận nhiều đối số khác nhau, thì đó có lẽ là dấu hiệu cho thấy phương thức đó đang làm quá nhiều và nên được chia thành các phương thức nhỏ hơn, nhỏ hơn.

Tuy nhiên, đôi khi, đôi khi, bạn thực sự cần rất nhiều thông số. Ví dụ anh ta đưa ra sẽ là một phương thức xây dựng một địa chỉ đầy đủ, sử dụng nhiều thuộc tính địa chỉ khác nhau (mặc dù điều này có thể được khắc phục bằng cách sử dụng một chuỗi chuỗi khi bạn nghĩ về nó).


7
Tôi có Code Complete 2. Có toàn bộ trang dành riêng cho vấn đề này. Kết luận là các tham số nên ở mức độ trừu tượng chính xác. Đôi khi điều đó đòi hỏi phải vượt qua toàn bộ một đối tượng, đôi khi chỉ là các thuộc tính riêng lẻ.
ĐẾN TỪ

UV. tham chiếu Hoàn thành là gấp đôi cộng tốt. Một sự xem xét tốt đẹp của thiết kế qua thử nghiệm nhanh chóng. Thích thiết kế, tôi nghĩ McConnell sẽ nói trong bối cảnh của chúng tôi. Vì vậy, một kết luận tuyệt vời sẽ là "tích hợp đối tượng tham số vào thiết kế" ( Studenttrong trường hợp này). Và đây là cách thử nghiệm thông báo cho thiết kế , hoàn toàn chấp nhận câu trả lời được nhiều phiếu nhất trong khi vẫn duy trì tính toàn vẹn của thiết kế.
radarbob

2

Việc viết và đọc các bài kiểm tra sẽ dễ dàng hơn nhiều nếu bạn vượt qua toàn bộ đối tượng:

public class AStudentView {
    @Test 
    public void displays_failing_grade_warning_when_a_student_with_a_failing_grade_is_shown() {
        StudentView view = aStudentView();
        view.show(aStudent().withAFailingGrade().build());
        Assert.that(view, displaysFailingGradeWarning());
    }

    private Matcher<StudentView> displaysFailingGradeWarning() {
        ...
    }
}

Để so sánh,

view.show(aStudent().withAFailingGrade().build());

dòng có thể được viết, nếu bạn chuyển các giá trị riêng biệt, như:

showAStudentWithAFailingGrade(view);

nơi cuộc gọi phương thức thực tế được chôn ở đâu đó như

private showAStudentWithAFailingGrade(StudentView view) {
    int someId = .....
    String someName = .....
    int someAge = .....
    // why have been I peeking and poking values I don't care about
    decimal aFailingGrade = .....
    view.show(someId, someName, someAge, aFailingGrade);
}

Để giải quyết vấn đề, bạn không thể thực hiện cuộc gọi phương thức thực tế trong thử nghiệm là dấu hiệu cho thấy API của bạn không tốt.


1

Bạn nên vượt qua những gì có ý nghĩa, một số ý tưởng:

Dễ kiểm tra hơn. Nếu (các) đối tượng cần được chỉnh sửa, cái gì đòi hỏi phải tái cấu trúc ít nhất? Việc sử dụng lại chức năng này cho các mục đích khác có hữu ích không? Lượng thông tin ít nhất tôi cần để cung cấp cho chức năng này là gì? (Bằng cách phá vỡ nó - nó có thể cho phép bạn sử dụng lại mã này - hãy cảnh giác khi rơi xuống lỗ hổng thiết kế để thực hiện chức năng này và sau đó làm tắc nghẽn mọi thứ để sử dụng riêng đối tượng này.)

Tất cả các quy tắc lập trình này chỉ là hướng dẫn để bạn suy nghĩ đúng hướng. Chỉ cần không xây dựng một con thú mã - nếu bạn không chắc chắn và chỉ cần tiếp tục, hãy chọn một hướng / của riêng bạn hoặc một gợi ý ở đây, và nếu bạn nhấn vào một điểm mà bạn nghĩ 'ồ, tôi nên làm điều đó cách '- sau đó bạn có thể quay lại và tái cấu trúc nó khá dễ dàng. (Ví dụ: nếu bạn có lớp Giáo viên - nó chỉ cần cùng thuộc tính được đặt với Học sinh và bạn thay đổi chức năng của mình để chấp nhận bất kỳ đối tượng nào của biểu mẫu Người)

Tôi sẽ có khuynh hướng nhất để giữ cho đối tượng chính được thông qua - bởi vì cách tôi viết mã sẽ giải thích dễ dàng hơn chức năng này đang làm gì.


1

Một lộ trình chung quanh đây là chèn một giao diện giữa hai quy trình.

public class Student {

    public int id;
    public String name;
    public int age;
    public float score;
}

interface HasInfo {
    public String getInfo();
}

public class StudentInfo implements HasInfo {
    final Student student;

    public StudentInfo(Student student) {
        this.student = student;
    }

    @Override
    public String getInfo() {
        return student.name;
    }

}

public class Window {

    public void showInfo(HasInfo info) {

    }
}

Điều này đôi khi hơi lộn xộn nhưng mọi thứ trở nên gọn gàng hơn trong Java nếu bạn sử dụng một lớp bên trong.

interface HasInfo {
    public String getInfo();
}

public class Student {

    public int id;
    public String name;
    public int age;
    public float score;

    public HasInfo getInfo() {
        return new HasInfo () {
            @Override
            public String getInfo() {
                return name;
            }

        };
    }
}

Sau đó, bạn có thể kiểm tra Windowlớp bằng cách chỉ cho nó một HasInfođối tượng giả .

Tôi nghi ngờ đây là một ví dụ về Mẫu trang trí .

Thêm

Dường như có một số nhầm lẫn gây ra bởi sự đơn giản của mã. Đây là một ví dụ khác có thể chứng minh kỹ thuật tốt hơn.

interface Drawable {

    public void Draw(Pane pane);
}

/**
 * Student knows nothing about Window or Drawable.
 */
public class Student {

    public int id;
    public String name;
    public int age;
    public float score;
}

/**
 * DrawsStudents knows about both Students and Drawable (but not Window)
 */
public class DrawsStudents implements Drawable {

    private final Student subject;

    public DrawsStudents(Student subject) {
        this.subject = subject;
    }

    @Override
    public void Draw(Pane pane) {
        // Draw a Student on a Pane
    }

}

/**
 * Window only knows about Drawables.
 */
public class Window {

    public void showInfo(Drawable info) {

    }
}

Nếu showInfo chỉ muốn hiển thị tên của sinh viên, tại sao không chỉ truyền tên? bao bọc một trường có tên có ý nghĩa về mặt ngữ nghĩa trong một giao diện trừu tượng có chứa một chuỗi không có manh mối gì về chuỗi mà nó thể hiện giống như một sự hạ cấp HUGE, cả về khả năng duy trì và dễ hiểu.
sara

@kai - Sử dụng StudentStringở đây cho loại trả lại hoàn toàn là để trình diễn. Có khả năng sẽ có các tham số bổ sung getInfonhư Panevẽ để vẽ. Khái niệm ở đây là để vượt qua các thành phần chức năng như trang trí của đối tượng ban đầu .
OldCurmudgeon

trong trường hợp đó, bạn sẽ kết hợp chặt chẽ thực thể sinh viên với khung UI của mình, điều đó nghe còn tệ hơn ...
sara

1
@kai - Hoàn toàn ngược lại. UI của tôi chỉ biết về HasInfocác đối tượng. Studentbiết làm thế nào để là một.
OldCurmudgeon

Nếu bạn getInfotrả lại khoảng trống, hãy chuyển nó Panesang, để thực hiện (trong Studentlớp) đột nhiên được kết hợp để xoay hoặc bất cứ điều gì bạn đang sử dụng. Nếu bạn làm cho nó trả về một số chuỗi và lấy 0 tham số, thì UI của bạn sẽ không biết phải làm gì với chuỗi mà không có giả định ma thuật và khớp nối ngầm. Nếu bạn thực getInfosự trả về một số mô hình khung nhìn với các thuộc tính có liên quan, thì Studentlớp của bạn lại được kết hợp với logic trình bày. Tôi không nghĩ bất kỳ lựa chọn thay thế nào là mong muốn
sara

1

Bạn đã có rất nhiều câu trả lời hay, nhưng dưới đây là một vài gợi ý có thể cho phép bạn xem một giải pháp thay thế:

  • Ví dụ của bạn cho thấy một Học sinh (rõ ràng là một đối tượng mô hình) đang được chuyển đến một Cửa sổ (rõ ràng là một đối tượng ở mức độ xem). Đối tượng Trình điều khiển hoặc Người trình bày trung gian có thể có lợi nếu bạn chưa có, cho phép bạn cách ly giao diện người dùng khỏi mô hình của mình. Bộ điều khiển / người trình bày nên cung cấp một giao diện có thể được sử dụng để thay thế nó để kiểm tra giao diện người dùng và nên sử dụng các giao diện để tham chiếu đến các đối tượng mô hình và xem các đối tượng để có thể cách ly nó khỏi cả hai đối tượng để thử nghiệm. Bạn có thể cần cung cấp một số cách trừu tượng để tạo hoặc tải những thứ này (ví dụ: đối tượng Factory, đối tượng Kho lưu trữ hoặc tương tự).

  • Chuyển các phần có liên quan của các đối tượng mô hình của bạn vào Đối tượng truyền dữ liệu là một cách tiếp cận hữu ích để can thiệp khi mô hình của bạn trở nên quá phức tạp.

  • Có thể là Học sinh của bạn vi phạm Nguyên tắc phân chia giao diện. Nếu vậy, có thể có ích khi chia nó thành nhiều giao diện dễ làm việc hơn.

  • Lazy Loading có thể làm cho việc xây dựng các đồ thị đối tượng lớn dễ dàng hơn.


0

Đây thực sự là một câu hỏi hay. Vấn đề thực sự ở đây là việc sử dụng thuật ngữ chung "đối tượng", có thể hơi mơ hồ.

Nói chung, trong một ngôn ngữ OOP cổ điển, thuật ngữ "đối tượng" có nghĩa là "thể hiện lớp". Các thể hiện của lớp có thể khá nặng - các thuộc tính công cộng và riêng tư (và các thuộc tính ở giữa), các phương thức, thừa kế, các phụ thuộc, v.v. Bạn sẽ không thực sự muốn sử dụng một cái gì đó như thế để đơn giản chuyển vào một số thuộc tính.

Trong trường hợp này, bạn đang sử dụng một đối tượng như một vật chứa chỉ đơn giản là chứa một số nguyên thủy. Trong C ++, các đối tượng như thế này được gọi là structs(và chúng vẫn tồn tại trong các ngôn ngữ như C #). Trên thực tế, các cấu trúc được thiết kế chính xác cho cách sử dụng mà bạn nói - chúng nhóm các đối tượng và nguyên thủy liên quan lại với nhau khi chúng có mối quan hệ logic.

Tuy nhiên, trong các ngôn ngữ hiện đại, thực sự không có sự khác biệt giữa một cấu trúc và một lớp khi bạn viết mã , vì vậy bạn vẫn ổn khi sử dụng một đối tượng. (Tuy nhiên, đằng sau hậu trường, có một số khác biệt mà bạn cần lưu ý - ví dụ: cấu trúc là loại giá trị, không phải loại tham chiếu.) Về cơ bản, miễn là bạn giữ cho đối tượng của mình đơn giản, nó sẽ dễ dàng để kiểm tra thủ công. Các ngôn ngữ và công cụ hiện đại cho phép bạn giảm thiểu điều này khá nhiều, mặc dù (thông qua giao diện, khung mô phỏng, nội xạ phụ thuộc, v.v.)


1
Truyền tham chiếu không tốn kém, ngay cả khi đối tượng có dung lượng lớn hàng tỷ terabyte, bởi vì tham chiếu vẫn chỉ có kích thước của một int trong hầu hết các ngôn ngữ. Bạn nên lo lắng nhiều hơn về việc liệu phương thức nhận có tiếp xúc với một api quá lớn hay không và liệu bạn có kết hợp mọi thứ theo cách không mong muốn hay không. Tôi đã xem xét việc tạo một lớp ánh xạ chuyển các đối tượng kinh doanh ( Student) thành các mô hình xem ( StudentInfohoặc StudentInfoViewModelv.v.), nhưng có thể không cần thiết.
sara

Các lớp học và cấu trúc rất khác nhau. Một được truyền bởi giá trị (có nghĩa là phương thức nhận nó nhận được một bản sao ) và phương thức khác được truyền bằng tham chiếu (người nhận chỉ cần lấy một con trỏ đến bản gốc). Không hiểu sự khác biệt này là nguy hiểm.
RubberDuck

@kai Tôi hiểu rằng việc chuyển một tài liệu tham khảo không tốn kém. Điều tôi đang nói là việc tạo một hàm yêu cầu một thể hiện của lớp đầy đủ có thể khó kiểm tra hơn tùy thuộc vào sự phụ thuộc của lớp đó, các phương thức của nó, v.v. - vì bạn phải chế giễu lớp đó bằng cách nào đó.
bữa ăn trưa317

Cá nhân tôi chống lại việc chế nhạo bất cứ thứ gì ngoại trừ các lớp ranh giới truy cập vào các hệ thống bên ngoài (tệp / mạng IO) hoặc các lớp không xác định (ví dụ: ngẫu nhiên, dựa trên thời gian hệ thống, v.v.). Nếu một lớp tôi đang kiểm tra có một phụ thuộc không liên quan đến tính năng hiện tại đang được kiểm tra, tôi thích chỉ cần vượt qua null nếu có thể. Nhưng nếu bạn đang thử nghiệm một phương thức lấy một đối tượng tham số, nếu đối tượng đó có một loạt các phụ thuộc, tôi sẽ lo lắng về thiết kế tổng thể. Những đồ vật như vậy nên nhẹ.
sara
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.