Java 编程--代码的选择

来源:互联网 发布:爱淘宝怎么推广 编辑:程序博客网 时间:2024/05/16 14:12

Java 编程–代码的选择

以下几点Java编程建议都是取自Effective Java的.所以本篇也算是Effective Java的读书笔记了。

使用静态工厂方法替代构造器

public class Product {    private static Product computer;    private String name;    public void setName(String name) {        this.name = name;    }    public String getName() {        return this.name;    }    public Product(String name) {        this.name = name;    }    public static Product getComputer(){        return new Product("Computer");    }    public static Product getStaticComputer() {        if (this.computer == null) {            this.computer = new Product("computer");        }        return this.computer;    }}public class Container {    public static void main(String[] args) {        // 1.通过构造器创建“computer”对象        Product computer1 = new Product("computer");        // 2.通过静态工厂方法创建“computer”对象        Product computer2 = Product.getComputer();    }}

好处:
- 静态工厂方法有名称来描述需要创建什么样的对象
- 静态工厂可以觉得是否每次都创建新的对象(代码中getStaticComputer()方法演示了这种情况)
- 静态方法里可以返回原类型的任何子类型对象
缺点:
- 如果类没有共有的构造器, 就无法继承
- 静态工厂方法其实与静态方法没有任何区别

构造器与构建器

public class Product {    private String name;    private float weight;    public Product(String name, float weight) {        this.name = name;        this.weight = weight;    }    public Product(String name) {        this.name = name;    }    public Product(float weight) {        this.weight = weight;    }    private Product(Builder builder) {        setName(builder.name);        setWeight(builder.weight);    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public float getWeight() {        return weight;    }    public void setWeight(float weight) {        this.weight = weight;    }    @Override    public String toString() {        return "Product{" +                "name='" + name + '\'' +                ", weight=" + weight +                '}';    }    /**     * 构建器     */    public static final class Builder {        private String name;        private float weight;        public Builder() {        }        public Builder name(String val) {            name = val;            return this;        }        public Builder weight(float val) {            weight = val;            return this;        }        public Product build() {            return new Product(this);        }    }}

使用构建器的好处是,在有多个参数情况下,如果使用构造器的话就需要多个构造器,而且排列组合很可能产生参数组合爆炸。构建器很容易实例化参数多的情况。但是使用构建器是需要在实例化对象之前实例化构建器对象。所以,这个构建器消耗资源比构造器大。

使用私有构造器或者枚举来强化单例

public class Product {    private static Product instance;    // 私有化构造器,外部只能通过静态工厂方法来实例化单例;    private Product() {    }    public Product getInstance() {        if (instance != null) {            instance = new Product();        }        return instance;    }}

如果不能实例化的类,通过构造器来实现

public class Factory {    private Factory() {        throw new Exception("Factory 不能够被实例化");    }    // 下面这段代码将会报错    public Product getInstance() {        return new Factory();    }}

避免创建不必要的对象

String s = new String("hello world");// String s = "hello world";
public class Person {    private final Date birthDate;    public boolean isBabyBoomer() {        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);        Date boomStart = gmtCal.getTime();        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);        Date boomEnd = gmtCal.getTime();        return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;    }}// 下面的实现方式比上面这种好,因为它避免了对象的重复创建public class Person {    private final Date birthDate;    private static final Date = BOOM_START;    private static final Date = BOOM_END;    static {        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);        Date boomStart = gmtCal.getTime();        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);        Date boomEnd = gmtCal.getTime();        BOOM_START = boomStart;        BOOM_END = boomEnd;    }    public boolean isBabyBoomer() {        return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;    }}

公有类是否暴露公有域

通俗一点,这个问题可以说: JavaBean字段是否用public声明

// 实现一pubic class Point {    public double x;    public double y;}// 实现二pubic class Point {    private double x;    private double y;    public double getX() { return x; }      public double getY() { return y; }    public void setX(double x) { this.x = x; }    public void setY(double y) { this.y = y; }}

以上两种实现让你来评价你选择哪种?

实现一优势:

  • 实现简单
  • 封装数据结构

实现二优势:

  • 封装逻辑
  • 不暴露对数据的操作
0 0
原创粉丝点击