2009-09-23 3 views
4

Для простоты предположим, что у меня есть два класса: класс под названием Car и класс коллекции под названием Tyres. Шины - это вложенный класс внутри класса Car. Я хочу, чтобы дать своим клиентам доступ к коллекции - то есть они должны быть в состоянии итерацию над ним:Вложенные классы Conundrum

foreach(var tire in car.tires) ... 

и доступ к свойствам каждой шины. Но я не хочу давать им доступ к методам в шинах. Я хочу, чтобы весь доступ к такому поведению, чтобы прийти через класс автомобиля:

car.FillTires(); 

Сценарий 1: Шины класса общедоступен методами частного: класс автомобиля не может получить доступ к методам шин.
Сценарий 2: Класс шин является приватным с общедоступными методами: я не могу предоставить коллекцию своим клиентам.
Внутренний язык не работает для меня, поскольку я не хочу предоставлять другим классам доступ к сборке.

ответ

3

Создайте интерфейс только с методами, которые вы хотите, чтобы клиенты могли получить доступ к коллекции типа интерфейса с помощью методов вашего класса.

+1

Хороший ответ, однако сам класс должен быть внутренним/частным. –

+1

Это не проблема для его предложения.Совершенно очевидно публично выставлять экземпляр частного класса, если вы делаете это только через открытый интерфейс. – Joren

+0

Я не сказал, что это проблема, я имел в виду, что она нуждается в разъяснении в ответе. –

2

Вариант 1: Вы можете поместить автомобиль в отдельную сборку и использовать сценарий 1ish (шина может быть общедоступной + метод внутренней).

Вариант 2: Вы могли бы сделать шины неизменны (например, строка) и позволяют потребителям делать все, что они хотят с шинами, но они не могут изменить шины в автомобиле (марка имущества коллекции покрышки в только для чтения, но не делают частное резервное поле только для чтения).

0

Вы можете написать класс FakeTire, который расширяет Tire.

Переопределить FillTires, чтобы исключить исключение из класса FakeTire. У автомобиля есть список настоящих шин, но это свойство Tires создает список Faketires для выдачи. Kindof как сборник только для чтения.

+0

Как предлагает Йорин выше, это меньше идеала. Он достигнет цели соблюдения правил, которые вы хотите, но все равно позволит вам думать, что вы можете изменить факетов, когда на самом деле не можете. – captncraig

3

Простым решением является переоценка, если Tires должен быть внутренним классом. Если вы делаете это обычным классом, вы можете просто использовать internal и public, чтобы различать, какие клиенты и к чему может получить Car.

Если есть неродственная причина, почему Tires должен быть внутренний класс, выставить только только для чтения версии:

  • Expose копии как CMP предлагает (не нужно быть другим класс, хотя это действительно лучше, поэтому вы можете бросить исключения). Мне нравится это предложение наименее, потому что неэлегантно иметь класс, который выглядит так, как будто вы можете его мутировать, а на самом деле вы не можете.
  • сделать весь класс непреложный, как Дэнни говорит, что является эффективным и аккуратным, но делает это менее удобно иметь дело с (необходимости перезаписать старый экземпляр в Car с новым каждый раз, когда вы хотите изменить что-то.)
  • Выставляйте класс только через интерфейс только для чтения, например, Asaph. Мне нравится это лучше всего, потому что он позволяет полностью контролировать систему , ограничивая доступ общественности без каких-либо неудобств или копирования.
Смежные вопросы