打造智能建筑商

构建API时,您应该始终考虑谁将使用它。 当API简单易用时,用户就会感到满意。 当用户满意时,每个人也都会满意。 但是出色的可用性并非总是容易实现的。 有一些模式对此有所帮助,在这篇文章中,我将重点介绍经典的构建器模式,以及如何使用步进构建器模式对其进行增强,以构建没有大脑接口,易于使用且不会出错的对象 。 因此,让我们开始绘制一些上下文,我们有2个域对象代表连接到某个远程或本地服务器的用户配置。 当需要远程凭据时,在本地时。

package com.marco.sbp;
public class UserConfiguration {private final String name;private ServerDetails serverDetails;public UserConfiguration(String name) {this.name = name;}public void setServerDetails(ServerDetails serverDetails) {this.serverDetails = serverDetails;}public String getName() {return name;}public ServerDetails getServerDetails() {return serverDetails;}
}
package com.marco.sbp;
public class ServerDetails {private final String host;private String user;private String password;public ServerDetails(String host) {this.host = host;}public void setUser(String user) {this.user = user;}public void setPassword(String password) {this.password = password;}public String getHost() {return host;}public String getUser() {return user;}public String getPassword() {return password;}
}

我们希望使用两种不同的技术(经典的构建器模式和步骤构建器模式)来抽象上述对象的构造。

经典的构建器模式非常简单,它使用诸如onLocalHost,onRemoteHost等正确命名的方法来掩盖UserConfiguration和ServerDetails的创建。

package com.marco.sbp.builder;
import com.marco.sbp.ServerDetails;
import com.marco.sbp.UserConfiguration;
public class ClassicBuilder {private String name;private String host;private String user;private String password;public ClassicBuilder(String name){this.name = name;}public ClassicBuilder onLocalHost(){this.host = "localhost";return this;}public ClassicBuilder onRemoteHost(String remoteHost){this.host = remoteHost;return this;}public ClassicBuilder credentials(String user, String password){this.user = user;this.password = password;return this;}public UserConfiguration build(){UserConfiguration userConfiguration = new UserConfiguration(name);ServerDetails serverDetails = new ServerDetails(host);serverDetails.setUser(user);serverDetails.setPassword(password);                    userConfiguration.setServerDetails(serverDetails);return userConfiguration;}
}

步骤构建器模式仍在使用智能名称来构造对象,但是仅在需要使用接口和适当的封装时才公开这些方法。

package com.marco.sbp.builder;
import com.marco.sbp.ServerDetails;
import com.marco.sbp.UserConfiguration;/** "Step Builder" */
public class StepBuilder {public static NameStep newBuilder() {return new Steps();}private StepBuilder() {}public static interface NameStep {/*** @param name*            unique identifier for this User Configuration* @return ServerStep*/ServerStep name(String name);}       public static interface ServerStep {/*** The hostname of the server where the User Configuration file is stored will be set to "localhost".* * @return BuildStep*/public BuildStep onLocalhost();/*** The hostname of the server where the User Configuration file is stored.* * @return CredentialsStep*/public CredentialsStep onRemotehost(String host);}public static interface CredentialsStep {/*** Username required to connect to remote machine Password required to connect to remote machine* * @return BuildStep*/public BuildStep credentials(String user, String password);}public static interface BuildStep {/*** @return an instance of a UserConfiguration based on the parameters passed during the creation.*/public UserConfiguration build();}private static class Steps implements NameStep, ServerStep, CredentialsStep, BuildStep {private String name;private String host;private String user;private String password;public BuildStep onLocalhost() {this.host = "localhost";return this;}public ServerStep name(String name) {this.name = name;return null;}public CredentialsStep onRemotehost(String host) {this.host = host;return this;}public BuildStep credentials(String user, String password) {this.user = user;this.password = password;return this;}public UserConfiguration build() {UserConfiguration userConfiguration = new UserConfiguration(name);ServerDetails serverDetails = new ServerDetails(host);serverDetails.setUser(user);serverDetails.setPassword(password);                    userConfiguration.setServerDetails(serverDetails);return userConfiguration;}}
}

