Подтвердить что ты не робот

В чем разница между объектами и структурами данных?

Я читал книгу "Чистый код: руководство по гибкому программному мастерству" , а в главе 6 страницы 95-98 разъясняется различия между объектами и структурами данных:

  • Объекты скрывают свои данные за абстракциями и раскрывают функции, которые работают с этими данными. Структуры данных раскрывают свои данные и не имеют значимых функций.

  • Объект обнаруживает поведение и скрывает данные. Это упрощает добавление новых видов объектов без изменения существующего поведения. Это также затрудняет добавление новых типов поведения к существующим объектам.

  • Структуры данных выставляют данные и не имеют существенного поведения. Это упрощает добавление новых типов поведения в существующие структуры данных, но затрудняет добавление новых структур данных в существующие функции.

Я немного путаюсь, являются ли некоторые классы объектами или структурами данных. Скажем, например, HashMaps в java.util, являются ли они объектами? (из-за своих методов, таких как put(), get(), мы не знаем их внутренней работы) или это структуры данных? (Я всегда думал об этом как о структурах данных, потому что их Карта).

Строки также являются структурами данных или объектами?

До сих пор большинство кода, которые я писал, были так называемыми "гибридными классами", которые также старались действовать как объект и структура данных. Любые советы о том, как их избежать?

4b9b3361

Ответ 1

Объект - это экземпляр класса. Класс может моделировать различные вещи из реального мира. Это абстракция чего-то (автомобиль, сокет, карта, связь, ученик, учитель, вы называете это).

Структура данных - это структура, которая упорядочивает определенные данные определенным образом. Вы можете реализовать структуры различными способами, используя классы (что вы делаете на языках, которые не поддерживают OOP, например, вы все равно можете реализовать структуру данных в C let say).

HashMap в java - это класс, который моделирует структуру данных карты с использованием хэш-реализации, поэтому он назывался HashMap.

Socket в java - это класс, который не моделирует структуру данных, а что-то еще (сокет).

Ответ 2

Различие между структурами данных и классами/объектами сложнее объяснить на Java, чем на С++. В C нет классов, только структур данных, которые представляют собой не что иное, как "контейнеры" типизированных и именованных полей. С++ унаследовал эти "структуры", поэтому вы можете иметь как "классические" структуры данных, так и "реальные объекты".

В Java вы можете "эмулировать" структуры данных в стиле С, используя классы, которые не имеют методов и только публичные поля:

public class VehicleStruct
{
    public Engine engine;
    public Wheel[] wheels;
}

Пользователь VehicleStruct знает о деталях, из которых изготовлен автомобиль, и может напрямую взаимодействовать с этими частями. Поведение, т.е. Функции, должно быть определено вне класса. Поэтому легко изменить поведение: добавление новых функций не требует изменения существующего кода. С другой стороны, изменение данных требует изменений практически во всех функциях, взаимодействующих с VehicleStruct. Это нарушает инкапсуляцию!

Идея ООП заключается в том, чтобы скрыть данные и выставить поведение. Он фокусируется на том, что вы можете сделать с автомобилем, не зная, есть ли у него двигатель или сколько колес установлено:

public class Vehicle
{
    private Details hidden;

    public void startEngine() { ... }
    public void shiftInto(int gear) { ... }
    public void accelerate(double amount) { ... }
    public void brake(double amount) { ... }
}

Обратите внимание, что Vehicle может быть мотоциклом, автомобилем, грузовиком или танком - вам не нужно знать детали. Изменение данных легко - никто из класса не знает о данных, поэтому ни один пользователь этого класса не нуждается в изменении. Изменение поведения затруднено: все подклассы должны быть отрегулированы при добавлении новой (абстрактной) функции в класс.

Теперь, следуя "правилам инкапсуляции", вы можете понять, как скрыть данные, просто сделав поля приватными и добавив методы доступа к VehicleStruct:

public class VehicleStruct
{
    private Engine engine;
    private Wheel[] wheels;

    public Engine getEngine() { return engine; }
    public Wheel[] getWheels() { return wheels; }
}

В своей книге дядя Боб утверждает, что, делая это, у вас все еще есть структура данных, а не объект. Вы по-прежнему просто моделируете автомобиль как сумму его частей и подвергаете эти части методам. Это по сути то же самое, что версия с общедоступными полями и простой старый C struct - следовательно, структура данных. Скрыть данные и методы раскрытия недостаточно для создания объекта, вам нужно подумать, действительно ли методы отображают поведение или просто данные!

Когда вы смешиваете два подхода, например. выставляя getEngine() вместе с startEngine(), вы получаете "гибрид". У меня нет книги Мартина, но я помню, что он вообще не рекомендовал гибридов, так как вы попадаете в худшее из обоих миров: объекты, где трудно изменять как данные, так и поведение.

Ваши вопросы, касающиеся HashMaps и Strings, немного сложны, так как они довольно низки и не подходят для классов, которые вы будете писать для своих приложений. Тем не менее, используя приведенные выше определения, вы должны быть в состоянии ответить на них.

A HashMap - это объект. Он раскрывает ваше поведение и скрывает все неприятные подробности хэширования. Вы сообщаете данные put и get, и не заботятся о том, какая функция хэша используется, сколько "ведер" есть и как обрабатываются столкновения. Фактически, вы используете HashMap только через его интерфейс Map, что является хорошим показателем абстракции и "реальных" объектов.

Не путайте, что вы можете использовать экземпляры Карты в качестве замены для структуры данных!

// A data structure
public class Point {
    public int x;
    public int y;
}

// A Map _instance_ used instead of a data structure!
Map<String, Integer> data = new HashMap<>();
data.put("x", 1);
data.put("y", 2);

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

Ответ 3

