编程语言
首页 > 编程语言> > java-考虑添加静态接口方法以提供用于对象创建的单个入口点

java-考虑添加静态接口方法以提供用于对象创建的单个入口点

作者:互联网

“实现” below是否表示对象的实例?也许它们是指执行代码.

Consider adding static interface methods, to allow the client code to
create (potentially specialized) objects that implement the interface.
For example, if we have an interface Point with two methods int x()
and int y(), then we can expose a static method Point.of(int x, int y)
that produces a (hidden) implementation of the interface.

So, if x and y are both zero, we can return a special implementation
class PointOrigoImpl (with no x or y fields), or else we return
another class PointImpl that holds the given x and y values. Ensure
that the implementation classes are in another package that are
clearly not a part of the API (e.g. put the Point interface in
com.company. product.shape and the implementations in
com.company.product.internal.shape).

Do This:

Point point = Point.of(1,2);

Don’t Do This:

Point point = new PointImpl(1,2);

这样做的好处是可以封装吗?但是,如果实现是私有的程序包而不是API的一部分,那不会造成访问问题吗?如果客户端,“世界”如下:

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

没有访问Point的实现的权限,那么如何才能像上面那样为“执行此操作”实例化一个新的Point?

解决方法:

For example, if we have an interface Point with two methods int x()
and int y(), then we can expose a static method Point.of(int x, int y)
that produces a (hidden) implementation of the interface.

1)请注意,由于Java 8,您可以在接口中添加静态方法,但是不能.

2)我在理解此建议时遇到一些困难:

So, if x and y are both zero, we can return a special implementation
class PointOrigoImpl (with no x or y fields), or else we return
another class PointImpl that holds the given x and y values. Ensure
that the implementation classes are in another package that are
clearly not a part of the API (e.g. put the Point interface in
com.company. product.shape and the implementations in
com.company.product.internal.shape).

这是一个与您引用的文本匹配的Point类示例:

package com.company.product.shape;

import com.company.product.internal.shape.PointOrigoImpl;
import com.company.product.internal.shape.PointImpl;

public interface Point{
   int x();
   int y();     
   static Point of(int x, int y) {
      if (x == 0 && y == 0){
         return new PointOrigoImpl();
      }
      return new PointImpl(x, y);
  }
}

如果将Point接口提供给客户端并且声明了工厂方法,则为了进行精细编译,PointInterface必须具有对PointOrigoImpl和PointImpl类的可见性才能实例化它们.

由于Point接口和子类位于两个不同的包(com.company.product.shape和com.company.product.internal.shape)中,
这意味着PointImpl和PointOrigoImpl应该具有公共构造函数,否则Point无法实例化它们.
最后,操纵Point的客户端还可以实例化PointImpl和PointOrigoImpl子类的构造函数.

它违反了工厂的目的,该工厂不想公开实现以选择要返回的实现.

接口是公共的,旨在使客户端可以完全访问.
因此,一般而言,它不应包含我们不想向客户公开的实现.

3)在这里:

The advantage being that this enforces encapsulation? However, if the
implementation is package private and not part of the API, would that
not create access problems? If the client, “world” as here:
doesn’t have access to the implementation of Point then how can it
possibly instantiate a new Point as above for “do this”?

我想你想知道为什么文本说:
 确保实现类在另一个显然不是API一部分的程序包中.

在您引用的文本中,作者希望让Point客户知道该接口,但是他不想让Point子类知道,因为他想根据工厂Point中使用的参数决定要返回的Point子类. .

点客户端将仅知道此界面.

在Java中,为了不提供对实现类的访问,可以使用公共类,接口和内部私有类:

>公共类暴露给客户端以调用返回实现的工厂方法
>接口类是众所周知的,与实现无关.
>内部私人阶层成为公共阶层的一部分.客户看不到它,但是工厂看到它以返回适当的实现.

对于您所引用的示例,它将很简单.

点(接口):

public interface Point{
   int x();
   int y();            
}

点工厂(包含私有类的公共类):

public final class PointFactory {

    // private classes
    private class PointImpl implements Point {

        private int x;
        private int y;

        private PointImpl(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int x() {
            return x;
        }

        public int y() {
            return y;
        }
    }

    private class PointOrigoImpl implements Point {

        public int x() {
            return 0;
        }

        public int y() {
            return 0;
        }
    }

    // end private classes

    public Point of(int x, int y) {
        if (x == 0 && y == 0) {
            return new PointOrigoImpl();
        }
        return new PointImpl(x, y);
    }

}

标签:java-8,oop,instantiation,factory-pattern,java
来源: https://codeday.me/bug/20191111/2022050.html