Java设计模式
本文记述Java设计模式中的15种例子.目前只整理了这些设计模式的demo,具体的业务实践以及在spring框架中的实现,自己阅读源码,本文例子中也部分写了在源码中的应用.
- java设计模式的六大原则
在写设计模式例子之前,先了解运用设计模式的六大原则
2.单例模式
2.1单例模式中的懒汉模式
/**
-
@author Stone
-
单例模式
-
1.定义:保证一个类只有一个实例,并且提供一个全局访问点
-
2.应用场景:线程池,数据库连接池,这些重量级的对象只需要一个实例
-
3.实现方式:
-
3.1 懒汉模式:只有使用的时候再进行初始化,延迟加载
-
3.2 饿汉模式:在类加载阶段就完成了实例的初始化
*/
public class Singleton {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
LazySingleton instance = LazySingleton.getInstance();
System.out.println(“thread1–”+instance);
}
}).start();new Thread(new Runnable() { @Override public void run() { LazySingleton instance = LazySingleton.getInstance(); System.out.println("thread2--"+instance); } }).start();
}
}
/**
-
1.懒汉模式: 只有使用的时候才开始实例化
-
需要注意点: 1.线程安全 2.防止指令重排
-
Spring源码中ReactiveAdapterRegistry类就使用了单例模式
*/
class LazySingleton{/**加volatile防止JVM优化时,JIT即时编译器出现指令重排,
- 防止其他线程访问时instance已经别赋值,
- 但却没有执行invokespecial初始化操作,
- 实际instance在获取属性操作的时候报空指针异常
*/
private volatile static LazySingleton instance;
/**
- 构造方法私有化
*/
private LazySingleton(){}
/**
- TimeUnit.MICROSECONDS.sleep(1000);让线程停顿来进行测试多线程情况下需要加锁
- @return
/
public static LazySingleton getInstance(){
if(instancenull){
//加锁是为了防止在多线程下创建多个实例
synchronized (LazySingleton.class){
//再次进行null判断是因为多个线程同时在增多锁资源的时候如果已经进行了第一步的instancenull的判断,会产生多个实例
if(instance==null){
instance=new LazySingleton();
}
}
}
return instance;
}
}
2.2单例模式中的饿汉模式
/*
-
@author Stone
-
饿汉模式
-
通过类加载机制保证线程安全,在ClassLoader中的loadClass(String name, boolean resolve)方法中加了synchronized关键字
/
public class HungrySingleton implements Serializable {
/*- 保证序列化和反序列化用同一个版本号
*/
static final long serialVersionUID = 42L;
private static HungrySingleton instance=new HungrySingleton();
/**
- 构造方法私有化
*/
private HungrySingleton(){
//防止反射攻击产生多个实例
if(HungrySingleton.instance!=null){
throw new RuntimeException(“单例不能有多个实例”);
}
}
public static HungrySingleton getInstance(){
return instance;
}/**
- 当类implements Serializable 时,反序列化的对象和序列化的对象不是同一个,
- 为了保持一致,反序列化的时候从流中返回相同的对象
- @return
- @throws ObjectStreamException
*/
Object readResolve() throws ObjectStreamException {
return instance;
}
public static void main(String[] args) {
HungrySingleton instance = HungrySingleton.getInstance();
}
2.3通过静态内部类实现懒汉模式
/** - 保证序列化和反序列化用同一个版本号
-
@author Stone
-
通过静态内部类实现懒汉模式,
-
通过JVM的类加载机制实现线程安全
-
在ClassLoader中的loadClass(String name, boolean resolve)方法中加了synchronized关键字
*/
public class InnerSingleton {static class InnerClass{
private static InnerSingleton instance=new InnerSingleton();
}public static InnerSingleton getInstance(){
return InnerClass.instance;
}private InnerSingleton(){
//防止反射攻击产生多个实例
if(InnerClass.instance!=null){
throw new RuntimeException(“单例不能有多个实例”);
}
}
}
3.观察者模式
/** -
@author Stone
-
观察者模式
-
1.模式定义:
-
定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新
-
2.在spring中的ApplicationListener运用
*/
public class ObserverTest {
public static void main(String[] args) {
Subject subject=new Subject();
Task1 task1=new Task1();
subject.addObserver(task1);
Task2 task2=new Task2();
subject.addObserver(task2);subject.notifyObserver("xxxxx");
}
}
class Subject{
/**- 容器
*/
List container=new ArrayList<>();
/**
- add
- @param observer
*/
public void addObserver(Observer observer){
container.add(observer);
}
/**
- remove
- @param observer
*/
public void removeObserver(Observer observer){
container.remove(observer);
}
/**
- 调用观察者update()方法
- @param object
*/
public void notifyObserver(Object object){
for(Observer item: container){
item.update(object);
}
}
- 容器
}
interface Observer{
void update(Object object);
}
class Task1 implements Observer{
@Override
public void update(Object object) {
System.out.println("task1 received:"+object);
}
}
class Task2 implements Observer{
@Override
public void update(Object object) {
System.out.println("task2 received:"+object);
}
}
自定义监听器实现观察者模式:
/**
-
@author Stone
-
观察者模式
-
1.模式定义:
-
定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新
-
2.在spring中的ApplicationListener运用
*/
public class ObserverTest {
public static void main(String[] args) {
Subject subject=new Subject();
Task1 task1=new Task1();
subject.addObserver(task1);
Task2 task2=new Task2();
subject.addObserver(task2);subject.notifyObserver("xxxxx");
}
}
class Subject{
/**- 容器
*/
List container=new ArrayList<>();
/**
- add
- @param observer
*/
public void addObserver(Observer observer){
container.add(observer);
}
/**
- remove
- @param observer
*/
public void removeObserver(Observer observer){
container.remove(observer);
}
/**
- 调用观察者update()方法
- @param object
*/
public void notifyObserver(Object object){
for(Observer item: container){
item.update(object);
}
}
- 容器
}
interface Observer{
void update(Object object);
}
class Task1 implements Observer{
@Override
public void update(Object object) {
System.out.println("task1 received:"+object);
}
}
class Task2 implements Observer{
@Override
public void update(Object object) {
System.out.println("task2 received:"+object);
}
}
4.动态代理
/**
- @author Stone
- 动态代理
*/
public class ProxyTest {
public static void main(String[] args) {
LiyuchunProxy liyuchunProxy=new LiyuchunProxy();
Person proxy= (Person)liyuchunProxy.createProxy();
proxy.sing(“忘情水”);
}
}
interface Person{
void sing(String name);
void dance(String name);
}
class Liyuchun implements Person{
@Override
public void sing(String name){
System.out.println(“春哥开唱了…”+name);
}
@Override
public void dance(String name){
System.out.println(“春哥开跳了…”+name);
}
}
/**
-
动态代理中用到了反射技术
-
动态代理的本质是有一个接口的一个实例,整出这个接口的另外一个实例
*/
class LiyuchunProxy{private Liyuchun liyuchun=new Liyuchun();
public Object createProxy(){
/**规定了,要产生的被代理类的代理类,要求被代理必须实现一个接口
* 最后一个参数用于产生的代理具体要干的事
* proxy:代理类本身
* method:代理类的某个方法
* args:调用方法的时候传过去的参数
*/
Object object = Proxy.newProxyInstance(LiyuchunProxy.class.getClassLoader(), liyuchun.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals(“sing”)){
System.out.println(“拿两万刀来…”);
method.invoke(liyuchun,args);
}
if(method.getName().equals(“dance”)){
System.out.println(“拿两万刀来才唱…”);
method.invoke(liyuchun,args);
}
return null;
}
});
return object;
}
}
5.抽象工厂模式
/**
-
@auhtor Stone
-
抽象工厂模式
-
1.模式定义:
-
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
-
2.应用场景
-
2.1程序需要处理不同系列的相关产品,但是你不希望它依赖于这些产品的具体类时
-
3.优点
-
3.1可以确信你从工厂得到的产品彼此是兼容的
-
3.2可以避免具体产品和客户端代码之间的紧密耦合
-
3.3符合单一职责原则
-
3.4符合开闭原则
*/
public class AbstractFactory {public static void main(String[] args) {
IDatabaseUtils iDatabaseUtils=new MysqlDataBaseUtils();
IConnection connection = iDatabaseUtils.getConnection();
connection.connect();
ICommand command = iDatabaseUtils.getCommand();
command.command();
}
}
interface IConnection{
void connect();
}
class MysqlIConnection implements IConnection {
public void connect() {
System.out.println(“mysql connected.”);
}
}
class MysqlCommand implements ICommand {
public void command() {
System.out.println(“mysql command…”);
}
}
interface ICommand{
void command();
}
interface IDatabaseUtils{
IConnection getConnection();
ICommand getCommand();
}
class MysqlDataBaseUtils implements IDatabaseUtils {
public IConnection getConnection() {
return new MysqlIConnection();
}
public ICommand getCommand() {
return new MysqlCommand();
}
}
6.工厂方法模式
/**
- @author Stone
- 工厂方法模式
- 1.模式定义:
- 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使得一个类的实例化延迟到子类
- 2.应用场景
- 2.1当你不知道该使用对象的确切类型的时候
- 2.2当你希望为库或框架提供扩展其内部组件的方法时
*3.主要优点: - 3.1将具体产品和创建者解耦
- 3.2符合单一职责原则
- 3.3符合开闭原则
*/
public class FactoryMethod {
public static void main(String[] args) {
Application application=new ConcreateProductA();
Product product = application.getObject();
product.method1();
}
}
interface Product{
void method1();
}
class ProductA implements Product{
public void method1(){
System.out.println(“ProductA.method1 executed…”);
}
}
class ProductA1 implements Product{
public void method1(){
System.out.println(“ProductA1.method1 executed…”);
}
}
abstract class Application{
/**
* 定义工厂方法
* @return
*/
abstract Product createProduct();
Product getObject(){
Product product=createProduct();
return product;
}
}
class ConcreateProductA extends Application{
@Override
Product createProduct() {
return new ProductA();
}
}
class ConcreateProductA1 extends Application{
@Override
Product createProduct() {
return new ProductA1();
}
}
7.建造者模式
5.1例子1
/**
*对于Test类@Builder会将类生成如下的class文件
@Builder
public class Test {
private Integer id;
private String name;
}
*
- @author Stone
*/
public class Test {
private Integer id;
private String name;
/**
* 创建之后不想被修改
* @param id
* @param name
*/
public Test(final Integer id, final String name){
this.id=id;
this.name=name;
}
public static Test.TestBuilder builder(){
return new Test.TestBuilder();
}
public static class TestBuilder{
private Integer id;
private String name;
public Test.TestBuilder id(Integer id){
this.id=id;
return this;
}
public Test.TestBuilder name(String name){
this.name=name;
return this;
}
public Test build(){
return new Test(this.id, this.name);
}
@Override
public String toString() {
return "Test.TestBuilder(id=" + this.id + ", name=" + this.name + ")";
}
}
}
5.2例子2
/**
- @author Stone
- 建造者模式:
- 1.模式定义:
- 将一个复杂对象的创建与他的表示分离,使得同样的构建过程可以创建不同的表示
- 2.流程图
- Director-------Builder--------ConcreteBuilder-------Product
- 3.Spring源码中的RequestMappingInfo类和BeanDefinitionBuilder就使用了builder建造者模式
*/
public class BuilderTest{
public static void main(String[] args) {
ProductBuilder builder=new ConcreteProductBuilder();
Director director=new Director(builder);
Product product = director.makeProduct(1, “张三”);
System.out.println(product);
}
}
/**
-
Director,构造一个使用Builder接口的对象
*/
class Director{private ProductBuilder builder;
public Director(ProductBuilder builder){
this.builder=builder;
}public Product makeProduct(Integer id,String name){
builder.builderId(id);
builder.builderName(name);
Product product = builder.build();
return product;
}
}
/**
- builder,抽象类
*/
interface ProductBuilder{
void builderId(Integer id);
void builderName(String name);
Product build();
}
/**
-
ConcreteBuilder,具体的builder类
-
ConcreteBuilder创建产品的内部表示并定义它的装配过程
*/
class ConcreteProductBuilder implements ProductBuilder{private Integer id;
private String name;@Override
public void builderId(Integer id) {
this.id=id;
}
@Override
public void builderName(String name) {
this.name=name;
}
@Override
public Product build() {
return new Product(this.id,this.name );
}
}
/**
-
Product
*/
class Product {
private Integer id;
private String name;public Product(){ }
public Product(Integer id, String name){
this.id=id;
this.name=name;
}@Override
public String toString() {
return “Product{” +
“id=” + id +
“, name=’” + name + ‘’’ +
‘}’;
}
}
8.原型模式
/** -
@author Stone
-
原型模式
-
1.模式定义:
-
指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
-
2.ArrayList和Spring中的AbstractBeanDefinition类中都有clone()方法
-
其中AbstractBeanDefinition类中的clone方法是在子类ChildBeanDefinition的clone()方法中实现的
*3.优点 -
3.1可以不耦合具体类的情况下克隆对象
-
3.2避免重复的初始化代码
-
3.3更方便的构建复杂对象
-
3.4构造方法只在一开始创建原型的时候初始化,在执行clone()方法的时候是直接从内存中获取数据,
-
在第一次创建对象的时候会把数据在内存中保留一份,克隆的时候直接调用,避免了初始化占用的时间和空间
*/
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {Student student=new Student(1,"李四"); School teacher=new School(2,"1001",student); School clone = teacher.clone(); teacher.getStudent().setName("王二"); System.out.println(teacher); System.out.println(clone);
}
static class Student implements Cloneable{
private Integer id;
private String name;public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student(Integer id, String name) { this.id = id; this.name = name; } /** * 实现浅度clone * @return * @throws CloneNotSupportedException */ @Override protected Student clone() throws CloneNotSupportedException { return (Student)super.clone(); } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + '}'; }
}
static class School implements Cloneable{
private int age;
private String number;
private Student student;public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public School(int age, String number, Student student) { System.out.println("shool构造器被调用了"); this.age = age; this.number = number; this.student = student; } @Override public String toString() { return "School{" + "age=" + age + ", number='" + number + '\'' + ", student=" + student + '}'; } /** * 实现深度clone * @return * @throws CloneNotSupportedException */ @Override protected School clone() throws CloneNotSupportedException { School school=(School)super.clone(); Student clone = student.clone(); school.student=clone; //school.setStudent(clone); return school; }
}
}
9.享元模式
/** -
@author Stone
-
享元模式
-
1.模式定义:
-
运用共享技术有效的支持大量细粒度的对象
-
2.优点:
-
如果系统有大量类似的对象,可以节省大量的内存以及CPU资源
*/
public class Flyweight {
public static void main(String[] args) {
TreeFactory factory=new TreeFactory();
TreeNode treeNode1=new TreeNode(3,4,TreeFactory.getTree(“xxxx”));
TreeNode treeNode2=new TreeNode(5,6,TreeFactory.getTree(“xxxx”));
}
}
class TreeFactory{
private static Map<String,Tree> map=new ConcurrentHashMap<>();
public static Tree getTree(String name){
if(map.containsKey(name)){
return map.get(name);
}
Tree tree=new Tree(name);
map.put(name,tree);
return tree;
}
}
class TreeNode{
private int x;
private int y;
private Tree tree;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Tree getTree() {
return tree;
}
public void setTree(Tree tree) {
this.tree = tree;
}
public TreeNode(int x, int y, Tree tree) {
this.x = x;
this.y = y;
this.tree = tree;
}
}
class Tree{
private final String name;
public String getName() {
return name;
}
public Tree(String name) {
System.out.println("Tree的构造器被调用");
this.name = name;
}
}
10.门面模式
/**
- @author Stone
- 门面模式
- 1.模式定义:
- 为子系统中的一组接口提供一个一致的接口,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
- 2.我们平时的contoller就是用了这种模式,还有在tomcate源码ReuqestFacade类中
- 3.应用场景
- 3.1当您需要使用复杂子系统的有限但直接的接口时
- 3.2当您想要将子系统组织成层时
- 4.优点
- 简化客户单的调用
*/
public class Facade {
public static void main(String[] args) {
}
}
class FacadeBuiler {
System1 system1=new System1();
System2 system2=new System2();
System3 system3=new System3();
public void doSomethingFacadeBuilder(){
system1.method1();
system2.method2();
system3.method3();
}
}
class Client1{
FacadeBuiler facadeBuiler=new FacadeBuiler();
public void doSomething1(){
facadeBuiler.doSomethingFacadeBuilder();
}
}
class Client2{
FacadeBuiler facadeBuiler=new FacadeBuiler();
public void doSomething2(){
facadeBuiler.doSomethingFacadeBuilder();
}
}
class System1{
public void method1(){
System.out.println(“System1.method1 executed…”);
}
}
class System2{
public void method2(){
System.out.println(“System2.method2 executed…”);
}
}
class System3{
public void method3(){
System.out.println(“System3.method3 executed…”);
}
}
11.适配器模式
9.1对象适配器
/**
- @author Stone
- 适配器模式
- 1.模式定义:
- 将一个类的接口转换成客户希望的另一个接口.
- Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
- 2.Arrays.asList()就是将数组类型转化成ArrayList类型
- 3.应用场景:
- 3.1当你希望使用某些现有类,但其接口与你的其他代码不兼容时
- 3.2当你希望用几个现有的子类,这些子类缺少一些不能添加到超类中的公共功能时.
- 4.优点:
- 1.符合单一职责原则
- 2.符合开闭原则
*/
public class AdapterTest {
public static void main(String[] args) {
Adapte adapte=new Adapte();
Target target=new Adapter(adapte);
target.output5v();
}
}
class Adapte{
public int output220V(){
return 220;
}
}
interface Target{
int output5v();
}
/**
-
Object Adapter模式,对象适配器模式,用的是组合
*/
class Adapter implements Target{private Adapte adapte;
public Adapter(Adapte adapte){
this.adapte=adapte;
}@Override
public int output5v() {
int i = adapte.output220V();
//在这里进行适配, 将220v的电压转化成5v的电压,最终返回5v的电压
System.out.println(String.format(“原始电压: %d v -> 输出电压: %d v”,i,5));
return 5;
}
}
9.2 类适配器
public class AdapterTest2 {
public static void main(String[] args) {
Adapter adapter=new Adapter();
int i = adapter.output5v();
}static class Adapte{
public int output220V(){
return 220;
}
}interface Target{
int output5v();
}/**
-
Class Adapter模式,类的适配器模式,用的是继承
*/
static class Adapter extends Adapte implements Target{@Override
public int output5v() {
int i = output220V();
//在这里进行适配, 将220v的电压转化成5v的电压,最终返回5v的电压
System.out.println(String.format(“原始电压: %d v -> 输出电压: %d v”,i,5));
return 5;
}
}
}
12.装饰者模式
/**
-
-
@author Stone
-
Decorator装饰者模式
-
1.模式定义:
-
在不改变原有对象的基础上,将功能附加到对象上
-
2.应用场景
-
扩展一个类的功能或给一个类添加附加职责
-
3.优点:
-
3.1不改变原有对象的情况下给一个对象扩展功能
-
3.2使用不同的组合可以实现不同的效果
-
3.3符合开闭原则
-
4.HttpServletRequestWrapper就是运用了装饰者模式
*/
public class DecoratorTest {
public static void main(String[] args) {
Component component=new ConcreteDecorator2(new ConcreteDecorator1(new ConcreteComponent()));
component.operation();
}
}
interface Component{
void operation();
}
class ConcreteComponent implements Component{
@Override
public void operation() {
System.out.println("拍照");
}
}
abstract class Decorator implements Component{
Component component;
public Decorator(Component component){
this.component=component;
}
}
class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Component component) {
super(component);
}
@Override
public void operation() {
System.out.println("添加美颜效果");
component.operation();
}
}
class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Component component) {
super(component);
}
@Override
public void operation() {
System.out.println("添加滤镜效果");
component.operation();
}
}
13.策略模式
/**
- @author Stone
- Strategy Pattern 策略模式
- 1.模式定义:
- 定义了算法族,分别封装起来,让它们之间可以相互替换,此模式的变化独立于算法的使用者
*2.Arrays.sort()方法就使用了策略模式,根据不同的策略进行不同的排序 - spring中的InstantiationStrategy接口
*/
public class StrategyTest {
public static void main(String[] args) {
Zombie zombie=new NormalZombie1(new StepByStepMove(),new BiteAttack());
zombie.display();
zombie.move();
zombie.attack();
}
}
interface Moveable{
void move();
}
interface Attackable{
void attack();
}
abstract class Zombie{
abstract public void display();
Moveable moveable;
Attackable attackable;
abstract void move();
abstract void attack();
public Zombie(Moveable moveable,Attackable attackable){
this.moveable=moveable;
this.attackable=attackable;
}
}
class StepByStepMove implements Moveable{
@Override
public void move() {
System.out.println("一步一步移动.....");
}
}
class BiteAttack implements Attackable{
@Override
public void attack() {
System.out.println(“咬…”);
}
}
class NormalZombie1 extends Zombie{
public NormalZombie1(Moveable moveable,Attackable attackable){
super(moveable,attackable);
}
@Override
public void display() {
System.out.println("我是普通僵尸....");
}
@Override
void move() {
moveable.move();
}
@Override
void attack() {
attackable.attack();
}
}
/**
- @author Stone
*/
public class ZombieTest {
public static void main(String[] args) {
AbstractZombie normalZombie=new NormalZombie();
normalZombie.display();
normalZombie.move();
normalZombie.attack();
System.out.println("-------------------------");
AbstractZombie flagZombie=new FlagZombie();
flagZombie.display();
flagZombie.move();
flagZombie.attack();
}
}
abstract class AbstractZombie{
public abstract void display();
public void attack(){
System.out.println(“咬…”);
};
public void move(){
System.out.println(“一步一步移动…”);
}
}
class NormalZombie extends AbstractZombie{
@Override
public void display() {
System.out.println("我是普通僵尸...");
}
}
class FlagZombie extends AbstractZombie{
@Override
public void display() {
System.out.println("我是旗手僵尸...");
}
}
14.模板方法模式:
/**
- @author Stone
- 模板方法模式:
- 1.模式定义:
- 定义一个操作的算法骨架,而将一些步骤延迟到子类中,Template Method 使得子类可以不改变一个算法的结构即可重定义改算法的某些特定步骤
*HttpServlet中的doGet和doPost方法就是用的模板方法模式
*
*/
public class TemplateMethodTest {
public static void main(String[] args) {
AbstractClass abstractClass=new SubClass();
abstractClass.operation();
}
}
abstract class AbstractClass{
public void operation(){
System.out.println(“pre…”);
System.out.println(“step1…”);
System.out.println(“step2…”);
temlateMethod();
}
abstract protected void temlateMethod();
}
class SubClass extends AbstractClass {
@Override
protected void temlateMethod() {
System.out.println("SubClass execute....");
}
}
15.责任链模式
/**
- @author Stone
- 责任链模式:
- 1.模式定义:
- 为请求创建了一个接收者对象的链
*2.优点: - 2.1请求的发送者和接收者解耦
- 2.2可以控制执行顺序
- 2.3符合开闭原则和单一职责原则
*/
public class ChainTest {
public static void main(String[] args) {
Request request = new Request.RequestBuilder().frequentOk(true).loggedOn(true).build();
RequestFrequentHander requestFrequentHander=new RequestFrequentHander(new LoggingHandler(null));
if(requestFrequentHander.process(request)){
System.out.println(“正常业务处理”);
}else{
System.out.println(“访问异常”);
}
}
}
class Request{
private boolean loggedOn;
private boolean frequentOk;
private boolean isPermits;
private boolean containsSensitiveWords;
private String requestBody;
public Request(Boolean loggedOn, Boolean frequentOk, Boolean isPermits, Boolean containsSensitiveWords) {
this.loggedOn = loggedOn;
this.frequentOk = frequentOk;
this.isPermits = isPermits;
this.containsSensitiveWords = containsSensitiveWords;
}
static class RequestBuilder{
private boolean loggedOn;
private boolean frequentOk;
private boolean isPermits;
private boolean containsSensitiveWords;
RequestBuilder loggedOn(boolean loggedOn){
this.loggedOn=loggedOn;
return this;
}
RequestBuilder frequentOk(boolean frequentOk){
this.frequentOk=frequentOk;
return this;
}
RequestBuilder isPermits(boolean isPermits){
this.isPermits=isPermits;
return this;
}
RequestBuilder containsSensitiveWords(boolean containsSensitiveWords){
this.containsSensitiveWords=containsSensitiveWords;
return this;
}
public Request build(){
Request request=new Request(this.loggedOn,this.frequentOk,this.isPermits,this.containsSensitiveWords);
return request;
}
}
public boolean isLoggedOn(){return loggedOn;};
public boolean isFrequentOk(){return frequentOk;};
public boolean isPermits(){return isPermits;};
public boolean isContainsSensitiveWords(){return isContainsSensitiveWords();};
}
abstract class Handler{
Handler next;
public Handler(Handler next){
this.next=next;
}
public Handler getNext() {
return next;
}
public void setNext(Handler next) {
this.next = next;
}
abstract boolean process(Request request);
}
class RequestFrequentHander extends Handler{
public RequestFrequentHander(Handler next) {
super(next);
}
@Override
boolean process(Request request) {
System.out.println("访问频率控制");
if(request.isFrequentOk()){
Handler next=getNext();
if(null==next){
return true;
}
if(!next.process(request)){
return false;
}else{
return true;
}
}
return false;
}
}
class LoggingHandler extends Handler{
public LoggingHandler(Handler next) {
super(next);
}
@Override
boolean process(Request request) {
System.out.println("登录验证");
if(request.isLoggedOn()){
Handler next=getNext();
if(null==next){
return true;
}
if(!next.process(request)){
return false;
}else{
return true;
}
}
return false;
}
}