荐:Java常见设计模式

设计模式的原则:

1、开闭原则 对扩展开放,对修改关闭。 

2、依赖倒置原则 通过抽象使各个类或者模块不相互影响,实现松耦合。 

3、单一职责原则 一个类、接口、方法只做一件事。 

4、接口隔离原则 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口。 

5、迪米特法则 又叫最少知道原则,一个类对其所依赖的类知道得越少越好。

6、里氏替换原则 子类可以扩展父类的功能但不能改变父类原有的功能。 

7、合成复用原则 尽量使用对象组合、聚合,而不使用继承关系达到代码复用的目的。

 

代码地址: https://github.com/ZhangYDevelop/java-design-pattern.git

一、工厂模式

package com.zy.java.design.patterns.factory;


/**
 * @AUTHOR zhangy
 * 2020-10-11  20:22
 * 工厂模式(simple factory pattern) ,列子:Spring 中的BeanFactory
 */
public class FactoryPattern {

    /**
     * 生产汽车的工厂
     */
    private static  class CarFactory {

        public  static Car getCarInstance(String type) {
            if (ICar.BEN_CHI.equals(type)) {
                return  new BenChiCar().createCar();
            }
            if (ICar.DA_ZHONG.equals(type)) {
                return  new DaZhongCar().createCar();
            }

            return  null;
        }

    }

    /**
     * 制造商
     */
    private static class BenChiCar implements ICar {
        public Car createCar() {
            System.out.println("生产奔驰车。。。");
            return new Car();
        }
    }
    /**
     * 制造商
     */
    private static  class DaZhongCar implements ICar {
        public Car createCar() {
            System.out.println("生产大众车...");
            return new Car();
        }
    }

    /**
     * 对生产车辆抽象
     */
    private interface ICar {
        String BEN_CHI = "BEN_CHI";
        String DA_ZHONG = "DA_ZHONG";
        
        Car createCar();
    }

    /**
     * 物质抽象
     */
    private  static  class Car {

        private String whell;

        private String engine;

    }

    public static void main(String[] args) {
        CarFactory.getCarInstance(ICar.DA_ZHONG);
    }
}

 

二、单列模式(提供一个全局访问点)

public class Singleton {
    // volatile 修饰,线程可见
    private volatile static Singleton  singleton= null;
    // 私有化构造方案
    private Singleton() {
        if (null != singleton) {
            throw new RuntimeException("单列不允许多实例");
//            //防止以下流氓方法
//            Class<?> clazz = Singleton.class;
//            try {
//                // 通过反射获取构造方法
//                Constructor construct =  clazz.getDeclaredConstructor(null);
//                // 强制访问
//                construct.setAccessible(true);
//                // 实例化对象
//                Object o1 = construct.newInstance();
//                Object o2 = construct.newInstance();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
        }
    }
    /**
     * 双重检查
     * @return
     */
    public static final Singleton  getInstance() {
        if (null == singleton) {
            synchronized (Singleton.class) {
                if (null == singleton) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

    /**
     * 通过内部类获取
     * @return
     */
    public static final Singleton  getInstanceExt() {
        //在返回结果以前,一定会先加载内部类
        return SingleHolder.singleton;
    }
    /**
     * 防止序列化破快单列
     * @return
     */
    private Object readResolve(){
        return singleton;
    }
    private static class SingleHolder {
        private static final Singleton singleton = new Singleton();
    }
}

 

三、原型模式(Prototype Pattern)

 

原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

应用场景:

1、类初始化消耗资源较多。

2、new 产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)

3、构造函数比较复杂。

4、循环体中生产大量对象时。

在Spring 中,原型模式应用得非常广泛。例如scope=“prototype”,在我们经常用

的JSON.parseObject()也是一种原型模式

/**
 * 原型模式(Prototype Pattern),相当于拷贝
 */
public class PrototypePattern {

    public interface ProtoType {
        ProtoType clone();

        ProtoType deepClone();
    }

    public static class PrototypeA implements ProtoType {
        int age;
        String name;

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        // 浅克隆
        public ProtoType clone() {
            PrototypeA prototypeA = new PrototypeA();
            prototypeA.setAge(this.age);
            prototypeA.setName(this.name);
            return prototypeA;
        }
        // 深克隆
        public ProtoType deepClone() {
            try{
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(this);
                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bis);
                ProtoType copy = (ProtoType)ois.readObject();
                return copy;
            }catch (Exception e){
                e.printStackTrace();
                return null;
            }
        }
    }
    public static void main(String[] args) {
        PrototypeA prototypeA = new PrototypeA();
        prototypeA.setName("zhangsan");
        prototypeA.setAge(12);
        ProtoType protoType = prototypeA.clone();
    }
}

 

四、代理模式(Proxy Pattern)

该模式为其他对象提供一种代理, 以控制对这个对象的访问。  

