2008-11-20 32 views
5

Có cần thiết cho các phương thức setter để có một đối số không? Thông thường, các phương thức setter chấp nhận một đối số làm giá trị của một thuộc tính nào đó của một đối tượng. Điều gì sẽ xảy ra nếu tôi muốn kiểm tra tính hợp lệ đầu tiên phụ thuộc vào một đối số khác là một boolean, nếu đúng, xác thực trước, chỉ cần đặt giá trị.Có cần thiết cho các phương thức setter để có một đối số không?

Tôi nhận được các giá trị từ khách hàng thông qua máy chủ FTP. Đôi khi các tệp đó chứa các giá trị rác. Ví dụ: một số điện thoại như # 3432838 # 9. Vì vậy, trước khi tôi đặt giá trị tôi cần phải loại bỏ các ký tự rác đó. Tôi có thể làm điều đó trong các phương pháp setter? Đó có phải là phương pháp hợp lệ không?

Cảm ơn một nhóm trước!

EDIT:

Đây có phải là hợp lệ:

public void setSomething(String strValue){ 
    if(checkValidity(strValue)){ 
     // set the value 
    } else { 
     // set the value to an empty string 
    } 
    } 
+0

Xem thêm http://stackoverflow.com/questions/2750/data-verifications-in-gettersetter-or-elsewhere – VonC

+0

Cảm ơn bạn rất, rất nhiều. – DragonBorn

+0

Chỉ cần thêm câu trả lời vào đoạn mã – VonC

Trả lời

12

Điều cần thiết đặc biệt trong mô hình khung đậu java, nhưng nó không bắt buộc nói chung.

Bạn có thể có setter mà không có đối số khi chúng có nghĩa là "swith" một giá trị. Ví dụ:

void setCheck() 

có thể có nghĩa là đặt thuộc tính boolean "kiểm tra" thành true.

Vì vậy, ngay cả khi nó không phải là "setter" trong nghĩa java bean của thuật ngữ, bạn có thể tưởng tượng setter được sử dụng cho các mục đích khác.

Thêm vào đó, theo điều 7 của thông số kỹ thuật JavaBean, một setter thể có hơn một đối số, ví dụ đối với tài sản Indexed (Một tài sản được lập chỉ mục hỗ trợ một loạt các giá trị. Bất cứ khi nào tài sản được đọc hoặc viết cho bạn chỉ cần chỉ định một chỉ số để xác định giá trị mà bạn muốn.)

void setter(int index, PropertyType value); // indexed setter 
void setter(PropertyType values[]); // array setter 

trong trường hợp của bạn, một cách tiếp cận hợp lệ sẽ được thêm một runtime exception để có chữ ký của chức năng của chúng tôi.
Bằng cách đó bạn không đặt bất kỳ trường hợp ngoại lệ biên dịch không cần thiết nào cho tất cả các lớp khác đang gọi setter của bạn.

Hoặc bạn có thể xem tài sản của mình là Thuộc tính bị ràng buộc và thêm ngoại lệ không phải là thời gian chạy.

Phương thức thiết lập thuộc tính bị ràng buộc được yêu cầu để hỗ trợ PropertyVetoException. Tài liệu này cho người dùng thuộc tính bị hạn chế cố gắng cập nhật có thể bị phủ quyết. Vì vậy, một tài sản bị hạn chế đơn giản có thể trông giống như:

PropertyType getFoo(); 
void setFoo(PropertyType value) throws PropertyVetoException; 

mà cho phép VetoableChangeListener được bổ sung nếu cần thiết.


Về đoạn mã của bạn, nó là "hợp lệ" nhưng có thể không tối ưu vì (như đã nói ở this question):

  • Validation nên được chụp riêng rẽ với getters hoặc setters trong một phương pháp xác nhận . Bằng cách đó, nếu xác thực cần được sử dụng lại trên nhiều thành phần, nó có sẵn.
  • Tốt hơn là không nhanh chóng (do đó đề xuất của tôi là thêm ngoại lệ cho trình thiết lập).
+0

Nhưng void setCheck() không còn là "setter" nữa. Nó chỉ là một phương thức đơn giản mà tên bắt đầu bằng "set". – Marko

