2013-06-05 9 views
5

Tôi đang đối mặt với một vấn đề, có thể được đặt trên programmers.stackexchange.com, nhưng vì nó khá gắn với Doctrine và ZF2, tôi đã chọn để đưa nó lên ở đây. Hãy để tôi giới thiệu bạn với kịch bản của tôi:Cách xử lý các thực thể thuộc tính khác nhau cho các thực thể khác nhau

  • Tôi có một Ứng dụng nơi Người dùng đăng thực thể (BaseEntity).
  • Các BaseEntity có tính chất $cagetory
  • Tùy thuộc vào $category tuy nhiên Entity phải có thêm Thuộc tính

Ab Ví dụ đơn giản:

class BaseEntity { 
    protected $id; 
    protected $title; 
    protected $description; 
} 

class MovieEntity { 
    protected $id; 
    protected $title; 
    protected $description; 
    protected $airingDateStart; // new property 
    protected $airingDateEnd; // new property 
} 

Bây giờ tôi có thể dễ dàng làm một công thức hai bước nơi mà người dùng đầu tiên chọn Danh mục của mình và tùy thuộc vào EntityClass sẽ được chọn - nhưng tôi không thể có điều đó. Nhưng điều đó không tốt bởi vì nếu Người dùng đưa Phim lên BaseEntity -Thể loại và sau đó muốn thay đổi Thực thể thành MovieEntity? Ý tưởng đó không thực sự là một lựa chọn an toàn.

Yêu cầu bổ sung (để làm công cụ phức tạp hơn)

  • Các hạng mục cũng như các thực thể đã được kiểm soát bởi Học thuyết
  • Mỗi Category được cung cấp cho các ứng dụng thông qua một đơn Module
  • Các mô-đun cần được đặt vào ứng dụng mà không cần cấu hình nhiều (tối đa một truy vấn DB để điền CategoryTable)

gì tôi đã làm cho đến nay

Lúc đầu tôi đã chọn để chạy với chức năng Giáo Lý Độc Bảng Inheritance. Điều này cho phép tôi dễ dàng thực hiện những việc như MovieEntity extends BaseEntity và mọi thứ hoạt động như một sự quyến rũ để thêm các thực thể mới vào Cơ sở dữ liệu. Nhưng vấn đề chính vẫn là: nếu người dùng thay đổi Category, nó sẽ thay đổi EntityClass và đó là một No-Go.

Ý tôi là có, tôi có thể cố ý làm mọi thứ theo cách hiện tại của mình và thay đổi danh mục theo cách thủ công sửa đổi DiscriminatorColumn nhưng điều đó thật bẩn.

Một cách tiếp cận thay thế khác là trong trường hợp thay đổi danh mục, thực thể MỚI sẽ được tạo và danh mục cũ sẽ bị hủy, nhưng điều đó cũng cảm thấy bẩn thỉu.

Tất cả trong tất cả tôi nghĩ rằng tôi đang đi sai hướng. Có thể có một mô hình phát triển mà tôi không biết về điều đó làm cho tất cả công việc khó khăn của tôi trông giống như một sự lãng phí và mọi thứ trở nên siêu dễ dàng vào cuối, nhưng có vẻ như tôi đang xem nội dung.

Để có thể có được một ý tưởng gần gũi hơn những gì tôi ký, bạn có thể có một cái nhìn tại ứng dụng của tôi trên GitHub:

  • DuitMarketplace - đây là ứng dụng chính với một cơ sở thể loại, tất cả các bộ điều khiển, v.v ...Các ItemController#editAction() có thể cung cấp một số manh mối hơn như thế nào tôi có ý định tự động hóa một số điều.
  • DuitMarketplaceItemVehicle - một thể loại mà có được của rơi vào mainapp

Cảm ơn trước cho tất cả các thông tin phản hồi tôi có thể nhận được. Tôi hoàn toàn nhận ra rằng câu hỏi này có lẽ là ranh giới giữa một tồn tại trên SO vs programmers.stackexchange, nhưng tôi đã chọn để có nó ở đây sau khi tất cả.

Trả lời

3

Nếu tôi đang đọc tình huống của bạn, có vẻ như bạn sẽ được phục vụ tốt hơn bằng cách tránh thừa kế trên Thing và thay vào đó là các thuộc tính cụ thể theo danh mục như thuộc tính của mối quan hệ giữa Mọi thứ và Danh mục.

gì về một kiến ​​trúc như thế này:

<?php 

class Category { 
    protected $id; 
    protected $title; 
    protected $things; //@ManyToOne(targetEntity="ThingCategory") 
} 

