当前位置: 首页 > news >正文

中国建设银行国际互联网网站网站是用什么做的

中国建设银行国际互联网网站,网站是用什么做的,辽宁招标网招标公告,osCommerce购物网站架设全攻略设计模式 在平时的开发中#xff0c;涉及到设计模式的有两块内容#xff1a; 我们平时使用的框架#xff08;比如spring、mybatis等#xff09;我们自己开发业务使用的设计模式。 在平时的业务开发中#xff0c;其实真正使用设计模式的场景并不多#xff0c;虽然设计号…设计模式 在平时的开发中涉及到设计模式的有两块内容 我们平时使用的框架比如spring、mybatis等我们自己开发业务使用的设计模式。 在平时的业务开发中其实真正使用设计模式的场景并不多虽然设计号称有23种之多不同的纬度可能会更多不同程序员看法也不同 但是在项目最常使用的也就几种而已在面试的过程中我们主要介绍一种或两种就可以也不会把你会的都问一遍 重点什么设计模式应对什么业务场景 本文重点介绍三种设计模式 工厂模式简单工厂、工厂方法、抽象工厂策略模式责任链模式 还有单例模式、建造者模式在开发中的案例但是不作为重点讲解 1. 工厂模式 1.1 概述 需求设计一个咖啡店点餐系统。 设计一个咖啡类Coffee并定义其两个子类 美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】 再设计一个咖啡店类CoffeeStore咖啡店具有点咖啡的功能。 具体类的设计如下 类图中的符号 表示public-表示private#表示protected 泛化关系(继承)用带空心三角箭头的实线来表示 依赖关系使用带箭头的虚线来表示 package com.itheima.factory.simple;public class CoffeeStore {public static void main(String[] args) {Coffee coffee orderCoffee(latte);System.out.println(coffee.getName());}public static Coffee orderCoffee(String type){Coffee coffee null;if(american.equals(type)){coffee new AmericanCoffee();}else if (latte.equals(type)){coffee new LatteCoffee();}//添加配料coffee.addMilk();coffee.addSuqar();return coffee;} }在 Java 中万物皆对象这些对象都需要创建如果需要实例的时候直接 new 该对象就会对该对象耦合严重 假如我们要更换对象所有 new 对象的地方都需要修改一遍这显然违背了软件设计的开闭原则。 如果我们使用工厂来生产对象我们就只和工厂打交道就可以了彻底和对象解耦如果要更换对象直接在工厂里更换该对象即可达到了与对象解耦的目的 所以说工厂模式最大的优点就是解耦。 开闭原则对扩展开放对修改关闭。在程序需要进行拓展的时候不能去修改原有的代码实现一个热插拔的效果。简言之是为了使程序的扩展性好易于维护和升级。 三种工厂模式 简单工厂模式工厂方法模式抽象工厂模式 1.2 简单工厂模式 简单工厂比较像是一种编程习惯。 1.2.1 结构 简单工厂包含如下角色 抽象产品 定义了产品的规范描述了产品的主要特性和功能。 具体产品 实现或者继承抽象产品的子类 具体工厂 提供了创建产品的方法调用者通过该方法来获取产品。 1.2.2 实现 现在使用简单工厂对上面案例进行改进类图如下 工厂类代码如下 public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {Coffee coffee null;if(americano.equals(type)) {coffee new AmericanoCoffee();} else if(latte.equals(type)) {coffee new LatteCoffee();}return coffee;} }咖啡店 package com.itheima.factory.simple;public class CoffeeStore {public Coffee orderCoffee(String type){//通过工厂获得对象不需要知道对象实现的细节SimpleCoffeeFactory factory new SimpleCoffeeFactory();Coffee coffee factory.createCoffee(type);//添加配料coffee.addMilk();coffee.addSuqar();return coffee;} }工厂factory处理创建对象的细节一旦有了 SimpleCoffeeFactoryCoffeeStore 类中的 orderCoffee() 就变成此对象的客户后期如果需要 Coffee 对象直接从工厂中获取即可。 这样也就解除了和 Coffee 实现类的耦合 同时又产生了新的耦合CoffeeStore 对象和 SimpleCoffeeFactory 工厂对象的耦合工厂对象和商品对象的耦合。 后期如果再加新品种的咖啡我们势必要需求修改 SimpleCoffeeFactory 的代码违反了开闭原则。工厂类的客户端可能有很多比如创建美团外卖等这样只需要修改工厂类的代码省去其他的修改操作。 1.2.3 优缺点 优点 封装了创建对象的过程可以通过参数直接获取对象。把对象的创建和业务逻辑层分开这样以后就避免了修改客户代码如果要实现新产品直接修改工厂类而不需要在原代码中修改这样就降低了客户代码修改的可能性更加容易扩展。 缺点 增加新产品时还是需要修改工厂类的代码违背了“开闭原则”。 1.2.4 扩展 静态工厂 在开发中也有一部分人将工厂类中的创建对象的功能定义为静态的这个就是静态工厂模式它也不是23种设计模式中的。代码如下 public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {Coffee coffee null;if(americano.equals(type)) {coffee new AmericanoCoffee();} else if(latte.equals(type)) {coffee new LatteCoffee();}return coffe;} }1.3 工厂方法模式 针对上例中的缺点使用工厂方法模式就可以完美的解决完全遵循开闭原则。 1.3.1 概念 定义一个用于创建对象的接口让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。 1.3.2 结构 工厂方法模式的主要角色 抽象工厂Abstract Factory提供了创建产品的接口调用者通过它访问具体工厂的工厂方法来创建产品。 具体工厂ConcreteFactory主要是实现抽象工厂中的抽象方法完成具体产品的创建。 抽象产品Product定义了产品的规范描述了产品的主要特性和功能。 具体产品ConcreteProduct实现了抽象产品角色所定义的接口由具体工厂来创建它同具体工厂之间一一对应。 1.3.3 实现 使用工厂方法模式对上例进行改进类图如下 流程 代码如下 抽象工厂 public interface CoffeeFactory {Coffee createCoffee(); }具体工厂 public class LatteCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new LatteCoffee();} }public class AmericanCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new AmericanCoffee();} }咖啡店类 public class CoffeeStore {private CoffeeFactory factory;public CoffeeStore(CoffeeFactory factory) {this.factory factory;}public Coffee orderCoffee() {Coffee coffee factory.createCoffee();coffee.addMilk();coffee.addsugar();return coffee;} }从以上的编写的代码可以看到要增加产品类时也要相应地增加工厂类不需要修改工厂类的代码了这样就解决了简单工厂模式的缺点。 工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性工厂方法模式保持了简单工厂模式的优点而且克服了它的缺点。 在线程池中也使用了这个设计模式去生产 Thread 1.3.4 优缺点 优点 用户只需要知道具体工厂的名称就可得到所要的产品无须知道产品的具体创建过程在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类无须对原工厂进行任何修改满足开闭原则 缺点 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类这增加了系统的复杂度。 1.4 抽象工厂模式 前面介绍的工厂方法模式中考虑的是一类产品的生产如畜牧场只养动物、电视机厂只生产电视机、传智播客只培养计算机软件专业的学生等。 这些工厂只生产同种类产品同种类产品称为同等级产品也就是说工厂方法模式只考虑生产同等级的产品但是在现实生活中许多工厂是综合型的工厂能生产多等级种类 的产品如电器厂既生产电视机又生产洗衣机或空调大学既有软件专业又有生物专业等。 本节要介绍的抽象工厂模式将考虑多等级产品的生产将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族下图所示 产品族一个品牌下面的所有产品例如华为下面的电脑、手机称为华为的产品族产品等级多个品牌下面的同种产品例如华为和小米都有手机电脑为一个产品等级 1.4.1 概念 是一种为访问类提供一个创建一组相关或相互依赖对象的接口且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 抽象工厂模式是工厂方法模式的升级版本工厂方法模式只生产一个等级的产品而抽象工厂模式可生产多个等级的产品。 一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂 1.4.2 结构 抽象工厂模式的主要角色如下 抽象工厂Abstract Factory提供了创建产品的接口它包含多个创建产品的方法可以创建多个不同等级的产品。 具体工厂Concrete Factory主要是实现抽象工厂中的多个抽象方法完成具体产品的创建。 抽象产品Product定义了产品的规范描述了产品的主要特性和功能抽象工厂模式有多个抽象产品。 具体产品ConcreteProduct实现了抽象产品角色所定义的接口由具体工厂来创建它同具体工厂之间是多对一的关系。 1.4.3 实现 现咖啡店业务发生改变不仅要生产咖啡还要生产甜点 同一个产品等级产品分类 咖啡拿铁咖啡、美式咖啡甜点提拉米苏、抹茶慕斯 同一个风味就是同一个产品族相当于同一个品牌 美式风味美式咖啡、抹茶慕斯意大利风味拿铁咖啡、提拉米苏 要是按照工厂方法模式 需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类很容易发生类爆炸情况。 所以这个案例可以使用抽象工厂模式实现。类图如下 实现关系使用带空心三角箭头的虚线来表示 整体调用思路 1.4.4 优缺点 优点 当一个产品族中的多个对象被设计成一起工作时它能保证客户端始终只使用同一个产品族中的对象。 缺点 当产品族中需要增加一个新的产品时所有的工厂类都需要进行修改。 1.4.5 使用场景 当需要创建的对象是一系列相互关联或相互依赖的产品族时如电器工厂中的电视机、洗衣机、空调等。系统中有多个产品族但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。系统中提供了产品的类库且所有产品的接口相同客户端不依赖产品实例的创建细节和内部结构。 如输入法换皮肤一整套一起换。生成不同操作系统的程序。 2 策略模式 先看下面的图片我们去旅游选择出行模式有很多种可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 定义 该模式定义了一系列算法并将每个算法封装起来使它们可以相互替换且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式它通过对算法进行封装把使用算法的责任和算法的实现分割开来并委派给不同的对象对这些算法进行管理。 2.2 结构 策略模式的主要角色如下 抽象策略Strategy类这是一个抽象角色通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略Concrete Strategy类实现了抽象策略定义的接口提供具体的算法实现或行为。环境Context类持有一个策略类的引用最终给客户端调用。 2.3 案例实现 【例】促销活动 一家百货公司在定年度的促销活动。针对不同的节日春节、中秋节、圣诞节推出不同的促销活动由促销员将促销活动展示给客户。类图如下 聚合关系可以用带空心菱形的实线来表示 代码如下 定义百货公司所有促销活动的共同接口 public interface Strategy {void show(); }定义具体策略角色Concrete Strategy每个节日具体的促销活动 //为春节准备的促销活动A public class StrategyA implements Strategy {public void show() {System.out.println(买一送一);} }//为中秋准备的促销活动B public class StrategyB implements Strategy {public void show() {System.out.println(满200元减50元);} }//为圣诞准备的促销活动C public class StrategyC implements Strategy {public void show() {System.out.println(满1000元加一元换购任意200元以下商品);} }定义环境角色Context用于连接上下文即把促销活动推销给客户这里可以理解为销售员 public class SalesMan { //持有抽象策略角色的引用 private Strategy strategy; public SalesMan(Strategy strategy) { this.strategy strategy; } //向客户展示促销活动 public void salesManShow(){ strategy.show(); } } 2.4 综合案例 2.4.1 概述 多种方式可以进行登录 用户名密码登录 短信验证码登录 微信登录 QQ登录 … 2.4.2 代码示例 登录接口说明 说明请求方式POST路径/api/user/login参数LoginReq返回值LoginResp 请求参数LoginReq Data public class LoginReq {private String name;private String password;private String phone;private String validateCode;//手机验证码private String wxCode;//用于微信登录/*** account : 用户名密码登录* sms : 手机验证码登录* we_chat : 微信登录*/private String type; }响应参数LoginResp Data public class LoginResp{private Integer userId;private String userName;private String roleCode;private String token; //jwt令牌private boolean success;}控制层LoginController RestController RequestMapping(/api/user) public class LoginController {Autowiredprivate UserService userService;PostMapping(/login)public LoginResp login(RequestBody LoginReq loginReq){return userService.login(loginReq);} }业务层UserService Service public class UserService {public LoginResp login(LoginReq loginReq){if(loginReq.getType().equals(account)){System.out.println(用户名密码登录);//执行用户密码登录逻辑return new LoginResp();}else if(loginReq.getType().equals(sms)){System.out.println(手机号验证码登录);//执行手机号验证码登录逻辑return new LoginResp();}else if (loginReq.getType().equals(we_chat)){System.out.println(微信登录);//执行用户微信登录逻辑return new LoginResp();}LoginResp loginResp new LoginResp();loginResp.setSuccess(false);System.out.println(登录失败);return loginResp;} }注意我们重点讲的是设计模式并不是登录的逻辑所以以上代码并没有真正的实现登录功能 问题分析 业务层代码大量使用到了if…else在后期阅读代码的时候会非常不友好大量使用if…else性能也不高如果业务发生变更比如现在新增了 QQ 登录方式这个时候需要修改业务层代码违反了开闭原则 解决 使用 工厂方法设计模式策略模式 解决 2.4.3 代码改造工厂策略 整体思路 改造之后不在service中写业务逻辑让service调用工厂然后通过service传递不同的参数来获取不同的登录策略登录方式 具体实现 抽象策略类UserGranter /*** 抽象策略类*/ public interface UserGranter{/*** 获取数据* param loginReq 传入的参数* return map值*/LoginResp login(LoginReq loginReq);}具体的策略AccountGranter、SmsGranter、WeChatGranter /*** 策略账号登录**/ Component public class AccountGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为账号登录 loginReq);// TODO// 执行业务操作 return new LoginResp();} } /*** 策略:短信登录*/ Component public class SmsGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为短信登录 loginReq);// TODO// 执行业务操作return new LoginResp();} } /*** 策略:微信登录*/ Component public class WeChatGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为微信登录 loginReq);// TODO// 执行业务操作return new LoginResp();} }工程类UserLoginFactory /*** 操作策略的上下文环境类 工具类* 将策略整合起来 方便管理*/ Component public class UserLoginFactory implements ApplicationContextAware {private static MapString, UserGranter granterPool new ConcurrentHashMap();Autowiredprivate LoginTypeConfig loginTypeConfig;/*** 从配置文件中读取策略信息存储到map中* {* account:accountGranter,* sms:smsGranter,* we_chat:weChatGranter* }** param applicationContext* throws BeansException*/Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {loginTypeConfig.getTypes().forEach((k, y) - {granterPool.put(k, (UserGranter) applicationContext.getBean(y));});}/*** 对外提供获取具体策略** param grantType 用户的登录方式需要跟配置文件中匹配* return 具体策略*/public UserGranter getGranter(String grantType) {UserGranter tokenGranter granterPool.get(grantType);return tokenGranter;}}在application.yml文件中新增自定义配置 login:types:account: accountGrantersms: smsGranterwe_chat: weChatGranter新增读取数据配置类 Getter Setter Configuration ConfigurationProperties(prefix login) public class LoginTypeConfig {private MapString,String types;} 改造service代码 Service public class UserService {Autowiredprivate UserLoginFactory factory;public LoginResp login(LoginReq loginReq){UserGranter granter factory.getGranter(loginReq.getType());if(granter null){LoginResp loginResp new LoginResp();loginResp.setSuccess(false);return loginResp;}LoginResp loginResp granter.login(loginReq);return loginResp;} }大家可以看到我们使用了设计模式之后业务层的代码就清爽多了如果后期有新的需求改动比如加入了QQ登录我们只需要添加对应的策略就可以无需再改动业务层代码。 2.4.4 举一反三 其实像这样的需求在日常开发中非常常见场景有很多以下的情景都可以使用工厂模式策略模式解决比如 订单的支付策略 支付宝支付微信支付银行卡支付现金支付 解析不同类型excel xls格式xlsx格式 打折促销 满300元9折满500元8折满1000元7折 物流运费阶梯计算 5kg以下5kg-10kg10kg-20kg20kg以上 一句话总结只要代码中有冗长的 if-else 或 switch 分支判断都可以采用策略模式优化 2.5 Spring 的 SPI Component public class LoginServiceSelector {public static final String WX_LOGIN_TYPE WX_JWT; // r6Vsr0public static final String EMAIL_LOGIN_TYPE EMAIL_JWT; // Rl0p0rprivate final ServiceLoaderLoginService loginServices ServiceLoader.load(LoginService.class);public LoginService select(String type) {// 选取服务for (LoginService loginService : loginServices) {if (loginService.match(type)) {return loginService;}}throw new GlobalServiceException(GlobalServiceStatusCode.REQUEST_NOT_VALID);}}10分钟让你彻底明白Java SPI附实例代码演示#安员外很有码_哔哩哔哩_bilibili JavaSPI机制你真的懂吗来看看动画版通俗易懂SPI机制讲解_哔哩哔哩_bilibili 3. 责任链模式 3.1 概述 在现实生活中常常会出现这样的事例 一个请求有多个对象可以处理但每个对象的处理条件或权限不同。例如公司员工请假可批假的领导有部门负责人、副总经理、总经理等但每个领导能批准的天数不同员工必须根据自己要请假的天数去找不同的领导签名也就是说员工必须记住每个领导的姓名、电话和地址等信息这增加了难度。 这样的例子还有很多如找领导出差报销、生活中的“击鼓传花”游戏等。 定义 又名职责链模式为了避免请求发送者与多个请求处理者耦合在一起将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链 当有请求发生时可将请求沿着这条链传递直到有对象处理它为止。 该请求的数据经过一系列的处理者找到负责的人或者是一步步地被加工/被消耗/被处理像流水线一样 比较常见的springmvc中的拦截器web开发中的filter过滤器 3.2 结构 职责链模式主要包含以下角色: 抽象处理者Handler角色定义一个处理请求的接口包含抽象处理方法和一个后继连接。具体处理者Concrete Handler角色实现抽象处理者的处理方法判断能否处理本次请求如果可以处理请求则处理否则将该请求转给它的后继者。客户类Client角色创建处理链并向链头的具体处理者对象提交请求它不关心处理细节和请求的传递过程。 3.2 案例实现 处理订单的操作 类图 代码 抽象处理者 package com.itheima.designpattern.chain;/*** 抽象处理者*/ public abstract class Handler {protected Handler handler;public void setNext(Handler handler) {this.handler handler;}/*** 处理过程* 需要子类进行实现*/public abstract void process(OrderInfo order); }订单信息类 package com.itheima.designpattern.chain;import java.math.BigDecimal;public class OrderInfo {private String productId;private String userId;private BigDecimal amount;public String getProductId() {return productId;}public void setProductId(String productId) {this.productId productId;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId userId;}public BigDecimal getAmount() {return amount;}public void setAmount(BigDecimal amount) {this.amount amount;} }具体处理者 /*** 订单校验*/ public class OrderValidition extends Handler {Overridepublic void process(OrderInfo order) {System.out.println(校验订单基本信息);//校验handler.process(order);}}/*** 补充订单信息*/ public class OrderFill extends Handler {Overridepublic void process(OrderInfo order) {System.out.println(补充订单信息);handler.process(order);}}/*** 计算金额*/ public class OrderAmountCalcuate extends Handler {Overridepublic void process(OrderInfo order) {System.out.println(计算金额-优惠券、VIP、活动打折);handler.process(order);}}/*** 订单入库*/ public class OrderCreate extends Handler {Overridepublic void process(OrderInfo order) {System.out.println(订单入库);} } 客户类 public class Application {public static void main(String[] args) {//检验订单Handler orderValidition new OrderValidition();//补充订单信息Handler orderFill new OrderFill();//订单算价Handler orderAmountCalcuate new OrderAmountCalcuate();//订单落库Handler orderCreate new OrderCreate();//设置责任链路orderValidition.setNext(orderFill);orderFill.setNext(orderAmountCalcuate);orderAmountCalcuate.setNext(orderCreate);//开始执行orderValidition.process(new OrderInfo());}}3.3 优缺点 优点 降低了对象之间的耦合度 该模式降低了请求发送者和接收者的耦合度。 增强了系统的可扩展性 可以根据需要增加新的请求处理类满足开闭原则。 增强了给对象指派职责的灵活性 当工作流程发生变化可以动态地改变链内的成员或者修改它们的次序也可动态地新增或者删除责任。 责任链简化了对象之间的连接 一个对象只需保持一个指向其后继者的引用不需保持其他所有处理者的引用这避免了使用众多的 if 或者 if···else 语句。 责任分担 每个类只需要处理自己该处理的工作不能处理的传递给下一个对象完成明确各类的责任范围符合类的单一职责原则。 缺点 不能保证每个请求一定被处理。由于一个请求没有明确的接收者所以不能保证它一定会被处理该请求可能一直传到链的末端都得不到处理。对比较长的职责链请求的处理可能涉及多个处理对象系统性能将受到一定影响。职责链建立的合理性要靠客户端来保证增加了客户端的复杂性可能会由于职责链的错误设置而导致系统出错如可能会造成循环调用。 3.4 举一反三 内容审核视频、文章、课程…. 任务分段顺序执行一步步消费可以用本地线程对象进行线程内部责任链节点之间的数据共享 订单创建一步步加工 简易流程审批直到负责人处理了 等等还有很多场景如果你觉得可以用责任链可以解耦可以提高扩展性那就试一下吧 4. 补充单例模式案例 比如这个场景访问一些微信接口需要有 ACCESS_TOKEN由于需要经常调用或者更新所以用到单例模式 只实例化一个对象并提供一个全局访问点 Getter Setter public class AccessToken {private String token;private long expireIn;//有效期限volatile private static AccessToken ACCESS_TOKEN null;private AccessToken() {}private void setExpireIn(int expireIn) {// 设置有效期限的时候的时间戳this.expireIn System.currentTimeMillis() TimeUnit.SECONDS.toMillis(expireIn);}public boolean isExpired() {return System.currentTimeMillis() this.getExpireIn();}private static void setAccessToken() {if(ACCESS_TOKEN null) {ACCESS_TOKEN new AccessToken();}MapString, Object map TokenUtil.getAccessTokenMap();ACCESS_TOKEN.setToken((String) map.get(access_token));ACCESS_TOKEN.setExpireIn((Integer) map.get(expires_in));}public static AccessToken getAccessToken() {if(ACCESS_TOKEN null || ACCESS_TOKEN.isExpired()) {synchronized (AccessToken.class) {if(ACCESS_TOKEN null || ACCESS_TOKEN.isExpired()) {setAccessToken();}}}return ACCESS_TOKEN;} }Component public class TokenUtil {// token 的 urlpublic static String URL https://api.weixin.qq.com/cgi-bin/token;public static String APP_ID;public static String APP_SECRET;Value(${wx.appid})private void setAPP_ID(String appId) {APP_ID appId;}Value(${wx.secret})private void setAPP_SECRET(String appSecret) {APP_SECRET appSecret;}public static MapString, Object getAccessTokenMap() {// 构造参数表MapString, Object param new HashMapString, Object(){{this.put(grant_type, client_credential);this.put(appid, APP_ID);this.put(secret, APP_SECRET);}};// 发起get请求String response HttpUtil.doGet(URL, param);// 解析jsonreturn JsonUtil.analyzeJson(response, Map.class);}public static String getToken() {return AccessToken.getAccessToken().getToken();} } 5. 补充简易版建造者模式案例 Lombok 提供的注解Builder 《重学Java设计模式》第6章建造者模式_哔哩哔哩_bilibili Getter Builder AllArgsConstructor NoArgsConstructor public class Person {private String name;private int age;private String gender;// 自定义方法来设置年龄并在方法中实现特殊逻辑public static class PersonBuilder {public PersonBuilder age(int age) {if (age 0 || age 120) {throw new IllegalArgumentException(Invalid age);}this.age age;return this;}} }之后就直接链式调用即可像说话一样方便的构造对象 Person.builder().name(小马).age(18).gender(男)。bulde();在内部定义一个静态内部类XXXBuilder实现对应的方法注解在“添加逻辑”的时候就会用我们写的 建议加上这些注解因为这个 Builder 注解会自动定义一个全参构造方法但是没有无参构造方法但是如果有构造方法了则没有全参构造方法 所以加上这两个注解以防万一 因为有些场景构造方法的存在很重要 比如 MyBatis在构造参数的时候需要无参构造方法如果没有会导致加了 Builder 后结果错乱 在二进制文件中可以查看到 public class Person {private String name;private int age;private String gender;public static PersonBuilder builder() {return new PersonBuilder();}public String getName() {return this.name;}public int getAge() {return this.age;}public String getGender() {return this.gender;}public Person(final String name, final int age, final String gender) {this.name name;this.age age;this.gender gender;}public Person() {}public static class PersonBuilder {private String name;private int age;private String gender;public PersonBuilder age(int age) {if (age 0 age 120) {this.age age;return this;} else {throw new IllegalArgumentException(Invalid age);}}PersonBuilder() {}public PersonBuilder name(final String name) {this.name name;return this;}public PersonBuilder gender(final String gender) {this.gender gender;return this;}public Person build() {return new Person(this.name, this.age, this.gender);}public String toString() {return Person.PersonBuilder(name this.name , age this.age , gender this.gender );}} }
http://www.zqtcl.cn/news/747941/