Как я вижу, то, что Роберт Мартин пытается передать, заключается в том, что объекты не должны раскрывать свои данные через геттеры и сеттеры, если только их единственная цель - действовать как простые контейнеры данных. Хорошими примерами таких контейнеров могут быть java beans, объекты объектов (из сопоставления объектов сущностей DB) и т.д.

Однако классы Java Collection Framework не являются хорошим примером того, на что он ссылается, поскольку они действительно не раскрывают свои внутренние данные (что во многих случаях относится к основным массивам). Он обеспечивает абстракцию, позволяющую извлекать объекты, которые они содержат. Таким образом (в моем POV) они вписываются в категорию "Объекты".

Причины указаны цитатами, которые вы добавили из книги, но есть еще более веские причины для отказа от разоблачения внутренних дел. Классы, которые предоставляют геттеры и сеттеры, например, предлагают нарушения Закона Деметры. Кроме того, зная структуру состояния какого-либо класса (зная, какие геттеры/сеттеры он имеет), уменьшается способность абстрагироваться от реализации этого класса. Существует еще много причин такого рода.

Ответ 4

Вот что, я считаю, Роберт. С. Мартин пытался передать:

  • Структуры данных - это классы, которые просто действуют как контейнеры структурированных данных. Например:

    public class Point {
        public double x;
        public double y;
    }
    
  • Объекты, с другой стороны, используются для создания абстракций. Под абстракцией понимается:

    упрощение чего-то гораздо более сложного, которое происходит под обложками Закон утечек абстракций, Joel on Software

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

    public interface Point {
        double getX();
        double getY();
        void setCartesian(double x, double y);
        double getR();
        double getTheta();
        void setPolar(double r, double theta);
    }
    

    Где мы не знаем, как Точка реализована, но мы знаем, как ее использовать.

Ответ 5

Структура данных - это буквально структурированное представление некоторых данных. Он не имеет встроенных "знаний", кроме структуры и наименования данных. Объект гораздо более общий и действительно может быть практически любой сущностью в вашей системе, которая представляет интерфейс для взаимодействия и может использоваться в разных контекстах. В частности, традиционный объект класса, например, может содержать данные и подходящие методы для доступа к данным и что данные могут быть объектными для экземпляра (для каждого экземпляра) или уровня класса.

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

Ответ 6

Структура данных - это только абстракция, особый способ представления данных. Это просто созданные человеком конструкции, которые помогают снизить сложность на высоком уровне, т.е. Не работать на низком уровне. Объект может показаться одним и тем же, но основное различие между объектами и структурами данных состоит в том, что объект может абстрагировать что угодно. Он также предлагает поведение. Структура данных не имеет никакого поведения, потому что это просто память для хранения данных.

Классы библиотек, такие как Map, List и т.д. являются классами, которые представляют структуры данных. Они реализуют и настраивают структуру данных, чтобы вы могли легко работать с ними в своих программах, создавая их экземпляры (т.е. Объекты).

Ответ 7

Структуры данных (DS) являются абстрактным способом сказать, что структура содержит некоторые данные ". HashMap с некоторыми парами значений ключей представляет собой структуру данных в Java. Связанные массивы аналогично в PHP и т.д. Объекты немного ниже уровня DS. Ваша хэш-карта - это структура данных. теперь для использования хэш-карты вы создаете" объект" и добавляете данные к этому объекту с помощью метода put. У меня может быть собственный класс Employee, у которого есть данные и, следовательно, DS для меня. Но использовать эти DS для выполнения некоторых операций, таких как o посмотреть, является ли сотрудник мужчиной или коллегой-женщиной, мне нужен экземпляр сотрудника и проверить его гендерное свойство.

Не путайте объекты со структурами данных.

Ответ 8

Ваш вопрос помечен как Java, поэтому я буду ссылаться только на Java здесь. Объекты - это класс Eve в Java; то есть все в Java расширяет Object, а объект - это класс.

Поэтому все структуры данных являются объектами, но не все объекты являются структурами данных.

Ключом к разнице является термин "Инкапсуляция".

Когда вы создаете объект на Java, считается наилучшей практикой сделать все ваши члены данных частными. Вы делаете это, чтобы защитить их от тех, кто использует класс.

Однако вы хотите, чтобы люди могли получать доступ к данным, иногда меняя их. Таким образом, вы предоставляете общедоступные методы, называемые accessors и mutators, чтобы позволить им это делать, также называемые getters и seters. Кроме того, вы можете захотеть, чтобы они просмотрели объект в целом в выбранном вами формате, поэтому вы можете определить метод toString; это возвращает строку, представляющую данные объекта.

Структура немного отличается.

Это класс.

Это объект.

Но он обычно является частным в другом классе; Поскольку Node является закрытым в дереве и не должен быть непосредственно доступен пользователю дерева. Однако внутри объекта дерева элементы данных узлов являются общедоступными. Сам Node не нуждается в аксессуарах и мутаторах, поскольку эти функции надежно защищены и защищены объектом дерева.

Ключевые слова для исследования: инкапсуляция, модификаторы видимости

Ответ 9

Объект - это экземпляр класса. Класс может определять набор свойств/полей, которые наследует каждый экземпляр/объект этого класса. Структура данных - это способ организации и хранения данных. Технически структура данных является объектом, но она представляет собой объект с конкретным использованием для хранения других объектов (все в Java - это объект, даже примитивные типы).

Чтобы ответить на ваш вопрос, String - это объект и структура данных. Каждый созданный объект String является экземпляром класса String. Строка, поскольку Java представляет ее внутренне, по существу является массивом символов, а массив - структурой данных.

Не все классы являются чертежами для структур данных, однако все структуры данных являются технически объектами экземпляров AKA класса (специально предназначенных для хранения данных), если это имеет смысл.