博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 空对象_Java中的空对象模式
阅读量:6692 次
发布时间:2019-06-25

本文共 5091 字,大约阅读时间需要 16 分钟。

今天,我正在讨论一种较少使用的模式,称为空对象模式。在面向对象的编程中,我们经常处理空对象。空对象是指没有任何引用的对象或使用中性/空功能/行为定义的对象。在访问任何成员或调用任何方法时,需要检查这些空对象以确保它们不为空。这是因为成员或方法通常无法在空对象上调用。

空对象模式

空对象设计模式描述了空对象的用法及其在系统中的行为。

·

空对象模式处理空对象。

·

·

而不是检查null对象,我们定义了null行为或调用了do-nothing行为。

·

·

这些空对象还可以用于在数据不可用的情况下提供默认行为。

·

·

这种方法优于有效的默认实现的优势在于,空对象非常容易预测,并且没有副作用-它 什么也不做。

·

·

如果资源不可用于测试,则空对象模式还可以用作测试的存根。

·

在使用空对象模式之前,我们应该了解:

·

该模式应谨慎使用。它可以使错误显示为正常程序执行。

·

·

我们不应该仅仅为了避免空检查而使代码更具可读性就实现这种模式。实际上,很难读取移至另一个位置的代码,例如null对象类。

·

·

我们必须执行其他测试以确保没有地方要分配null而不是null对象。

·

让我们看一个例子,以更好地理解这种模式。

空对象的示例

·

创建一个抽象类(或接口)以指定各种功能。我在本示例中使用shape接口。请注意,我也在isNull() 界面中创建了一个方法 。有一个方法很好,而且我喜欢它,因为我可以更好地识别和控制空定义的对象。false 对于所有的具体类,此方法将返回 。并且,它将true 仅针对空对象类返回 。

·

package design.nullobject;

public interface Shape {

double area();

double perimeter();

void draw();

// nice to have method to indicate null object

boolean isNull();

}

您将需要创建一个扩展该类或实现该接口的具体类。每个具体的类都将定义功能的特定版本。我定义三种形状: Circle , Rectangle ,和 Triangle。这些具体的类将定义不同类型的形状。下面是Circle 该类的代码 :

package design.nullobject;

public class Circle implements Shape {

// sides

private final double radius;

public Circle() {

this(1.0d);

}

public Circle(double radius) {

this.radius = radius;

}

@Override public double area() {

// Area = π r^2

return Math.PI * Math.pow(radius, 2);

}

@Override public double perimeter() {

// Perimeter = 2πr

return 2 * Math.PI * radius;

}

@Override public void draw() {

System.out.println("Drawing Circle with area: " + area() + " and perimeter: " + perimeter());

}

@Override

public boolean isNull() {

return false;

}

}

下面是Rectangle 该类的代码 :

package design.nullobject;

public class Rectangle implements Shape {

// sides

private final double width;

private final double length;

public Rectangle() {

this(1.0d ,1.0d);

}

public Rectangle(double width, double length) {

this.width = width;

this.length = length;

}

@Override

public double area() {

// A = w * l

return width * length;

}

@Override

public double perimeter() {

// P = 2(w + l)

return 2 * (width + length);

}

@Override

public void draw() {

System.out.println("Drawing Rectangle with area: " + area() + " and perimeter: " + perimeter());

}

@Override

public boolean isNull() {

return false;

}

}

下面是Triangle 该类的代码 :

package design.nullobject;

public class Triangle implements Shape {

// sides

private final double a;

private final double b;

private final double c;

public Triangle() {

this(1.0d, 1.0d, 1.0d);

}

public Triangle(double a, double b, double c) {

this.a = a;

this.b = b;

this.c = c;

}

@Override

public double area() {

// Using Heron's formula:

// Area = SquareRoot(s * (s - a) * (s - b) * (s - c))

// where s = (a + b + c) / 2, or 1/2 of the perimeter of the triangle

double s = (a + b + c) / 2;

return Math.sqrt(s * (s - a) * (s - b) * (s - c));

}

@Override

public double perimeter() {

// P = a + b + c

return a + b + c;

}

@Override public void draw() {

System.out.println("Drawing Triangle with area: " + area() + " and perimeter: " + perimeter());

}

@Override

public boolean isNull() {

return false;

}

}

