当一个类型的Field特别多的时候,使用构造函数来实例化是非常愚蠢的,因为这样构造函数会使用很多参数,超过3个参数的函数就是失败的。所以这时我们需要构建模式来解决这个弊端。一般Builder构造函数只是简单的赋值,主要逻辑在builder()中,下面给大家举出简单实例理解和实际使用例子,帮助大家真正懂得构建模式。
下面先看个简单的demo:
public class Student {
private int age;
private String name;
private int id;
private String address;
private String sex;
private String phnum;
public Student() {
}
public Student(Bulider bulider) {
this.age = bulider.age;
this.name = bulider.name;
this.id = bulider.id;
this.address = bulider.address;
this.sex = bulider.sex;
this.phnum = bulider.phnum;
}
//通过这个静态内部类来构造Student对象
public static class Bulider {
//学生类必须有的属性
private int age;
private String name;
//学生类非必须有的属性
private int id = 0;//身份证
private String address = null;//住址
private String sex = null;//性别
private String phnum = null;//电话号码
// 通过Student类必须有的属性来写Builder的构造函数
public Bulider(int age, String name) {
this.age = age;
this.name = name;
}
// 通过方法来给Student类的属性赋值,注意,方法要返回Builder本身,方便链式调用
public Bulider id(int val) {
this.id = val;
return this;
}
public Bulider address(String val) {
this.address = val;
return this;
}
public Bulider sex(String val) {
this.sex = val;
return this;
}
public Bulider phnum(String val) {
this.phnum = val;
return this;
}
public Student build() {
return new Student(this);
}
}
// 使用
public static void main(String[] args) {
Student student = new Bulider(18, "小明").address("北京").build();
}
}
再来看看实战的,Shiro中:
package org.apache.shiro.subject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.StringUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
public interface Subject {
Object getPrincipal();
PrincipalCollection getPrincipals();
boolean isPermitted(String permission);
boolean isPermitted(Permission permission);
boolean[] isPermitted(String... permissions);
boolean[] isPermitted(List<Permission> permissions);
boolean isPermittedAll(String... permissions);
boolean isPermittedAll(Collection<Permission> permissions);
void checkPermission(String permission) throws AuthorizationException;
void checkPermission(Permission permission) throws AuthorizationException;
void checkPermissions(String... permissions) throws AuthorizationException;
void checkPermissions(Collection<Permission> permissions) throws AuthorizationException;
boolean hasRole(String roleIdentifier);
boolean[] hasRoles(List<String> roleIdentifiers);
boolean hasAllRoles(Collection<String> roleIdentifiers);
void checkRole(String roleIdentifier) throws AuthorizationException;
void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;
void checkRoles(String... roleIdentifiers) throws AuthorizationException;
void login(AuthenticationToken token) throws AuthenticationException;
boolean isAuthenticated();
boolean isRemembered();
Session getSession();
Session getSession(boolean create);
void logout();
<V> V execute(Callable<V> callable) throws ExecutionException;
void execute(Runnable runnable);
<V> Callable<V> associateWith(Callable<V> callable);
Runnable associateWith(Runnable runnable);
void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException;
boolean isRunAs();
PrincipalCollection getPreviousPrincipals();
PrincipalCollection releaseRunAs();
public static class Builder {
private final SubjectContext subjectContext;
private final SecurityManager securityManager;
public Builder() {
this(SecurityUtils.getSecurityManager());
}
public Builder(SecurityManager securityManager) {
if (securityManager == null) {
throw new NullPointerException("SecurityManager method argument cannot be null.");
}
this.securityManager = securityManager;
this.subjectContext = newSubjectContextInstance();
if (this.subjectContext == null) {
throw new IllegalStateException("Subject instance returned from 'newSubjectContextInstance' " +
"cannot be null.");
}
this.subjectContext.setSecurityManager(securityManager);
}
protected SubjectContext newSubjectContextInstance() {
return new DefaultSubjectContext();
}
protected SubjectContext getSubjectContext() {
return this.subjectContext;
}
public Builder sessionId(Serializable sessionId) {
if (sessionId != null) {
this.subjectContext.setSessionId(sessionId);
}
return this;
}
public Builder host(String host) {
if (StringUtils.hasText(host)) {
this.subjectContext.setHost(host);
}
return this;
}
public Builder session(Session session) {
if (session != null) {
this.subjectContext.setSession(session);
}
return this;
}
public Builder principals(PrincipalCollection principals) {
if (principals != null && !principals.isEmpty()) {
this.subjectContext.setPrincipals(principals);
}
return this;
}
public Builder sessionCreationEnabled(boolean enabled) {
this.subjectContext.setSessionCreationEnabled(enabled);
return this;
}
public Builder authenticated(boolean authenticated) {
this.subjectContext.setAuthenticated(authenticated);
return this;
}
public Builder contextAttribute(String attributeKey, Object attributeValue) {
if (attributeKey == null) {
String msg = "Subject context map key cannot be null.";
throw new IllegalArgumentException(msg);
}
if (attributeValue == null) {
this.subjectContext.remove(attributeKey);
} else {
this.subjectContext.put(attributeKey, attributeValue);
}
return this;
}
public Subject buildSubject() {
return this.securityManager.createSubject(this.subjectContext);
}
}
}