class Thing { 
    protected $id; 
    protected $title; 
    protected $description; 
    protected $category; //@ManyToOne(targetEntity="ThingCategory") 
}  

/** 
* Use [Single|Class]-Table Inheritence to model subject-category attributes. 
* 
* ThingCategory is just a base class. Modules provide concrete subclasses 
* that encapsulate category-specific attributes. 
*/ 
class ThingCategory { 
    protected $id; //surrogate key, not strictly necessary 
    protected $thing; //@ManyToOne(targetEntity="Thing") 
    protected $category //@ManyToOne(targetEntity="Category") 
} 

class ThingMovieCategory extends ThingCategory{ 
    protected $airingStartDate; 
    protected $airingEndDate; 
} 

class ThingCarCategory extends ThingCategory { 
    protected $horespower; 
    protected $numberOfDoors; 
    protected $color; 
} 

Vì vậy, bây giờ mọi thứ có thể di chuyển giữa các loại bằng cách thay thế các thực thể ThingCategory liên kết với nó. Danh tính của Thing không bao giờ thay đổi, chỉ là mối quan hệ với thể loại. Các thuộc tính cần thiết để đưa vào thể loại đó là các thuộc tính của thực thể quan hệ ThingCategory, không phải của chính Thing.

CHỈNH SỬA: Sự cố bạn có thể gặp phải là không có cách nào được sửa đổi tài liệu về bản đồ phân biệt đối tượng khi phân lớp thực thể. Hiệu ứng phụ không may là module cơ sở của bạn sẽ phải biết về mọi mô-đun có thể. Nhưng đó có lẽ không phải là một mối quan tâm lớn. Nếu có, tôi tin rằng nó có thể tránh điều này bằng cách có mỗi mô-đun thao tác ClassMetaData cho thực thể cơ sở, nhưng tôi không bao giờ làm phiền thực sự làm việc đó.

+0

Hey tim, cảm ơn cho đầu vào của bạn, thiết kế đó trông rõ ràng hơn so với những gì tôi đã làm trong ứng dụng của tôi cho đến nay, vì vậy cảm ơn cho đầu vào. Vấn đề tôi thấy (mặc dù tôi có thể sai) vẫn là THAY ĐỔI của một Danh mục. Ví dụ của bạn có tự động cập nhật 'discriminatorColumn' bên trong' Entity' khi một Category khác được chọn không? Tôi chắc chắn sẽ kiểm tra điều này! Tái bút: Để mở rộng DiscriminatorMapping từ một số Mô-đun nhất định: hãy xem [my onBootstrap() của SubModule] (https://github.com/manuakasam/DuitMarketplaceItemVehicle/blob/master/Module.php#L35-L48) – Sam

+1

Sam, tôi không Không nghĩ như vậy, chỉ có một 'Thing' (hoặc 'BaseEntity'). Điều khác biệt 'BaseEntity' từ' MovieEntity' đã được chuyển sang các danh mục khác nhau. Những gì tôi đang thiếu mặc dù trong giải pháp của timdev, là cách lưu trữ các giá trị của các thuộc tính được định nghĩa bởi danh mục cho mỗi 'Điều'. Cần có một thực thể 'ThingCategoryProperty' có một sự xác nhận ManyToOne với' Thing' và 'Category'. Bằng cách này Sam, tôi thích cách bạn giải quyết các nội dung động của 'DiscriminatorMapping'! – netiul

+0

@Sam - Không, khi bạn thay đổi thể loại, bạn xóa một ThingSomeCategory và chèn một số ThingSomeCategory khác. – timdev

1

Vấn đề của bạn là câu này "Nhưng vấn đề chính vẫn là: nếu người dùng thay đổi Danh mục, nó sẽ thay đổi EntityClass và điều đó khá là Không có."

Danh mục sẽ không thực sự thay đổi, danh mục sẽ bị xóa và thay thế bằng danh mục mới. Vì vậy, hãy phản ánh điều này trong mã của bạn, tạo một thực thể mới, lưu giữ nó, cập nhật tất cả các tham chiếu để trỏ đến thực thể mới, và sau đó xóa thực thể cũ.

+0

Tôi sẽ thực hiện nguyên tắc thiết kế này, đơn giản vì nó có nghĩa là những thay đổi nhỏ nhất đối với ứng dụng hiện tại của tôi. Mặc dù tôi chắc chắn sẽ cần phải cấu trúc lại mã tại một thời điểm sau đó khi tôi có nhiều thời gian hơn – Sam