对象和数据结构有什么区别? [英] Whats the difference between objects and data structures?

查看:58
本文介绍了对象和数据结构有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读这本书 清洁代码:敏捷软件工艺手册,在第 6 章第 95-98 页中阐明了对象和数据结构之间的区别:

I've been reading the book Clean Code: A Handbook of Agile Software Craftsmanship and in chapter six pages 95-98 it clarifies about the differences between objects and data structures:

  • 对象将它们的数据隐藏在抽象之后,并公开对这些数据进行操作的函数.数据结构暴露了它们的数据并且没有任何有意义的功能.

  • Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions.

对象公开行为并隐藏数据.这使得在不改变现有行为的情况下轻松添加新类型的对象.这也使得向现有对象添加新行为变得困难.

Object expose behavior and hide data. This makes it easy to add new kinds of objects without changing existing behaviors. It also makes it hard to add new behaviors to existing objects.

数据结构公开数据并且没有重要的行为.这使得向现有数据结构添加新行为变得容易,但使向现有函数添加新数据结构变得困难.

Data structures expose data and have no significant behavior. This makes it easy to add new behaviors to existing data structures but makes it hard to add new data structures to existing functions.

我有点困惑某些类是对象还是数据结构.比如说 java.util 中的 HashMaps,它们是对象吗?(因为像 put()、get() 这样的方法,我们不知道它们的内部工作原理)还是它们是数据结构?(我一直认为它是数据结构,因为它是一个 Map).

I'm a tad bit confused whether some classes are objects or data structures. Say for example HashMaps in java.util, are they objects? (because of its methods like put(), get(), we dont know their inner workings) or are they data structures? (I've always thought of it as data structures because its a Map).

字符串也是,它们是数据结构还是对象?

Strings as well, are they data structures or objects?

到目前为止,我编写的大部分代码都是所谓的混合类",它们试图充当对象和数据结构.关于如何避免它们的任何提示?

So far majority of the code I've been writing have been the so called "hybrid classes" which try to act as an object and a data structure as well. Any tips on how to avoid them as well?

推荐答案

数据结构和类/对象之间的区别在 Java 中比在 C++ 中更难解释.在 C 中,没有类,只有数据结构,它们只不过是类型化和命名字段的容器".C++ 继承了这些结构",因此您可以同时拥有经典"数据结构和真实对象".

The distinction between data structures and classes/objects is a harder to explain in Java than in C++. In C, there are no classes, only data structures, that are nothing more than "containers" of typed and named fields. C++ inherited these "structs", so you can have both "classic" data structures and "real objects".

在 Java 中,您可以使用没有方法而只有公共字段的类来模拟"C 风格的数据结构:

In Java, you can "emulate" C-style data structures using classes that have no methods and only public fields:

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

VehicleStruct 的用户知道车辆的组成部分,并且可以直接与这些部分进行交互.行为,即函数,必须在类之外定义.这就是为什么很容易改变行为的原因:添加新函数不需要改变现有代码.另一方面,更改数据需要更改与 VehicleStruct 交互的几乎每个函数.它违反了封装!

A user of VehicleStruct knows about the parts a vehicle is made of, and can directly interact with these parts. Behavior, i.e. functions, have to be defined outside of the class. That's why it is easy to change behavior: Adding new functions won't require existing code to change. Changing data, on the other hand, requires changes in virtually every function interacting with VehicleStruct. It violates encapsulation!

OOP 背后的想法是隐藏数据并公开行为.它侧重于您可以使用车辆做什么,而无需知道它是否有发动机或安装了多少个车轮:

The idea behind OOP is to hide the data and expose behavior instead. It focuses on what you can do with a vehicle without having to know if it has engine or how many wheels are installed:

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 可以是摩托车、汽车、卡车或坦克 - 您不需要了解详细信息.更改数据很容易——类之外没有人知道数据,因此不需要更改类的用户.改变行为很困难:当一个新的(抽象的)函数被添加到类中时,所有的子类都必须进行调整.

Notice how the Vehicle could be a motorcycle, a car, a truck, or a tank -- you don't need to know the details. Changing data is easy -- nobody outside the class knows about data so no user of the class needs to be changed. Changing behavior is difficult: All subclasses must be adjusted when a new (abstract) function is added to the class.

现在,遵循封装规则",您可以将隐藏数据理解为简单地将字段设为私有并将访问器方法添加到 VehicleStruct:

Now, following the "rules of encapsulation", you could understand hiding the data as simply making the fields private and adding accessor methods to VehicleStruct:

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

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

在他的书中,鲍勃叔叔认为,通过这样做,你仍然拥有一个数据结构,而不是一个对象.您仍然只是将车辆建模为其部件的总和,并使用方法来显示这些部件.它本质上与具有公共字段和普通旧 C struct 的版本相同——因此是一种数据结构.隐藏数据和公开方法不足以创建一个对象,您必须考虑这些方法是真正公开行为还是仅仅公开数据!

In his book, Uncle Bob argues that by doing this, you still have a data structure and not an object. You are still just modeling the vehicle as the sum of its parts, and expose these parts using methods. It is essentially the same as the version with public fields and a plain old C struct -- hence a data structure. Hiding data and exposing methods is not enough to create an object, you have to consider if the methods actually expose behavior or just the data!

当你混合这两种方法时,例如将 getEngine()startEngine() 一起公开,你最终会得到一个混合".我手头没有 Martin 的书,但我记得他根本不推荐混合,因为你最终会遇到两个世界中最糟糕的情况:数据和行为都难以改变的对象.

When you mix the two approaches, e.g. exposing getEngine() along with startEngine(), you end up with a "hybrid". I don't have Martin's Book at hand, but I remember that he did not recommend hybrids at all, as you end up with the worst of both worlds: Objects where both data and behavior is hard to change.

您关于 HashMap 和字符串的问题有点棘手,因为它们的级别非常低,并且不太适合您将为应用程序编写的类.不过,使用上面给出的定义,您应该能够回答它们.

Your questions concerning HashMaps and Strings are a bit tricky, as these are pretty low level and don't fit quite well in the kinds of classes you will be writing for your applications. Nevertheless, using the definitions given above, you should be able to answer them.

HashMap 是一个对象.它向您公开其行为并隐藏所有令人讨厌的散列细节.你告诉它 putget 数据,而不关心使用哪个散列函数,有多少桶",以及如何处理冲突.实际上,您仅通过 Map 接口使用 HashMap,这很好地表明了抽象和真实"对象.

A HashMap is an object. It exposes its behavior to you and hides all the nasty hashing details. You tell it to put and get data, and don't care which hash function is used, how many "buckets" there are, and how collisions are handled. Actually, you are using HashMap solely through its Map interface, which is quite a good indication of abstraction and "real" objects.

不要对可以使用 Map 的实例代替数据结构感到困惑!

Don't get confused that you can use instances of a Map as a replacement for a data structure!

// 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);

另一方面,

String 几乎是一个字符数组,并不会试图隐藏它.我想人们可以称其为一种数据结构,但老实说,我不确定以这种方式或另一种方式是否可以获得很多.

A String, on the other hand, is pretty much an array of characters, and does not try to hide this very much. I guess one could call it a data structure, but to be honest I am not sure if much is to be gained one way or the other.

这篇关于对象和数据结构有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