相关文章:

  • 做建设网站的活的兼职网络推广专员的岗位职责是
  • 韩国 网站设计保定网站开发公司
  • 发外链的网站都要企业注册网站建设的基本概念
  • 网站管理员有哪些权限中文域名网站好不好优化
  • wordpress主题 资源站关闭wordpress自动更新
  • 网站排名怎么上去创建全国文明城市我们应该怎么做
  • 网站 ftp自助建站信息网
  • 做珠宝的网站wordpress获取相关文章
  • 网站开发视频 百度云视频资源的网站怎么做
  • 写出网站建设的基本流程鹤山市城乡住房建设部网站
  • 万网域名注册后如何做网站教学网络传奇游戏
  • 岳阳网站建设方案免费网站模板建设
  • 郑州响应式网站制作如何做公众号微信
  • 专业公司网站建设精准引流推广团队
  • 蔡甸建设局网站怎么用云校建设学校网站
  • 建立网站需要哪些东西软件开发流程包括
  • 网站的pdf目录怎么做的网站编写
  • 南宫企业做网站wordpress图片显示距离
  • 青岛红岛做网站百度怎么打广告
  • 凡科建站怎么建网站网络搭建是什么工作
  • wordpress支持国内视频的编辑器网站优化排名软件网站
  • 建设摩托官方网站南京做网站群的公司
  • 晋城城乡建设局网站设计网站公司选泽y湖南岚鸿询 问
  • 思坎普网站建设湘潭网站推广
  • 北京网站建设公司哪个最好做投标网站条件
  • 网站建设的成本有哪些内容怎么样制作网页
  • 怎么做网站的seo排名知乎茂名网站制作公司
  • 建安证查询网站官方网站建设对比
  • 关于医院要求建设网站的请示市场推广12种推广渠道
  • php做不了大型网站深圳公司注册网址官方