2009-10-16 28 views
8

Tôi có một đối tượng được gọi là tham số được ném từ phương pháp để phương thức xuống và lên cây gọi, qua ranh giới gói. Nó có khoảng năm mươi biến trạng thái. Mỗi phương thức có thể sử dụng một hoặc hai biến để kiểm soát đầu ra của nó.Thiên Chúa đối tượng - giảm khớp nối với một 'chủ' đối tượng

Tôi nghĩ rằng đây là một ý tưởng tồi, vì tôi không thể dễ dàng thấy phương thức cần thực hiện, hoặc thậm chí điều gì có thể xảy ra nếu kết hợp các thông số cho mô-đun Y hoàn toàn không liên quan đến mô-đun hiện tại của tôi.

Một số kỹ thuật tốt để giảm ghép nối với vật thể thần này là gì, hoặc lý tưởng loại bỏ nó?

 public void ExporterExcelParFonds(ParametresExecution parametres) 
    { 
     ApplicationExcel appExcel = null; 
     LogTool.Instance.ExceptionSoulevee = false; 


     bool inclureReferences = parametres.inclureReferences; 
     bool inclureBornes = parametres.inclureBornes; 
     DateTime dateDebut = parametres.date; 
     DateTime dateFin = parametres.dateFin; 

     try 
     { 
      LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference); 

      bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds); 
      if (!fichiersPreparesAvecSucces) 
      { 
       parametres.afficherRapportApresGeneration = false; 
       LogTool.Instance.ExceptionSoulevee = true; 
      } 
      else 
      { 

Người gọi sẽ làm gì:

   PortefeuillesReference pr = new PortefeuillesReference(); 
      pr.ExporterExcelParFonds(parametres); 
+0

Đối tượng cấu hình có phải là "Tham số" không? –

+0

Vâng, đúng thế. Được sử dụng để có giao diện người dùng thực hiện bất kỳ thông số nào mà lớp doanh nghiệp có thể cần. –

Trả lời

9

Đầu tiên, có nguy cơ nêu rõ: chuyển các tham số được sử dụng bởi phương pháp, chứ không phải là đối tượng thần.

Điều này, tuy nhiên, có thể dẫn đến một số phương pháp cần số lượng lớn thông số vì chúng gọi các phương thức khác, lần lượt gọi các phương thức khác, v.v. Đó có lẽ là nguồn cảm hứng cho việc đặt tất cả mọi thứ vào một vật thể thần. Tôi sẽ đưa ra một ví dụ đơn giản về phương thức như vậy với quá nhiều tham số; bạn sẽ phải tưởng tượng rằng "quá nhiều" == 3 ở đây :-)

public void PrintFilteredReport(
    Data data, FilterCriteria criteria, ReportFormat format) 
{ 
    var filteredData = Filter(data, criteria); 
    PrintReport(filteredData, format); 
} 

Vậy câu hỏi là, làm thế nào chúng ta có thể làm giảm lượng các thông số mà không cần đến một đối tượng thần? Câu trả lời là để loại bỏ lập trình thủ tục và sử dụng tốt thiết kế hướng đối tượng. Đối tượng có thể sử dụng lẫn nhau mà không cần phải biết các thông số đã được sử dụng để khởi tạo cộng tác viên của họ:

// dataFilter service object only needs to know the criteria 
var dataFilter = new DataFilter(criteria); 

// report printer service object only needs to know the format 
var reportPrinter = new ReportPrinter(format); 

// filteredReportPrinter service object is initialized with a 
// dataFilter and a reportPrinter service, but it doesn't need 
// to know which parameters those are using to do their job 
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter); 

Bây giờ phương pháp FilteredReportPrinter.Print thể được thực hiện chỉ với một tham số:

public void Print(data) 
{ 
    var filteredData = this.dataFilter.Filter(data); 
    this.reportPrinter.Print(filteredData); 
} 

Ngẫu nhiên, điều này loại tách mối quan tâm và tiêm phụ thuộc là tốt cho nhiều hơn là chỉ loại bỏ các thông số. Nếu bạn truy cập cộng tác viên các đối tượng thông qua các giao diện, sau đó mà làm cho lớp học của bạn

  • rất linh hoạt: bạn có thể thiết lập FilteredReportPrinter với bất kỳ thực hiện bộ lọc/máy in mà bạn có thể tưởng tượng
  • rất thể kiểm chứng: bạn có thể vượt qua trong cộng tác giả với đóng hộp phản hồi và xác minh rằng chúng đã được sử dụng chính xác trong thử nghiệm đơn vị
+1

Câu trả lời hay nhất, trong ý kiến ​​của tôi. –

0

Query từng khách hàng cho các thông số cần thiết của họ và tiêm họ?

Ví dụ: mỗi "đối tượng" yêu cầu "thông số" là "Khách hàng". Mỗi "Client" cho thấy một giao diện thông qua đó một "Agent Agent" truy vấn Client cho các tham số cần thiết của nó. Tác nhân cấu hình sau đó "injects" các tham số (và chỉ những thông số được yêu cầu bởi Client).

+0

