《建造者模式》

1.建造者模式的特点和解决问题

  • 特点:属于创建型模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
  • 主要解决: :使得"一个复杂对象"的创建工作变得简单

2.建造者的简单使用

//为bookStrap封装的分页类
@Data
public class DataGridResult {

    private Long total;//bootstrap中默认根据total,获取数据的总数量
    private List<?> rows; //bootstrap中默认根据rows,获取当前页的数据集合

    public DataGridResult() {}
    public DataGridResult(long total, List<?> rows) {
        this.total = total;
        this.rows = rows;
    }
    //静态方法返回一个建造者对象
    public static DataGridResult.Builder builder(){
        return new DataGridResult.Builder();
    }
    //建造者
    public static class Builder{
        private Long total;
        private List<?> rows;

        public Builder(){}

        public Builder total(Long total){
            if (!Objects.isNull(total))
                this.total = total;
            return this;
        }
        public Builder rows(List<?> rows){
            if (!Objects.isNull(rows))
                this.rows = rows;
            return this;
        }
        public DataGridResult build(){
            return new DataGridResult(this.total,this.rows);
        }
    }
}

3.Shiro源码中的建造者模式

在这里插入图片描述

  • Subject的建造者
public interface Subject {
    Object getPrincipal();

    PrincipalCollection getPrincipals();

    boolean isPermitted(String var1);

    void checkPermissions(Collection<Permission> var1) throws AuthorizationException;

    boolean hasRole(String var1);
   //.......

    //建造者里面维护两个属性主题上下文和安全管家
    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.");
            } else {
                this.securityManager = securityManager;
                //
                this.subjectContext = this.newSubjectContextInstance();
                if (this.subjectContext == null) {
                    throw new IllegalStateException("Subject instance returned from 'newSubjectContextInstance' cannot be null.");
                } else {
                    this.subjectContext.setSecurityManager(securityManager);
                }
            }
        }

        protected SubjectContext newSubjectContextInstance() {
            return new DefaultSubjectContext();
        }

        protected SubjectContext getSubjectContext() {
            return this.subjectContext;
        }
        //设置属性到subjectContext的SessionId,并返回建造者本身
        public Subject.Builder sessionId(Serializable sessionId) {
            if (sessionId != null) {
                this.subjectContext.setSessionId(sessionId);
            }

            return this;
        }
        //设置属性到subjectContext的host,并返回建造者本身
        public Subject.Builder host(String host) {
            if (StringUtils.hasText(host)) {
                this.subjectContext.setHost(host);
            }

            return this;
        }
        //设置属性到subjectContext的session,并返回建造者本身
        public Subject.Builder session(Session session) {
            if (session != null) {
                this.subjectContext.setSession(session);
            }

            return this;
        }
        //设置属性到subjectContext的Principals,并返回建造者本身
        public Subject.Builder principals(PrincipalCollection principals) {
            if (!CollectionUtils.isEmpty(principals)) {
                this.subjectContext.setPrincipals(principals);
            }

            return this;
        }
        //.....
        public Subject.Builder sessionCreationEnabled(boolean enabled) {
            this.subjectContext.setSessionCreationEnabled(enabled);
            return this;
        }
         //.....
        public Subject.Builder authenticated(boolean authenticated) {
            this.subjectContext.setAuthenticated(authenticated);
            return this;
        }

        public Subject.Builder contextAttribute(String attributeKey, Object attributeValue) {
            if (attributeKey == null) {
                String msg = "Subject context map key cannot be null.";
                throw new IllegalArgumentException(msg);
            } else {
                if (attributeValue == null) {
                    this.subjectContext.remove(attributeKey);
                } else {
                    this.subjectContext.put(attributeKey, attributeValue);
                }

                return this;
            }
        }
        //建造者的最终完成建造方法,根据之前方法完善的subjectContext,
        //交给securityManager去构建Subject
        public Subject buildSubject() {
            return this.securityManager.createSubject(this.subjectContext);
        }
    }
}
  • WebSubject中建造者:继承了Subject的Builder,对其进行了扩展
public interface WebSubject extends Subject, RequestPairSource {
    ServletRequest getServletRequest();

    ServletResponse getServletResponse();

    public static class Builder extends org.apache.shiro.subject.Subject.Builder {
        public Builder(ServletRequest request, ServletResponse response) {
            this(SecurityUtils.getSecurityManager(), request, response);
        }

        public Builder(SecurityManager securityManager, ServletRequest request, ServletResponse response) {
            super(securityManager);
            if (request == null) {
                throw new IllegalArgumentException("ServletRequest argument cannot be null.");
            } else if (response == null) {
                throw new IllegalArgumentException("ServletResponse argument cannot be null.");
            } else {
                this.setRequest(request);
                this.setResponse(response);
            }
        }
        //重写了Subject中的newSubjectContextInstance的方法,返回一个DefaultWebSubjectContext
        //该方法在父建造者会被调用 this.subjectContext = this.newSubjectContextInstance();
        //因此WebSubject维护的SubjectContext对象是DefaultWebSubjectContext
        protected SubjectContext newSubjectContextInstance() {
            return new DefaultWebSubjectContext();
        }
        //WebSubject建造者在父类的基础上拓展了servletRequest属性的设置
        protected WebSubject.Builder setRequest(ServletRequest request) {
            if (request != null) {
                ((WebSubjectContext)this.getSubjectContext()).setServletRequest(request);
            }

            return this;
        }
         //WebSubject建造者在父类的基础上拓展了servletResponse属性的设置
        protected WebSubject.Builder setResponse(ServletResponse response) {
            if (response != null) {
                ((WebSubjectContext)this.getSubjectContext()).setServletResponse(response);
            }

            return this;
        }
        
        //调用父类的buildSubject方法构造Subject,并且校验Subject是不是WebSubject
        public WebSubject buildWebSubject() {
            Subject subject = super.buildSubject();
            if (!(subject instanceof WebSubject)) {
                String msg = "Subject implementation returned from the SecurityManager was not a " + WebSubject.class.getName() + " implementation.  Please ensure a Web-enabled SecurityManager has been configured and made available to this builder.";
                throw new IllegalStateException(msg);
            } else {
                return (WebSubject)subject;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值