2010-10-14 29 views
6

Tôi đã tự hỏi làm thế nào người ta có thể ẩn dữ liệu có điều kiện trong lớp học. Ví dụ: , cho phép nói rằng tôi có một lớp được gọi là Ô tô có ba trường: Engine, MeterReading và Mileage.Làm thế nào để thực hiện đóng gói có điều kiện trong C#

Tôi có ba thực thể khác được gọi là: Trình điều khiển, Cơ khí và Hành khách. Bây giờ những gì tôi muốn là:

A Driver chỉ nên có thể truy cập Mileage (và không Động cơ và MeterReading)

Một Mechanic chỉ sẽ có thể truy cập Công cụ và Mileage (và không MeterReading)

Hành khách chỉ có thể truy cập MeterReading (và không phải Công cụ và Mileage)

Cách tốt nhất để thực hiện điều này là gì .. (không căn cứ toàn bộ logic trên các câu lệnh khác)?

Bất kỳ ý tưởng nào?

Cảm ơn.

Trả lời

4

Tôi sẽ sử dụng explicit interface implementation. Nó ẩn thực hiện giao diện khi đối tượng được truy cập theo loại của nó. Việc triển khai chỉ có thể truy cập khi truy cập bằng giao diện. Trong ví dụ của bạn:

interface IUsableByPassenger 
{ 
    MeterReading MeterReading 
    { 
     get; set; 
    } 
} 

interface IUsableByDriver 
{ 
    Mileage Mileage 
    { 
     get; set; 
    } 
} 

interface IUsableByMechanic : IUsableByDriver 
{ 
    Engine Engine 
    { 
     get; set; 
    } 
} 

class Car : IUsableByMechanic, IUsableByPassenger 
{ 
    Mileage IUsableByDriver.Mileage 
    { 
     // implement mileage access 
    } 

    Engine IUsableByMechanic.Engine 
    { 
     // implement engine access 
    } 

    MeterReading IUsableByPassenger.MeterReading 
    { 
     // implement engine access 
    } 
} 

class Mechanic 
{ 
    public Mechanic(IUsableByMechanic usable) 
    { 
     // usable.MeterReading is not here 
    } 
} 
+0

Tất nhiên cần phải chỉ ra rằng chỉ bảo vệ chống lại tai nạn khi mã hóa, nhưng nó không phải là biện pháp bảo mật đối với các máy khách thù địch vì mã máy khách vẫn có thể tạo một thể hiện 'IUsableByPassenger' thành' Car' và sau đó tới 'IUsableByMechanic' và tất cả những người khác. – Timwi

+0

Chắc chắn, nhưng không có cách nào để tránh điều đó khi phơi bày bất kỳ đối tượng nào có khả năng bằng cách nào đó làm nhiều hơn việc tiếp xúc. Người ta luôn có thể sử dụng sự phản chiếu để tìm một loại, đọc các tư liệu, vv – NOtherDev

+0

@A: Có thể ngăn chặn mã máy khách không tin cậy bằng cách sử dụng sự phản chiếu, nhưng không ngăn cản việc truyền đơn giản. – Timwi

12

Ý tưởng đầu tiên mà bạn nghĩ đến là lớp Car triển khai 3 giao diện khác nhau mà mỗi lớp khác có thể sử dụng để tương tác với lớp học Car của bạn.

Ví dụ, (và tên của tôi chắc chắn có thể được cải thiện khi, nhưng bạn sẽ nhận được các ý tưởng), giao diện IDriverAccess có thể là như sau:

public interface IDriverAccess 
{ 
    double Mileage { get; } 
} 

Giao diện IMechanicAccess có thể là như sau:

public interface IMechanicAccess 
{ 
    EngineObject Engine { get; set; } 

    double Mileage { get; } 
} 

Và cứ tiếp tục như vậy. Lớp xe của bạn sau đó có thể thực hiện các giao diện này, nhưng các lớp học cho người lái xe, thợ máy, hành khách & sẽ chỉ sử dụng các giao diện để tương tác với đối tượng.

public Car : IDriverAccess, IMechanicAccess, IPassengerAccess 
{ 
    // implement the interfaces 
} 
+0

Bạn đã đánh bại tôi đúng giờ! – Aliostad

+3

Tất nhiên cần phải chỉ ra rằng chỉ bảo vệ chống lại tai nạn khi mã hóa, nhưng nó không phải là biện pháp bảo mật đối với các máy khách thù địch vì mã máy khách vẫn có thể truyền một thể hiện 'IDriverAccess' thành' Xe' và truy cập mọi thứ. – Timwi

+1

Nhưng khi bạn thực hiện các giao diện đó một cách ngầm định, lớp 'Xe' bên ngoài' Cơ khí' hoặc 'Trình điều khiển' (tức là khi truy cập bởi khó chịu 'Thief') sẽ vẫn phơi bày mọi thứ. – NOtherDev

2

tôi sẽ tạo ra các giao diện:

public interface IDriviableCar 
{ 
    object Mileage { get; } 
} 

public interface IRepairableCar 
{ 
    object Engine { get; } 
} 

public interface IHirableCar 
{ 
    object MeterReader { get; } 
} 

public class Car : IDriviableCar, IRepairableCar, IHirableCar 
{ 
    private object _mileage; 

    private object _engine; 

    private object _meterReader; 

    public object Mileage 
    { 
     get { return _mileage; } 
    } 

    public object Engine 
    { 
     get { return _engine; } 
    } 

    public object MeterReader 
    { 
     get { return _meterReader; } 
    } 
} 

Và để cho mỗi người sử dụng giao diện để truy cập xe.

+0

Như trên - khi bạn thực hiện giao diện đó một cách ngầm định, lớp 'Xe' bên ngoài' Cơ khí' hoặc 'Trình điều khiển' (tức là khi được truy cập bởi khó chịu' Thief') sẽ vẫn phơi bày mọi thứ. – NOtherDev

+0

Nhưng họ không nên có quyền truy cập vào nó và đó là chìa khóa. – Aliostad

+0

Tất nhiên cần phải chỉ ra rằng chỉ bảo vệ chống lại tai nạn trong khi mã hóa, nhưng nó không phải là biện pháp bảo mật đối với các máy khách thù địch vì mã máy khách vẫn có thể tạo một thể hiện 'IDrivableCar' thành' Xe' và truy cập mọi thứ. – Timwi

2

tạo lớp Giao diện triển khai xe hơi IEngine, ImaterReading và như vậy. Chỉ cấp cho mỗi đối tượng truy cập giao diện specifyc. nói rằng ổ đĩa chỉ có quyền truy cập IMilage, IMilage cơ khí và IEngine.

+0

tại sao downvoted này? – Arseny

+0

Xin lỗi .. đó là tình cờ! – Sennin

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