现在,最重要的步骤是创建一个空对象类,该对象类扩展了抽象类或接口并定义了“不执行操作”行为。万一数据不可用,“不执行任何操作”行为就像默认行为。

package design.nullobject;

public class NullShape implements Shape {

// no sides

@Override

public double area() {

return 0.0d;

}

@Override

public double perimeter() {

return 0.0d;

}

@Override

public void draw() {

System.out.println("Null object can't be draw");

}

@Override

public boolean isNull() {

return true;

}

}

现在,我们定义 Factory 该类以创建各种类型的形状。请参阅(Java中的策略vs工厂设计模式)以了解工厂模式。我ShapeFactory 为此示例创建 类。

package design.nullobject;

public class ShapeFactory {

public static Shape createShape(String shapeType) {

Shape shape = null;

if ("Circle".equalsIgnoreCase(shapeType)) {

shape = new Circle();

} else if ("Rectangle".equalsIgnoreCase(shapeType)) {

shape = new Rectangle();

} else if ("Triangle".equalsIgnoreCase(shapeType)) {

shape = new Triangle();

} else {

shape = new NullShape();

}

return shape;

}

}

为了使示例简单,我没有在ShapeFactory 方法中收到形状边的参数 。因此,工厂正在创建Shape 具有固定边值的其他 对象。

·

并且,在最后一步,创建一个 Main 类来执行和测试代码:

·

package design.nullobject;

import design.nullobject.ShapeFactory;

public class ShapeMain {

public static void main(String[] args) {

String[] shapeTypes = new String[] { "Circle", null, "Triangle", "Pentagon", "Rectangle", "Trapezoid"};

for (String shapeType : shapeTypes) {

Shape shape = ShapeFactory.createShape(shapeType);

// no null-check required since shape factory always creates shape objects

System.out.println("Shape area: " + shape.area());

System.out.println("Shape Perimeter: " + shape.perimeter());

shape.draw();

System.out.println();

}

}

}

下面是代码的输出:

Shape area: 3.141592653589793

Shape Perimeter: 6.283185307179586

Drawing Circle with area: 3.141592653589793 and perimeter: 6.283185307179586

Shape area: 0.0

Shape Perimeter: 0.0

Null object can't be draw

Shape area: 0.4330127018922193

Shape Perimeter: 3.0

Drawing Triangle with area: 0.4330127018922193 and perimeter: 3.0

Shape area: 0.0

Shape Perimeter: 0.0

Null object can't be draw

Shape area: 1.0

Shape Perimeter: 4.0

Drawing Rectangle with area: 1.0 and perimeter: 4.0

Shape area: 0.0

Shape Perimeter: 0.0

Null object can't be draw

在Java 8中,我们具有 java.util.Optional 处理空引用的类。此类最初来自Guava API。

转载地址:http://xvdoo.baihongyu.com/

你可能感兴趣的文章
Javascript特效代码大全(420个)(转)
查看>>
jQuery闭包之浅见,从面向对象角度来理解
查看>>
(原创)北美信用卡(Credit Card)个人使用心得与总结(个人理财版) [精华]
查看>>
gevent
查看>>
LightOJ 1018 Brush (IV)(记忆化搜索)
查看>>
x264编码参数大测试:03 subme与crf(c)
查看>>
对自然数的有限区间散列
查看>>
低端路由器和高端路由的区别
查看>>
android webview 播放swf 失败<彻底解决黑框>
查看>>
应用程序实例——用户信息管理
查看>>
中文分词 mmseg4j 在 lucene 中的使用示例
查看>>
volley 发送post请求
查看>>
ti processor sdk linux am335x evm /bin/setup-uboot-env.sh hacking
查看>>
php 操作数组 (合并,拆分,追加,查找,删除等)
查看>>
[Hibernate] - EAGER and LAZY
查看>>
python 异常类型
查看>>
CentOS进入图形界面
查看>>
C#--web services之wsdl文件生成cs
查看>>
配置Apache+Tomcat实现SSO(单点登录)
查看>>
《Pro ASP.NET MVC 3 Framework》学习笔记之十五【示例项目SportsStore】
查看>>