建设部网站进不去,阿里巴巴网站域名建设,网站建设使用什么软件比较好,宿舍设计方案ppt之前#xff0c;我已经讨论过一些关于Builder模式的信息 #xff0c; Builder Pattern是一种有用的模式#xff0c;用于实例化具有多个#xff08;可能是可选的#xff09;属性的类#xff0c;这些属性可以使读取#xff0c;编写和维护客户端代码更加容易#xff0c;还… 之前我已经讨论过一些关于Builder模式的信息 Builder Pattern是一种有用的模式用于实例化具有多个可能是可选的属性的类这些属性可以使读取编写和维护客户端代码更加容易还有其他好处。 今天我将继续探索对象创建技术但是这次是更一般的情况。 以下面的示例为例除了说明我的观点外它绝不是有用的类。 顾名思义我们有一个RandomIntGenerator类它生成随机的int数。 就像是 public class RandomIntGenerator {private final int min;private final int max;public int next() {...}
} 我们的生成器采用最小值和最大值然后生成这两个值之间的随机数。 注意这两个属性都声明为final因此我们必须在它们的声明或类构造函数中对其进行初始化。 让我们来看一下构造函数 public RandomIntGenerator(int min, int max) {this.min min;this.max max;} 现在我们还希望给客户提供仅指定最小值的可能性然后为该整数生成介于最小值和最大值之间的随机值。 因此我们添加了第二个构造函数 public RandomIntGenerator(int min) {this.min min;this.max Integer.MAX_VALUE;} 到目前为止一切顺利对吗 但是就像我们提供一个仅指定最小值的构造函数一样我们只想为最大值做同样的事情。 我们将只添加第三个构造函数例如 public RandomIntGenerator(int max) {this.min Integer.MIN_VALUE;this.max max;} 如果尝试这样做则会遇到以下编译错误 类型为RandomIntGenerator的重复方法RandomIntGeneratorint 。 怎么了 问题在于根据定义构造函数没有名称。 因此一个类只能具有一个具有给定签名的构造函数而不能具有两个具有相同签名的方法相同的返回类型名称和参数类型。 这就是为什么当我们尝试添加RandomIntGeneratorint max构造函数时会出现该编译错误的原因因为我们已经有了RandomIntGeneratorint min一个。 在这种情况下我们可以做些什么吗 不是构造函数但幸运的是我们可以使用其他方法 静态工厂方法 它们只是返回类实例的公共静态方法。 您可能没有意识到就使用了这种技术。 您曾经使用过Boolean.valueOf吗 看起来像 public static Boolean valueOf(boolean b) {return (b ? TRUE : FALSE);} 将静态工厂应用于我们的RandomIntGenerator示例我们可以获得 public class RandomIntGenerator {private final int min;private final int max;private RandomIntGenerator(int min, int max) {this.min min;this.max max;}public static RandomIntGenerator between(int max, int min) {return new RandomIntGenerator(min, max);}public static RandomIntGenerator biggerThan(int min) {return new RandomIntGenerator(min, Integer.MAX_VALUE);}public static RandomIntGenerator smallerThan(int max) {return new RandomIntGenerator(Integer.MIN_VALUE, max);}public int next() {...}
} 请注意如何使构造函数私有化以确保仅通过其公共静态工厂方法实例化该类。 还要注意当您的客户端使用RandomIntGenerator.between(10,20)而不是new RandomIntGenerator(10,20)时如何清楚地表达您的意图。 值得一提的是该技术与“ 四人帮”中的Factory方法设计模式不同。 任何类都可以提供静态工厂方法来代替构造函数或在构造函数之外提供静态方法。 那么这种技术的优缺点是什么 我们已经提到了静态工厂方法的第一个优点与构造函数不同它们有名称。 这有两个直接的后果 我们可以为构造函数提供一个有意义的名称。 我们可以为多个构造函数提供相同数量和类型的参数就像我们之前看到的那样我们无法使用类构造函数。 静态工厂的另一个优点是与构造函数不同静态工厂不需要在每次调用时都返回新对象。 当使用不可变的类为常用值提供常量对象并避免创建不必要的重复对象时这非常有用。 我之前显示的Boolean.valueOf代码很好地说明了这一点。 请注意此静态方法返回TRUE或FALSE 这两个都是不可变的布尔对象。 静态工厂方法的第三个优点是它们可以返回其返回类型的任何子类型的对象。 这使您可以自由更改退货类型而不会影响客户。 此外您可以隐藏实现类并拥有基于接口的API 这通常是一个好主意。 但是我认为可以通过一个例子更好地看出这一点。 还记得本文开头的RandomIntGenerator吗 让我们稍微复杂一点。 想象一下我们现在不仅要为整数提供随机数生成器还要为其他数据类型如StringDouble或Long提供随机数生成器。 它们都将具有next()方法该方法返回特定类型的随机对象因此我们可以从如下接口开始 public interface RandomGeneratorT {T next();
} 现在我们对RandomIntGenerator第一个实现变为 class RandomIntGenerator implements RandomGeneratorInteger {private final int min;private final int max;RandomIntGenerator(int min, int max) {this.min min;this.max max;}public Integer next() {...}
} 我们还可以有一个String生成器 class RandomStringGenerator implements RandomGeneratorString {private final String prefix;RandomStringGenerator(String prefix) {this.prefix prefix;}public String next() {...}
} 请注意如何将所有类声明为包专用默认范围以及它们的构造函数也是如此。 这意味着包之外的任何客户端都无法创建这些生成器的实例。 那么我们该怎么办 提示它以“静态”开始以“方法”结束。 考虑以下类别 public final class RandomGenerators {// Suppresses default constructor, ensuring non-instantiability.private RandomGenerators() {}public static final RandomGeneratorInteger getIntGenerator() {return new RandomIntGenerator(Integer.MIN_VALUE, Integer.MAX_VALUE);}public static final RandomGeneratorString getStringGenerator() {return new RandomStringGenerator();}
} RandomGenerators只是一个RandomGenerators实用程序类除了静态工厂方法外别无其他。 与不同的生成器位于同一个包中该类可以有效地访问和实例化这些类。 但是有趣的部分到了。 请注意这些方法仅返回RandomGenerator接口而这正是客户端真正需要的。 如果他们获得了RandomGeneratorInteger他们知道可以调用next()并获得一个随机整数。 想象一下下个月我们将编写一个超级高效的新整数生成器。 只要这个新类实现了RandomGeneratorInteger我们就可以更改静态工厂方法的返回类型并且所有客户端现在都在神奇地使用新实现而他们甚至没有注意到更改。 在JDK和第三方库上诸如RandomGenerators类的类都很常见。 您可以在Guava的 Collections 在java.util中 Lists Sets或Maps中查看示例。 命名约定通常是相同的如果您有一个名为Type的接口则将您的静态工厂方法放在一个名为Types不可实例化的类中。 静态工厂的最后一个优点是它们使实例化参数化的类的详细程度降低了很多。 您是否曾经不得不编写过这样的代码 MapString, ListString map new HashMapString, ListString(); 您在同一行代码上重复相同的参数两次。 如果可以从左侧推断出分配的右侧那会很好吗 好吧有了静态工厂就可以。 以下代码摘自Guava的Maps类 public static K, V HashMapK, V newHashMap() {return new HashMapK, V();} 因此现在我们的客户代码变为 MapString, ListString map Maps.newHashMap(); 很好不是吗 此功能称为类型推断 。 值得一提的是Java 7通过使用菱形运算符引入了类型推断。 因此如果您使用的是Java 7则可以将前面的示例编写为 MapString, ListString map new HashMap(); 静态工厂的主要缺点是无法扩展没有公共或受保护的构造函数的类。 但这在某些情况下实际上可能是一件好事因为它鼓励开发人员偏向于继承而不是继承 。 总而言之静态工厂方法提供了很多好处但只有一个缺点当您考虑它时这实际上可能不是问题。 因此抵制自动提供公共构造函数并评估静态工厂是否更适合您的类的冲动。 参考 开发时我们的JCG合作伙伴 Jose Luis的静态工厂方法与传统构造方法的比较 它应该是博客。 翻译自: https://www.javacodegeeks.com/2013/01/static-factory-methods-vs-traditional-constructors.html