现在让我们看一下两个构建器的用户体验。 经典构建器将使用用户配置的名称来构造,然后它将公开其所有方法,从而使用户过于自由,无法选择下一步。

例如,一个不小心的用户可能最终将UserConfiguration设置为localhost,而无需身份验证,仍然传递用户名和密码。

这令人困惑,并且可能导致运行时异常。

这些是用户可以最终得到的UserConfigurations的一些可能组合,其中一些是正确的,很多是错误的:

步骤构建器有一个完全不同的故事,这里仅显示了当时的一个步骤:

如果不需要凭据,则不会公开它们,只有在确保对象状态一致且完整时才提供build()方法:

使用此模式只能构建2个可能的UserConfigurations,它们既有意义又对用户清楚。

结论

步骤构建器模式不是经典Bloch 模式的替代,有时您想强迫用户在进行创建之前填充一些参数,在这种情况下,步骤构建器正在执行此工作,否则,当需要更开放的方法时比经典的建造者更适合您。

参考:从我们的JCG合作伙伴 Marco Castigliego(在“ 删除重复并修复不良名称”博客中) 构建智能构建器 。

翻译自: https://www.javacodegeeks.com/2013/05/building-smart-builders.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合BeautyEye开源UI框架实现的较美观的Java桌面程序

BeautyJavaSwingRobot 结合BeautyEye开源UI框架实现的较美观的Java桌面程序,主要功能就是图灵机器人和一个2345网站万年历的抓取。。。。   挺简单而且实用的一个项目,实现出来的效果也还不错。希望可以学到知识的小可爱不对应该是帅哥,可…

【从入门到放弃】23种设计模式(1):设计模式综述

一、设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、单例模式(Singleton)、建造者模式…

【2017级面向对象程序设计】第2次成绩排行

作业地址 https://edu.cnblogs.com/campus/fzu/OOP/homework/1864 评分标准 1) C 流程图 or 文字描述程序结构 5分C 类图 or 文字描述程序结构 5分2) 代码 共 10 分构造函数 :2 分析构函数 :2 分成员函数 显示当前所处楼层&#x…

css定位position

