2016-12-17 9 views
0

Это вопрос, который я всегда был, но теперь настало время, чтобы решить:Объектно-ориентированное программирование и композиция объектов, как установить свойства композиции?

Я пытаюсь реализовать состав объектов с использованием общественных атрибутов, как:

Person { 
public Car car; 
} 

Owner { 
    public Person person; 
    public Car car; 
} 

Car { 
    public Person person; 
} 

Действительно, мой вопрос: Является ли хорошей практикой устанавливать, что свойства композиции являются государственными или частными?

Разница:

а) Public: делать общественности, доступ быстро и не сложно, потому что мне нужно только сослаться на свойство непосредственно с экземпляром, как:

$instancePerson.car.getNumberOfGearsGood() 

проблема: свойство автомобиля доступно для изменения кем угодно из любого места.

б) Частный: делать частный, доступ, если медленно и необходимо использовать методы, чтобы получить эти свойства, как:

$instancePerson.getCar().getNumberOfGearsGood() 

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

Я знаю, что многие разработчики и разработчики программного обеспечения предпочтут частное решение, но можете ли вы объяснить его там?

+1

Непонятно, какой язык вы используете и что вы написали, не похоже на java или C++. Цель использования геттеров - позволить вам изменить внутреннее представление свойства без изменения вызывающих абонентов и предотвратить непреднамеренную модификацию свойства. – pvg

+0

Язык не важен (возьмите его как пример) и да, я знаю, что вы написали, но мой вопрос о производительности более быстрый, чем Person.car, чем Person.getCar() ... obviusly ... –

+2

Это не содержательный или ответственный вопрос без специфики и, следовательно, принципиально не конкретный вопрос программирования. На некоторых языках и во время выполнения это может иметь последствия для производительности в других, возможно, это не связано с оптимизацией. Вам нужно либо придумать более конкретный вопрос, либо, возможно, принять это к обмену стеками программного обеспечения. – pvg

ответ

-1

Короткий ответ заключается в том, что, за исключением очень немногих случаев, вы хотите, чтобы эти переменные были частными, и часто технологии в JVM будут делать доступ быстрее, чем вы думаете (а иногда даже быстрее, чем в C/C++).
Для получения более подробного ответа:

Главный вопрос: кто должен иметь возможность изменять эти переменные? например, вы можете захотеть создать Car, передав его конструктору Person и никогда не позволять ему изменять (в мире, где нет рынка подержанных автомобилей). В этом случае, если поле открыто, другой объект может изменить его и изменить владельца автомобиля. Но если вы сделаете поле приватным и предоставите метод getOwner(), никто не сможет его изменить. Если метод get равен final и поэтому не может быть переопределен в подклассе, JVM может даже преобразовать внутренне любое обращение x.getOwner() в эквиваленте x.owner. Однако в вашем примере невозможно передать все элементы в конструкторе, поскольку они ссылаются друг на друга. На самом деле, мне кажется, у вашей модели слишком много классов. Давайте попробуем написать это немного по-другому:

Person { 
public Car car; 
} 

Car { 
    public Person owner; 
} 

Теперь, если предположить, что каждый автомобиль имеет владельца, и каждый человек является владельцем автомобиля, эта модель является опасным, потому что вы могли бы сделать что-то вроде этого:

Person p = new Person() 
Car c = new Car(); 
p.car = c; 

Как вы можете видеть, я забыл установить c.owner = p.

Давайте посмотрим, как мы можем это исправить:

Person { 
    private Car car; 
    public void setCar(Car c) { 
    if (car == c) 
     return; 
    car = c; 
    c.setOwner(this); 
    } 
} 

Car { 
    private Person owner; 
    public void setOwner(Person o) { 
    if (o == owner) 
     return; 
    owner = o; 
    o.setCar(this); 
    } 
} 

теперь я могу сделать:

Person p = new Person(); 
Car c = new Car(); 
p.setCar(c); 

или

Person p = new Person(); 
Car c = new Car(); 
c.setOwner(p); 

и в любом случае, как отношения будут установлены правильно.

Другими словами, принуждение к доступу через аксессуар позволяет установить больше, чем просто поле, которое полезно для установления когерентного состояния между элементами модели, связанными с отношениями.

0

Если вы делаете OO, не должно быть такого понятия, как «общедоступный» атрибут. Все атрибуты - это детали реализации объекта, поэтому они скрыты от всех. Публикуются только методы, связанные с ответственностью объекта.

Так что ответить на вопрос:

  • Все «атрибуты» должны быть частным
  • И не должно быть никаких поглотитель на частном атрибуте

Да, там должно быть

person.getCar().getNumberOfGears(); 

Это иногда называют d Law of Demeter. У человека должны быть методы, которые делают вещи, связанные с ответственностью класса Person, поэтому нет атрибутов доступа к производительности, поскольку этот доступ всегда является внутренним для класса и прямого.