 Jdk动态代理

import sun.misc.ProxyGenerator;

import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * Jdk 动态代理
 */
public class JdkProxy  implements InvocationHandler {
    /**
     * 被代理类必须实现接口
     */
    Object target;
    public  Object  getInstance(Object object) {
        this.target = object;
        Class<?> clazz = target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object retObj = method.invoke(target, args);
        after();
        return retObj;
    }
    /**
     * 可以模拟spring的事务开启
     */
    private void after() {
        System.out.println("开启事务。。。");
    }

    /**
     * 可以模拟spring的事务提交
     */
    private void before() {
        System.out.println("提交事务。。。。");
    }

    public interface CrudHandler{
        Object addObject(Object o);

        void delete(String id);
    }
    public static class CrudHandlerImpl implements CrudHandler {

        @Override
        public Object addObject(Object o) {
            System.out.println("向数据库添加一条数据");
            return null;
        }

        @Override
        public void delete(String id) {
            System.out.println("删除数据库一条数据, id=" + id );
        }
    }

    public static void main(String[] args) {
       CrudHandler crudHandler = (CrudHandler)new JdkProxy().getInstance(new CrudHandlerImpl());
       crudHandler.delete("dfdfdfdfdf");
       byte[] bytes =   ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{CrudHandler.class});
        try {
            FileOutputStream fos = new FileOutputStream("C://zhangyu//$Proxy0.class");
            fos.write(bytes);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

    我们读取代理类$Proxy0并写到磁盘,通多 jad 命令来反编译文件(jad  $Proxy0.class  proxy0.jad),就可以很清楚的看到jdk动态代理的原理,也很容易理解为什么jdk代理为什么只能代理接口。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 

import java.lang.reflect.*;

public final class $Proxy0 extends Proxy
    implements JdkProxy.CrudHandler
{

    public $Proxy0(InvocationHandler invocationhandler)
    {
        super(invocationhandler);
    }

     ###########沈略部分代码########

    public final Object addObject(Object obj)
    {
        try
        {
            return (Object)super.h.invoke(this, m4, new Object[] {
                obj
            });
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }
	
	  public final void delete(String s)
    {
        try
        {
            super.h.invoke(this, m3, new Object[] {
                s
            });
            return;
        }
        catch(Error _ex) { }
        catch(Throwable throwable)
        {
            throw new UndeclaredThrowableException(throwable);
        }
    }

     ###########沈略部分代码########
}

 

 Cglib代理,它是通过动态继承目标对象 实现的动态代理

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Cglib 动态代理
 */
public class CglibProxy  implements MethodInterceptor{

    public Object getCglibProxyInstance(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        //要把哪个设置为即将生成的新类父类
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object retObj = methodProxy.invokeSuper(o,objects);
        after();
        return retObj;
    }

    /**
     * 可以模拟spring的事务开启
     */
    private void after() {
        System.out.println("开启事务。。。");
    }

    /**
     * 可以模拟spring的事务提交
     */
    private void before() {
        System.out.println("调校事务。。。。");
    }

    public static void main(String[] args) {
        Hanlder handler =  (Hanlder)new CglibProxy().getCglibProxyInstance(Hanlder.class);
        handler.delete("dfdfdfd");
    }


   
}

 public class  Hanlder {
        public void delete(String id) {
            System.out.println("删除数据库一条数据, id=" + id );
        }
    }

 

CGLib和JDK动态代理对比

    1、JDK动态代理是实现了被代理对象的接口,CGLib是继承了被代理对象。

    2、JDK和CGLib都是在运行期生成字节码,JDK是直接写Class 字节码,CGLib使用ASM框架写Class字节码,Cglib代理实现  更复杂,生成代理类比JDK效率低。

    3、JDK调用代理方法,是通过反射机制调用,CGLib是通过 FastClass机制直接调用方法,CGLib执行效率更高。

    4、CGLib无法代理final修饰的方法,也无法代理内部类。

 

Spring 中的代理选择原则 

1、当 Bean 有实现接口时,Spring 就会用 JDK 的动态代理 

2、当 Bean 没有实现接口时,Spring 选择 CGLib。

 

五、委派模式(Delegate Pattern)

该模式不属于GOF23 种设计模式中。委派模式(Delegate Pattern)的基本作用就是负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。在springMVC中DispatcherServlet就是很好例子

import java.util.HashMap;
import java.util.Map;

/**
 * 委派模式
 * 简单列子:老板叫领导干活
 */
public class DelegatePattern {
    /**
     * 员工接口
     */
    public interface Employee {
      void   doSomething(String commond);
    }
    /**
     * 打印员
     */
    public static class EmployeeA implements Employee{
        @Override
        public void doSomething(String commond) {
            System.out.println("打印员接到通知:" + commond);
        }
    }
    /**
     * 前台
     */
    public static  class EmployeeB implements Employee{
        @Override
        public void doSomething(String commond) {
            System.out.println("前台接到命令:" + commond);
        }
    }
    /**
     * 领导,不干活,指挥别人干
     */
    public static class Leader implements Employee {

        private Map<String, Employee> employees  = new HashMap<>();

        public Leader() {
            employees.put("前台", new EmployeeB());
            employees.put("打印员", new EmployeeA());
        }
        @Override
        public void doSomething(String commond) {
            employees.get(commond).doSomething(commond);
        }
    }
    /**
     * 老板下达命令
     */
    public static class Boss {
        public void commond(String commond) {
            new Leader().doSomething(commond);
        }
    }
    public static void main(String[] args) {
            //客户请求(Boss)、委派者(Leader)、被被委派者(Target)
                //委派者要持有被委派者的引用
                //代理模式注重的是过程, 委派模式注重的是结果
                //策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
                //委派的核心:就是分发、调度、派遣
                //委派模式:就是静态代理和策略模式一种特殊的组合
        new Boss().commond("前台");
    }
}

六、策略模式(Strategy Pattern)

import java.sql.ParameterMetaData;
import java.util.HashMap;
import java.util.Map;

/**
 * 策略模式
 * 简单列子:支付方式的选择
 */
public class StrategyPattern {
    /**
     * 支付抽象
     */
    public interface Payment {
        void pay(int mount);
    }

    /**
     * 阿里支付
     */
    public static class Alipay implements Payment {
        @Override
        public void pay(int mount) {
            System.out.println("阿里支付,支付金额:" + mount);
        }
    }

    /**
     * 微信支付
     */
    public static class Wechatpay implements Payment {
        @Override
        public void pay(int mount) {
            System.out.println("微信支付,支付金额:" + mount);
        }
    }

    public static class PaymentFactory {

        private static Map<String, Payment>  payMentMap  = new HashMap<>();

        private  static  Payment defaultPayMent = new Alipay();

        public PaymentFactory() {
            payMentMap.put(PayType.ALI_PAY, new Alipay());
            payMentMap.put(PayType.WECHAT_PAY, new Wechatpay());
        }

        public static Payment getPayMent(String type) {
            Payment payment = payMentMap.get(type);
            return  payment == null ? defaultPayMent : payment;
        }
    }

    public interface PayType {
        public static final String ALI_PAY = "ALI_PAY";
        public static final String WECHAT_PAY = "WECHAT_PAY";
    }

    public static void main(String[] args) {
      Payment payment =  PaymentFactory.getPayMent(PayType.WECHAT_PAY);
      payment.pay(234);
    }
}

 

七、模版方法模式

package com.zy.java.design.patterns.template;

/**
 * @AUTHOR zhangy
 * 2020-10-11  14:22
 * 模版方法模式(Template Method Pattern)是指定义一个算法的骨 架,并允许子类为一
 * 个或者多个步骤提供实现。
 */
public abstract class TemplateMethodPattern {


    /**
     * 创建订单
     * @param info
     */
    protected final void  createOrder(Object info) {

        // 创建订单
        saveOrderInfo(info);
        
        // 支付
        pay(info);

        // 产生物流信息
        saveWuliuInfo(info);

        // 发送短信给用户
        sendMessage(info);

        // .....

    }

    private final  void sendMessage(Object info) {
        System.out.println("发送短信");
    }

    protected final void saveWuliuInfo(Object info) {
        System.out.println("产生物流信息");
    }

    /**
     * 交给不同的子类实现 可能有不同的支付方式:支付宝 微信 。。。
     * @param info
     */
    protected abstract void pay(Object info);

    protected final void saveOrderInfo(Object info) {
        System.out.println("产生一条订单:insert into order_info ....");
    }
}

 模板模式的优缺点 

优点: 

1、利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。 

2、将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。

3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台, 符合开闭原则。 

缺点: 

1、类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。 

2、类数量的增加,间接地增加了系统实现的复杂度。 

3、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。 模板方法模式比较简单,相信小伙伴们肯定能学会,也肯定能理解好!只要勤加练习, 多结合业务场景思考问题,就能够把模板方法模式运用好。

 

八 适配器模式(adapter pattern)

 一个类的接口转换成客户期望的另一个接口,使原本的接口不兼容的类可以一起工作,属于结构型设计模式

/**
 * 适配器模式(adapter pattern),不改变原有规则的前提下适应新的规则需求
 */
public class AdaptePattern {

    public static  class LoginService {
        public Object login(String userName, String password) {
            System.out.println("账号密码登录");
            return  new Object();
        }
    }

    /**
     * 登录业务适配的抽象
     */
    public interface LoginAdapter {
        Object login(LoginAdapter adapter);

        boolean support(Object adapter);
    }

    public static  class LoginForQQ implements LoginAdapter {

        public Object login(LoginAdapter adapter) {
            System.out.println("qq 登录");
            return new Object();
        }

        public boolean support(Object adapter) {
            return adapter instanceof LoginForQQ;
        }
    }

    public static class LoginForWechat implements LoginAdapter {
        public Object login(LoginAdapter adapter) {
            System.out.println("wechat 登录");
            return new Object();
        }

        public boolean support(Object adapter) {
            return adapter instanceof LoginForWechat;
        }
    }

    /**
     * 第三方登录
     */
    public interface LoginForthirdPart {

        Object loginForQQ();

        Object loginForWechat();

    }

    /**
     *扩展原有的业务逻辑,不改变原有代码,适应新的需求
     */
    public static class LoginForthirdPartService  extends LoginService implements LoginForthirdPart {

        public Object loginForQQ() {

            return doLogin(LoginForQQ.class);
        }

        public Object loginForWechat() {
            return doLogin(LoginForWechat.class);
        }

       private Object  doLogin (Class<? extends  LoginAdapter> clazz) {
           try {
               LoginAdapter adapter = clazz.newInstance();
               if (adapter.support(adapter) ) {
                   return  adapter.login(adapter);
               } else {
                   return  null;
               }
           } catch (InstantiationException e) {
               e.printStackTrace();
           } catch (IllegalAccessException e) {
               e.printStackTrace();
           }

           return  null;
       }

    }

    public static void main(String[] args) {

        new LoginForthirdPartService().loginForWechat();
    }

}

 

 适配器模式的优缺点 

    优点: 

    1、能提高类的透明性和复用,现有的类复用但不需要改变。 

    2、目标类和适配器类解耦,提高程序的扩展性。 

    3、在很多业务场景中符合开闭原则。 

    缺点: 

    1、适配器编写过程需要全面考虑,可能会增加系统的复杂性。 

    2、增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

 

九、装饰者模式(Decorator Pattern)

装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对

象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。

/**
 * 装饰者模式(Decorator Pattern)
 * 列:煎饼加香肠、加鸡蛋
 */
public class DecoratorPattern {

    public static abstract class BatterCake {
       protected abstract String getBatterCake();
       protected abstract int getPrice();
    }

    /**
     * 煎饼类
     */
    public static class BaseBatterCake  extends BatterCake{

        @Override
        protected String getBatterCake() {
            return "煎饼";
        }

        @Override
        protected int getPrice() {
            return 5;
        }
    }

    public static   abstract class BatterCakeDecorator extends BatterCake {
        // 委派 静态代理
        private BatterCake  batterCake;
        
        public BatterCakeDecorator(BatterCake batterCake) {
            this.batterCake = batterCake;
        }

        @Override
        protected String getBatterCake() {
            return this.batterCake.getBatterCake();
        }

        @Override
        protected int getPrice() {
            return this.batterCake.getPrice();
        }
        abstract void doSomething();
    }



    public static   class BatterCakeWithEgg extends BatterCakeDecorator {

        public BatterCakeWithEgg(BatterCake batterCake) {
            super(batterCake);
        }

        @Override
        protected String getBatterCake() {
            return super.getBatterCake() + "鸡蛋";
        }

        @Override
        protected int getPrice() {
            return super.getPrice() + 2;
        }

        @Override
        void doSomething() {
            System.out.println("business ....");
        }
    }
    public static class BatterCakeWithEggAndHotDogs extends  BatterCakeDecorator {

        public BatterCakeWithEggAndHotDogs(BatterCake batterCake) {
            super(batterCake);
        }

        @Override
        protected String getBatterCake() {
            return super.getBatterCake() + "鸡蛋 + 肠";
        }

        @Override
        protected int getPrice() {
            return super.getPrice() + 3;
        }

        @Override
        void doSomething() {
            System.out.println("business ....");
        }
    }
    public static void main(String[] args) {
        BatterCake cake = new BaseBatterCake();
        System.out.println(cake.getBatterCake());
        cake = new BatterCakeWithEgg(cake);
        System.out.println(cake.getBatterCake());
        cake = new BatterCakeWithEggAndHotDogs(cake);
        System.out.println(cake.getBatterCake());
    }
}

 

十、观察者模式(Observe Pattern)

 

观察者模式定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通知并更新,属于行为型模式。

 

/**
 * 观察者模式(Observe Pattern)
 * 场景:学生反馈问题,老师接收
 */
public class ObservePattern {

    public static class Question {
        private  String user;
        private String questionDescribe;

        public String getUser() {
            return user;
        }

        public void setUser(String user) {
            this.user = user;
        }

        public String getQuestionDescribe() {
            return questionDescribe;
        }

        public void setQuestionDescribe(String questionDescribe) {
            this.questionDescribe = questionDescribe;
        }
    }

    /**
     *  JDK提供观察者、被观察者模式
     */
    public static class MesageObserve extends Observable {
        private static MesageObserve mesageObserve = null;
        private String name = "学生管理平台";

        public String getName() {
            return name;
        }

        public static MesageObserve getInstance() {
            if (null == mesageObserve) {
                mesageObserve = new MesageObserve();
            }
            return mesageObserve;
        }

        public void publishQuestion(Question question) {
            System.out.println("学生:" + question.getUser() + "在平台上反馈了一个问题");
            setChanged();
            notifyObservers(question);
        }
    }

    public static class  Teacher  implements Observer{
        private String name;
        public Teacher(String name){
            this.name = name;
        }
        public void update(Observable o, Object arg) {
            MesageObserve gper = (MesageObserve)o;
            Question question = (Question)arg;
            System.out.println("===============================");
            System.out.println(name + "老师,你好!\n" +
                            "您收到了一个来自“" + gper.getName() + "”的提问,希望您解答,问题内容如下:\n" +
                            question.getQuestionDescribe() + "\n" +
                    "提问者:" + question.getUser());
        }
    }

    public static void main(String[] args) {
        MesageObserve mesageObserve = MesageObserve.getInstance();
        Teacher zhang = new Teacher("zhang");
        Teacher huang = new Teacher("huang");
        mesageObserve.addObserver(zhang);
        mesageObserve.addObserver(huang);

        Question question = new Question();
        question.setUser("小明");
        question.setQuestionDescribe("装饰者模式怎么使用。。。");
        mesageObserve.publishQuestion(question);
    }
}

十一、责任链模式(Chain of Responsibility)

责任链模式么一个节点看做是一个对象,每一个节点处理不同业务逻辑,且内部维护下一个节点对象。

/**
 * 责任链模式(Chain of Responsibility)
 * 列:对参数校验(非空、登录、权限)
 */
public class ChainOfResponsibility {

    public static class Params {
        private String userName;
        private String token;
        private String userRule;

        public String getUserName() {
            return userName;
        }

        ########省略部分get set###########
    }


    public static abstract class Handler {
        public Handler chain;

        public void  setNextHandler (Handler handler) {
            this.chain = handler;
        }

        public abstract  void doHandler (Params params);
    }

    /**
     * 非空参数验证Handler
     */
    public static class  VolidateHandler extends  Handler {
        @Override
        public void doHandler(Params params) {
            System.out.println("参数非空验证通过。。。");
            chain.doHandler(params);
        }
    }
    /**
     * 角色验证Handler
     */
    public static class RoleHandler extends  Handler {
        @Override
        public void doHandler(Params params) {
            System.out.println("角色验证通过。。。");
            chain.doHandler(params);
        }
    }
    /**
     * 权限验证Handler
     */
    public static class AuthorHandler extends  Handler {
        @Override
        public void doHandler(Params params) {
            System.out.println("权限验证通过。。。");
            if (null != chain) {
                chain.doHandler(params);
            }
        }
    }

    public static class HandlerService {
        public boolean userLogin(String userName) {
            Params params = new Params();
            params.setUserName(userName);
            params.setToken("token");
            params.setUserRule("admin");
            VolidateHandler volidateHandler = new VolidateHandler();
            RoleHandler roleHandler = new RoleHandler();
            AuthorHandler authorHandler = new AuthorHandler();
            volidateHandler.setNextHandler(roleHandler);
            roleHandler.setNextHandler(authorHandler);
            volidateHandler.doHandler(params);
            System.out.println("login success");
            return  true;
        }
    }

    public static void main(String[] args) {
        new HandlerService().userLogin("zhangsan ");
    }
}

文章详情查看: http://www.xiaoyuge.com.cn/#/article/detail?articleId=67

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值