闲言碎语不多说,直接开写! 关于定位 我们可以使用css的position属性来设置元素定位类型,position的设置项如下: a、relative生成相对定位元素,元素所占据的文档流的位置不变(即元素不会脱离文档流&#x…

php运城,运城php培训

作用域:全局的request恳求   描绘:经过在Global中完成Application_Error办法,来到达侦听未经处置的异常   详细代码如下:sudo dtrace -qFn pid$target:Finding?Ray:Finding?Ray:r{ printf("%s\n", probefunc); } …

利用爬虫模拟网页微信wechat

1.登录页面,显示二维码 当我们打开网页微信时,会看到一个用于扫码登录的二维码,所以我们要模拟该页面给我们的页面也弄一个二维码 通过查看网页代码我们发现,这个二维码的标签为 这个src属性的最后一段每次访问都是不同的&#xf…

爬取饿了么商铺信息

分析: 当我们访问https://www.ele.me/home/时,看看我们得到了什么 1.png我们发现所有的城市名称和他的经纬度,还有一个风流的男子 然后随机输入一些东西看看,进入某个地区看一看 在新的界面里我们看到了这样一条url: https://main…

linux基本命令du,Linux常用操作命令汇总

你还在为不知道Linux常用操作命令汇总而不知所措么?下面来是学习啦小编为大家收集的Linux常用操作命令汇总,欢迎大家阅读:Linux常用操作命令汇总1.ls 命令ls以默认方式显示当前目录文件列表服务器教程ls -a显示所有文件包括隐藏文件ls -l显示文件属性&a…

后处理效果栈

Unity官方的Github实现:Post Processing Stack Post-processing is the process of applying full-screen filters and effects to a camera’s image buffer before it is displayed to screen. It can drastically improve the visuals of your product with litt…

linux 安装tcl命令,TCL/TK Linux下安装 | 勤奋的小青蛙

原创文章,转载请注明: 转载自勤奋的小青蛙本文链接地址: TCL/TK Linux下安装在Linux下安装TCL/TK,可以有编译源代码的方式安装,也可以有直接通过二进制压缩包进行解压缩安装,本文采用比较快捷的方式,用二进…

安全性中的Spring AOP –通过方面控制UI组件的创建

以下文章将显示在我参与的一个项目中,我们如何使用Spring的AOP来介绍一些与安全性相关的功能。 这样的概念是为了使用户能够看到一些UI组件,他需要具有一定级别的安全特权。 如果不满足该要求,则不会显示UIComponent。 让我们看一下项目结构&…

模拟生物自然进化的基因遗传算法

基因遗传算法(Genetic Algorithm,GA)是一种通过模拟生物进化过程来寻找最优解的优化算法。它是一种常见的启发式搜索算法,常用于优化、搜索和机器学习等领域。 生物基因遗传 生物的基因遗传是指父母通过基因传递给子代的过程。基因…

CSS学习笔记11 CSS背景

background-color:背景色 前面我们经常用background-color这个属性来设置元素的背景色,例如下面这条css可将段落的背景色设置为灰色 p {background-color: gray;} 如果想要元素的背景色向外延伸,则只需增加内边距即可 background-color可以为…

linux 文件的目录,Linux文件及目录管理

第七列:文件或目录名。名以 . 开头表示为隐藏文件或隐藏目录2.2 修改文件目录或者权限改变文件所属用户组:chgrpchgrp [-R] 用户组 文件或目录 ...[-R]:递归修改该目录下所有文件和目录;改变文件所有者:chownchown [-R…

套接字(linux相关)

前言:略 一、前因 一切从tcp、udp开始。 众所周知,网络模型一般有两种模型,一种为OSI概念模型(七层),另一种为TCP/IP网络模型(四层)。 TCP/IP应用层对应OSI的应用层、显示层、会话层…

linux查看进程运行日志文件,【Linux】常用指令、ps查看进程、kill杀进程、启动停止tomcat命令、查看日志、查看端口、find查找文件...

1.说出 10 个 linux 常用的指令1) ls 查看目录中的文件2)cd /home 进入 / home 目录;cd .. 返回上一级目录;cd ../.. 返回上两级目录3)mkdir dir1 创建一个叫做 dir1 的目录4)rmdir dir1 删除一个叫做 dir1 的目录 (只能删除空目录)5)rm -f file1 删除一…

Java PDF库

最近,我有一项任务是选择一些Java PDF库用于PDF生成。 但这不是一个简单的任务。 我想到的第一件事是iText。 众所周知Java库具有良好的声誉。 但是...有一些塞子。 iText 5版是在AGPL许可下发布的。 即,如果我们想在商业产品中使用iText,则必…

前端工程师必备的几个实用网站

一、配色类网站 http://colorhunt.co 这个网站给我们提供了很多的配色方案,我们直接使用就OK了。使用方法也很简单,鼠标移动到对应的颜色上,我们就可以看到颜色的十六进制码,复制这个颜色到工具里就可以使用了。 https://webgra…

linux 修改jmeter内存溢出,jmeter本机内存溢出如何修改?

websocket连接过程中内存溢出,本机配置的内存最大和最小设置的512;一、后台返回二、结果树返回:Thread Name: 线程组 1-9Sample Start: 2017-09-11 13:59:49 CSTLoad time: 9006Connect Time: 0Latency: 0Size in bytes: 0Sent bytes:0Header…

JSF:在传统组件和时尚性能杀手之间进行选择

这篇博客文章起源于一个大型Web应用程序中的性能问题。 每个人都优化Java代码,但似乎没有人尝试优化JavaScript代码。 奇怪,因为在客户端有很多改进的空间。 我会说,甚至比服务器端还要多。 我们将分析可编辑的JSF标准组件(有时称…