Bạn có thể mở rộng trên điều này, có thể với một ví dụ? Tôi nghĩ rằng tôi đồng ý với điều này, nhưng tôi muốn chắc chắn. – gn22

+0

Tôi không hiểu. –

+0

Tôi đã thêm chi tiết. – jldupont

1

Nếu tất cả các phương thức của bạn đang sử dụng cùng một lớp Parameters thì có lẽ nó phải là biến thành viên của một lớp với các phương thức thích hợp trong đó, sau đó bạn có thể chuyển Parameters vào hàm tạo của lớp này. và tất cả các phương pháp của bạn có thể sử dụng nó với việc phải truyền nó như một tham số.

Cách tốt để bắt đầu tái cấu trúc lớp thần linh này là chia nhỏ nó thành nhiều phần nhỏ hơn. Tìm các nhóm thuộc tính có liên quan và chia chúng thành lớp riêng của chúng.

Sau đó, bạn có thể truy cập lại các phương pháp phụ thuộc vào Parameters và xem bạn có thể thay thế phương thức đó bằng một trong các lớp nhỏ hơn bạn đã tạo hay không.

Khó để đưa ra giải pháp tốt mà không có một số mẫu mã và tình huống thực tế.

0

Có vẻ như bạn không áp dụng các nguyên tắc hướng đối tượng (OO) trong thiết kế của bạn. Kể từ khi bạn đề cập đến từ "đối tượng" tôi đoán bạn đang làm việc trong một số loại mô hình OO. Tôi khuyên bạn nên chuyển đổi "cây gọi" thành các đối tượng mô hình hóa vấn đề bạn đang giải quyết. Một "đối tượng thần" chắc chắn là một cái gì đó để tránh. Tôi nghĩ rằng bạn có thể thiếu một cái gì đó cơ bản ... Nếu bạn đăng một số ví dụ mã tôi có thể trả lời chi tiết hơn.

+0

Vâng, đó là một hệ thống di sản, và nó được viết kém, tôi đồng ý. –

+1

Vui lòng đăng ví dụ về mã ... cách bạn đối phó với tình huống này tùy thuộc vào chi tiết. – SingleShot

-2

(Tôi giả sử đây là trong môi trường Java hoặc .NET) Chuyển đổi lớp thành một singleton. Thêm một phương thức tĩnh gọi là "getInstance()" hoặc một cái gì đó tương tự như gọi để nhận được gói giá trị tên (và dừng "tramping" nó xung quanh - xem Ch. 10 của "Code Complete" book).

Bây giờ là phần khó khăn. Có lẽ, đây là trong một ứng dụng web hoặc một số môi trường không phải bó/đơn luồng khác. Vì vậy, để có được quyền truy cập vào đúng đối tượng khi đối tượng không thực sự là một singleton thực, bạn phải ẩn logic lựa chọn bên trong của accessor tĩnh.

Trong java, bạn có thể thiết lập tham chiếu "địa phương chủ đề" và khởi chạy nó khi mỗi yêu cầu hoặc nhiệm vụ phụ bắt đầu. Sau đó, mã accessor về thread-local đó. Tôi không biết nếu một cái gì đó tương tự tồn tại trong. NET, nhưng bạn luôn có thể giả mạo nó với một từ điển (Hash, Bản đồ) trong đó sử dụng thể hiện thread hiện tại như là chìa khóa.

Đó là một sự khởi đầu ...(luôn có sự phân hủy của chính blob, nhưng tôi đã xây dựng một khung có một cửa hàng giá trị bán toàn cầu rất giống với nó)

+3

Tôi đang cố gắng tránh việc có một singleton. Tôi thực sự không thích những người độc thân vì nơi tôi đã thấy nó được sử dụng. Sử dụng nó ở đây sẽ là một bước trở lại. –

+0

-1 thực tế là bạn cần threadlocal để giảm "toàn cầu" của "singleton" chỉ ra rằng bạn không nên sử dụng globals ở nơi đầu tiên. OP có thể nói về một ứng dụng winforms đơn luồng anyway. –

0

Đối với các thông số quy định hành vi, người ta có thể khởi tạo đối tượng thể hiện hành vi được định cấu hình. Sau đó, các lớp máy khách chỉ đơn giản là sử dụng đối tượng instantiated - cả khách hàng lẫn dịch vụ đều không biết giá trị của tham số là gì. Ví dụ cho một tham số cho biết nơi để đọc dữ liệu từ, có FlatFileReader, XMLFileReader và DatabaseReader tất cả kế thừa cùng một lớp cơ sở (hoặc thực hiện cùng một giao diện). Khởi tạo một trong số chúng dựa trên giá trị của tham số, sau đó các máy khách của lớp người đọc chỉ yêu cầu dữ liệu cho đối tượng trình đọc được instantiated mà không biết dữ liệu đến từ một tệp hay từ DB.

Để bắt đầu, bạn có thể phá vỡ lớp ParametresExecution lớn của bạn thành nhiều lớp, mỗi lớp một gói, chỉ giữ các tham số cho gói.

Một hướng khác có thể là chuyển đối tượng ParametresExecution vào thời gian xây dựng. Bạn sẽ không phải vượt qua nó xung quanh ở mọi cuộc gọi chức năng.

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