面向对象的编程和对象组合,如何把组合属性?

时间:2016-12-17 08:45:25

标签: java c++ oop object composition

这是我一直有的问题,但现在是时候解决它了:

我尝试使用公共属性来实现对象的组合,例如:

Person {
 public Car car;
}

Owner {
  public Person person;
  public Car car;
}

Car {
  public Person person;
}

真的我的问题是:将组合属性设置为公共或私有是一种好习惯吗?

区别:

a)公开:公开,访问速度快而且不复杂,因为我只需要直接引用属性,例如:

$instancePerson.car.getNumberOfGearsGood()

问题:任何人都可以修改汽车属性。

b)私有:做私有,访问速度很慢,并且必须使用方法来获取这些属性,如:

$instancePerson.getCar().getNumberOfGearsGood()

当我说慢是因为你需要做一个方法两个方法调用,而在Public解决方案中你只需要做一个。

我知道这里的许多开发人员和软件工程师都更喜欢私有解决方案,但您能解释一下那里的性能吗?

2 个答案:

答案 0 :(得分:0)

如果你正在做OO,那么就不应该有" public"属性。所有属性都是对象的实现细节,因此对每个人都是隐藏的。只有与对象责任相关的方法才是公开的。

所以回答这个问题:

  • 所有"属性"应该是私人的
  • 私有属性
  • 应该没有getter

是的,应该没有

person.getCar().getNumberOfGears();

有时称为Law of Demeter。该人员应该拥有与Person类的职责相关联的方法,因此访问属性没有性能损失,因为这种访问始终是类的内部和直接访问。

答案 1 :(得分:-1)

简短的回答是,除了极少数情况之外,您希望这些变量是私有的,并且JVM中的技术通常会使访问速度超出您的预期(有时甚至比C / C ++更快) 。
有关更详细的答案:

主要问题是:谁应该能够修改这些变量?例如,您可能希望创建CarPerson传递给其构造函数,并且永远不允许此人更改(在没有二手车市场的世界中)。在这种情况下,如果该字段是公共的,则另一个对象可以修改它并更改汽车的所有者。但是如果你将该字段设为私有,并提供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);

并且两种关系都将正确设置。

换句话说,被迫通过访问器允许设置的不仅仅是一个简单的字段,这对于在关系中涉及的模型元素建立连贯状态很有用。