+0

True: Tôi chỉ có nghĩa là một "setter" không nhất thiết phải gắn liền với Java Bean. Nó có thể bị từ chối vì các mục đích khác. – VonC

+0

Vì vậy, đoạn mã được thêm vào có phải là phương pháp hợp lệ không? Cảm ơn bạn. – DragonBorn

5

By Java Bean đặc điểm kỹ thuật setter có một cuộc tranh cãi. Nếu bạn thêm một cái khác, vì lý do gì đó, nó không được coi là setter nữa.

Setter hoàn toàn hợp lệ để "dọn sạch" đối số của nó hoặc ném ngoại lệ nếu không hợp lệ.

2

Tại sao không. Việc xác minh và xác thực đầu vào là một biến thể tốt để đưa vào trình thiết lập. Câu hỏi đặt ra ở đây là, nếu bạn muốn cho phép thiết lập thành viên mà không cần xác nhận.

Có thể bạn cần hình thức tiêu chuẩn của bộ đặt cho một số khung mà bạn sử dụng (sử dụng làm đậu). Nhưng nếu bạn không bị giới hạn theo cách này, bạn có thể thử điều này.

Bạn cũng có thể sử dụng các xác nhận trong setter, nếu bạn nghĩ rằng mã khác nên thực hiện xác thực nhưng các giá trị sai sẽ không bao giờ được đặt.

1

Trong cuốn sách "Hiệu quả Java phiên bản 2" của Joshua Bloch (ISBN-13: 978-0-321-35668-0) nói rằng tốt nhất nên sử dụng mẫu xây dựng hơn so với quy ước bean cho các đối tượng sáng tạo.

Ví dụ (mẫu đậu):

NutritionFacts cocaCola = new NutritionFacts(); 
cocaCola.setServingSize(240); 
cocaCola.setServings(8); 
cocaCola.setCalories(100); 
cocaCola.setSodium(35); 
cocaCola.setCarbohydrate(27); 

sử dụng cho phép người xây dựng mô hình:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). 
    calories(100). 
    sodium(35). 
    carbohydrate(27). 
    build(); 

Việc thực hiện mô hình xây dựng:

// Builder Pattern 
public class NutritionFacts { 
    private final int servingSize; 
    private final int servings; 
    private final int calories; 
    private final int fat; 
    private final int sodium; 
    private final int carbohydrate; 
    public static class Builder { 
     // Required parameters 
     private final int servingSize; 
     private final int servings; 
     // Optional parameters - initialized to default values 
     private int calories = 0; 
     private int fat = 0; 
     private int carbohydrate = 0; 
     private int sodium = 0; 
     public Builder(int servingSize, int servings) { 
      this.servingSize = servingSize; 
      this.servings = servings; 
     } 
     public Builder calories(int val) 
     { calories = val; return this; } 
     public Builder fat(int val) 
     { fat = val; return this; } 
     public Builder carbohydrate(int val) 
     { carbohydrate = val; return this; } 
     public Builder sodium(int val) 
     { sodium = val; return this; } 
     public NutritionFacts build() { 
      return new NutritionFacts(this); 
     } 
    } 
    private NutritionFacts(Builder builder) { 
     servingSize = builder.servingSize; 
     servings = builder.servings; 
     calories = builder.calories; 
     fat = builder.fat; 
     sodium = builder.sodium; 
     carbohydrate = builder.carbohydrate; 
    } 
} 

Khi hai đối số đầu tiên ar cần thiết.
Để xác thực, bạn có thể sử dụng xác thực sớm (trong mỗi phương thức <field>) hoặc xác thực lười (trong phương thức build()). Và định dạng là kiểu khởi tạo khóa-giá trị python.

+0

Ý nghĩa của việc xây dựng phương pháp là gì? Tại sao không chỉ dừng lại ở .carbohydrate()? – Allyn

+0

Phương thức xây dựng trả về một đối tượng NutritionFacts. Những người khác trả lại một Builder. Bạn có thể viết một số điều như sau: NutritionFacts n = new NutritionFacts.Builder (12, 15) .sodium (12) .build(); – user2427

Các vấn đề liên quan