对象与数据结构
1 数据抽象
将数据设为 private 的目的就是就是隐藏数据,不被其他人依赖。但是有许多程序员给私有变量添加赋值器和取值器,使之如同公有变量一般。
类并不能简单地用取值器和赋值器将其变量推向外间,而是暴露抽象接口,以便用户无需了解数据的实现就能操作数据本体。
傻乐得乱加取值器和赋值器,是最坏的打算。
例子:
public class Square{
private double x;
private double y;
public Square(double x,double y){
this.x = x;
this.y = y;
}
public double area(){
return x*y;
}
public double perimeter(){
return 2*(x+y);
}
}
2 数据、对象的反对称性
对象把数据隐藏于抽象之后,暴露操作数据的函数。数据结构暴露其数据,没有提供有意义的函数。
过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数。面向对象代码便于在不改动既有函数的前提下添加新类。
过程式代码难以添加新数据结构,因为必须修改所有函数。面向对象代码难以添加新函数,因为必须修改所有类。
面向过程和面向对象是直接对立的,对于面向对象难的事,对于面向过程却是较容易的,反之亦然。
在进行实际的编程中我们的目标是写出优秀的代码,不是要写出完全面向对象或者完全面向过程的代码,在面向对象的编码中可以恰当地使用面向过程的思想,是我们的代码在解决需求的同时更加优秀
例如简单工厂模式就是一个例子
public interface Animal{
void eat();
}
public class Cat implements Animal{
public void eat(){
System.out.print(”吃猫粮“);
}
}
public class Dog implements Animal{
public void eat(){
System.out.print(”吃狗粮“);
}
}
public class AnimalFactory{
public static final int CAT = 0;
public static final int DOG = 1;
public static Animal create(int type){
switch(type){
case CAT:
return new Cat();
break;
case DOG:
return new Dog();
break;
}
}
}
public class test{
public static void main(String []args){
Animal cat = AnimalFactory.create(AnimalFactory.CAT);
cat.eat();
Animal dog = AnimalFactory.create(AnimalFactory.DOG);
dog.eat();
}
3 得墨忒而律
模块不应了解它所操作对象的内部情况。
对象隐藏数据,暴露操作;
方法不应调用由任何函数返回的对象的方法
反面例子:
//该代码风格就像一类火车,一般称之为火车失事,应该避免这种风格
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
String outputFile = outputDir+"/"+className.replace(".","/")+".class";
FileOutputStream fout = new FileOutputStream(outputFile);
BufferOutputStream bos = new BufferOutputStream(fout);
从上面代码可看出取得临时目录绝对路径的目的是为了创建制定名称的临时文件,那么应该由ctxt对象来做这件事,隐藏内部结构
BufferOutputStream bos = ctxt.createScratchFileStream(classFileName);
4 数据传送对象
- 最为精炼的数据结构,是只有一个公共变量、没有函数的类,这种数据结构有时被称为数据传送对象,DTO。
- 一般用于数据库通信,原始数据转换为的数据库的翻译过程
- bean结构拥有由赋值器和取值器操作的私有变量,然而没有什么好处。
- Active Record 是一种特殊的DTO形式,拥有公共变量的数据结构,但通常也拥有类似save和find这样的可浏览方法。
- 可以把Active Record当做数据结构,并创建包含业务规则、隐藏内部数据的独立对象。
5 小结
对象暴露行为,隐藏数据,便于添加新的对象类型无需修改既有行为,却难以在既有对象中添加新行为。
数据结构暴露数据,没有行为,便于添加行为,难以向既有函数添加新的数据结构
开发者可根据实际情况来选择合适的方式,无需死守着一定要面向对象。