Java 具有内部对象实例化的组合最佳实践
我在玩弄作文,有个问题。假设我有一个Java 具有内部对象实例化的组合最佳实践,java,inheritance,composition,Java,Inheritance,Composition,我在玩弄作文,有个问题。假设我有一个水果和苹果类,其中苹果是水果的传递 public class Apple { Fruit fruit; } 水果有一系列成员字段,如皮肤,颜色等。当我们实例化苹果对象时,最佳做法是什么?我是否应该在内部构造水果对象,而不暴露苹果包含水果对象的任何迹象?i、 e.在构造Apple对象时,我调用Apple.setColor(),它在内部设置fruit.setColor()属性。或者,我是否应该构造完整的水果对象,并在苹果实例化过程中,传入完整构造的水果对
水果
和苹果
类,其中苹果
是水果的传递
public class Apple {
Fruit fruit;
}
水果有一系列成员字段,如
皮肤
,颜色
等。当我们实例化苹果
对象时,最佳做法是什么?我是否应该在内部构造水果
对象,而不暴露苹果包含水果对象的任何迹象?i、 e.在构造Apple对象时,我调用Apple.setColor()
,它在内部设置fruit.setColor()
属性。或者,我是否应该构造完整的水果
对象,并在苹果
实例化过程中,传入完整构造的水果
对象?在苹果中有水果似乎很奇怪。在这种情况下,我将使用继承。或者至少让Apple实现一个Fruit接口并隐藏代理成员。对于构建水果成员,这意味着:在Apple构造函数内部进行。这是因为苹果和水果概念之间的关系
在其他情况下,在构造函数中为成员传递预构造的实例可能会很有用。如果更多的苹果引用同一个水果实例,情况就是如此。一般来说,这更多的是苹果和水果之间的has-a或uses关系,这实际上取决于你如何建模你的问题。但我认为关注OOP的封装原理会对我们有所帮助。封装希望我们隐藏对象本身的信息,或者换句话说,让每个对象负责执行自己的操作
回到你的问题,首先让我们考虑以下的情况:<代码>水果>代码>对象只是一个底层的数据结构(即<代码> Apple < /Cord>对象是一个完整的超集:代码>水果<代码>职责中)。在这种情况下,如果您要求开发人员为您构建
水果
对象并将其传递给您,那么您就暴露了您的内部责任,您可能会让开发人员访问不需要的数据或行为
Fruit f = new Fruit();
f.doSomethingPrivate(); // This is not intended for an Apple to be set externally
Apple a = new Apple(f); // Now the Fruit object may not comply with Apple definition
现在很明显,在某些情况下,上面的示例正是您想要做的事情。现在考虑构图模式(见)。在组合中,您有一个容器,该容器预期不会封装其所包含元素的职责
一个非常简单的例子是大学课程,其中一些学生注册并有一名讲师:
public class Course {
private Person instructor;
private Person[] students;
}
在这里,暴露教师或学生的行为并不是
课程
的目标责任。相反,容器对象可能有get讲师()
和set讲师()
方法,并让开发人员决定组合中包含的元素。为什么您首先希望苹果中有一个水果对象?这只是一个人为的例子,只是在我的问题周围有一些上下文。本质上可以归结为:如果我的外部类中有另一个类的实例,那么最好的做法是在内部或外部配置它。例如,在我的Apple类中,我的颜色Apple.setColor(红色)的setter基本上会在Apple类Apple.getColor中设置水果。setColor(红色)和颜色的getter()将返回水果。getColor()?我之前的评论不准确。在设计Apple类时,通过Apple构造函数将整个水果传递给Apple应该是更好的方法。除非您希望您的Apple更改颜色,否则setter不是一个好主意。从这里得到了这个想法: