1.单例设计模式
1.1定义
保证一个类只有一个实例,并且提供一个全局的访问点
1.2场景
重量级对象,不需要多个实例,如线程池,数据库连接池
1.3饿汉模式
-
延迟加载,只有在真正使用的时候,才开始实例化
-
线程安全问题
-
double check 加锁优化
-
编译器(JIT),CPU有可能对指定进行重排序,导致使用到尚未初始化的实力,可以通过添加 volatile 关键字进行修饰,对于
volatile 修饰的字段,可以防止指令重排
class LazySingleton {
private volatile static LazySingleton singleton = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (singleton == null) {
synchronized (LazySingleton.class) {
if (singleton == null) {
singleton = new LazySingleton();
}
}
}
return singleton;
}
}
1.4 饿汉模式
类加载的初始化阶段就完成啦实例的初始化。本质上就是借助于jvm类加载机制,保证实例的唯一性
类记载过程:
- 加载二进制到内存中,生成对应的我Class数据结构
- 连接:a.验证,b.准备(给类的静态成员变量赋默认值),c.解析
- 初始化:类的静态变量赋值
只有在真正使用对应的类时,才会触发初始化 如(当前类是启动类即main函数所在类,直接进行new 操作,访问静态属性,访问静态方法,用反射访问类,初始化一个类的子类等)
class HungrySingleton {
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
}
1.5 静态内部类
- 本质上是利用累的加载机制来保证线程安全
- 只有在实际使用的时候,才会触发类的初始化,所以也是懒加载的一种形式
class InnerClassSingleton {
private static class InnerClass {
private static InnerClassSingleton singleton = new InnerClassSingleton();
}
private InnerClassSingleton() {
}
public static InnerClassSingleton getInstance() {
return InnerClass.singleton;
}
}
1.6 反射问题
public class InnerClassSingletonTest {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerClassSingleton> declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerClassSingleton instance = declaredConstructor.newInstance();
InnerClassSingleton instance1 = InnerClassSingleton.getInstance();
System.out.println(instance1 == instance);
}
}
防护
public class InnerClassSingletonTest {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerClassSingleton> declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerClassSingleton instance = declaredConstructor.newInstance();
InnerClassSingleton instance1 = InnerClassSingleton.getInstance();
System.out.println(instance1 == instance);
}
}
class InnerClassSingleton {
private static class InnerClass {
private static InnerClassSingleton singleton = new InnerClassSingleton();
}
private InnerClassSingleton() {
if (InnerClass.singleton != null) {
throw new RuntimeException("不允许多实例化此类");
}
}
public static InnerClassSingleton getInstance() {
return InnerClass.singleton;
}
}
1.7 枚举类型
- 天然不支持反射创建对应的实例,且有自己的反序列化机制
- 利用类加载机制保证线程安全
public class EnumSingletonTest {
public static void main(String[] args) {
EnumSingleton instence = EnumSingleton.INSTENCE;
EnumSingleton instence1 = EnumSingleton.INSTENCE;
System.out.println(instence == instence1);
}
}
enum EnumSingleton {
INSTENCE;
public void print() {
System.out.println(this.hashCode());
}
}
1.8 序列化
- 可以利用 指定方法来替换从反序列化流中的数据
public class SerializeSingletonTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerializeSingleton instance = SerializeSingleton.getInstance();
//
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("testSerializable"));
// oos.writeObject(instance);
// oos.flush();
// oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("testSerializable"));
SerializeSingleton singleton = (SerializeSingleton) ois.readObject();
System.out.println(singleton == instance);
}
}
class SerializeSingleton implements Serializable {
static final long serialVersionUID = 42L;
private static class Serialize {
private static SerializeSingleton singleton = new SerializeSingleton();
}
public static SerializeSingleton getInstance() {
return Serialize.singleton;
}
Object readResolve() throws ObjectStreamException {
return Serialize.singleton;
}
}
2.工厂模式
2.1 工厂方法模式
应用场景
- 当你不知道该使用对象的确切类型的时候
- 当你希望为库或框架提供扩展器内部组件方法时
主要优点
- 将具体产品和创建这解耦
- 符合单一职责原则
- 符合开闭原则
public class FactoryMethodTest {
public static void main(String[] args) {
new CreateProductB().getObj().m1();
}
}
interface Product {
void m1();
}
class ProductA implements Product{
@Override
public void m1() {
System.out.println("ProductA m1 executed. ");
}
}
class ProductB implements Product {
@Override
public void m1() {
System.out.println("ProductB m1 executed. ");
}
}
class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ProductA();
} else if (type.equals("B")) {
return new ProductB();
}
return null;
}
}
abstract class Application {
abstract Product createProduct();
public Product getObj() {
return createProduct();
}
}
class CreateProductA extends Application {
@Override
Product createProduct() {
return new ProductA();
}
}
class CreateProductB extends Application {
@Override
Product createProduct() {
return new ProductB();
}
}
2.1 抽象工厂模式
定义
提供一个创建一系列相关或互相依赖的对象接口,而无需指定他们具体的类
应用场景
程序需要处理不同系列的相关产品,但是您不希望它依赖于这些产品的具体类时,可以使用抽象工厂
优点:
- 可以确信你从工厂得到的产品彼此是兼容的
- 可以避免具体产品和客户端代码之间的紧密耦合
- 符合单一职责原则
- 符合开闭原则
public class AbstractFactoryTest {
public static void main(String[] args) {
MYSQLDatabase database = new MYSQLDatabase();
IConnection connection = database.getConnection();
ICommand command = database.getCommand();
connection.connect();
command.command();
OracleDatabase oracleDatabase = new OracleDatabase();
oracleDatabase.getConnection().connect();
oracleDatabase.getCommand().command();
}
}
interface IConnection {
void connect();
}
interface ICommand {
void command();
}
interface IDatabase {
IConnection getConnection();
ICommand getCommand();
}
class OracleConnection implements IConnection {
@Override
public void connect() {
System.out.println("oracle 连接");
}
}
class OracleCommand implements ICommand {
@Override
public void command() {
System.out.println("oracle 命令");
}
}
class OracleDatabase implements IDatabase {
@Override
public IConnection getConnection() {
return new OracleConnection();
}
@Override
public ICommand getCommand() {
return new OracleCommand();
}
}
class MYSQLConnection implements IConnection {
@Override
public void connect() {
System.out.println("mysql 连接");
}
}
class MYSQLCommand implements ICommand {
@Override
public void command() {
System.out.println("mysql 命令");
}
}
class MYSQLDatabase implements IDatabase {
@Override
public IConnection getConnection() {
return new MYSQLConnection();
}
@Override
public ICommand getCommand() {
return new MYSQLCommand();
}
}
3 建造者模式
定义
讲一个复杂对象创建与他的表示分离,使得同样的构建过程可以创建不同的表示
应用场景
- 需要生成的对象具有复杂的内部机构
- 需要生成的对象内部属性本身互相依赖
- 与不可变对象配合使用
优点
- 建造者独立,易扩展
- 便于控制细节风险
public class BuilderTest {
public static void main(String[] args) {
DefaultConcreteProductBuilder productBuilder = new DefaultConcreteProductBuilder();
Director director = new Director(productBuilder);
director.makeProduct("asdasd", "adsad", "dasda", "dadssa", "dsad", "dsadsa", "dasd");
System.out.println(productBuilder.build());
}
}
interface ProductBuilder {
void builderProductName(String productName);
void builderCompanyName(String companyName);
void builderPart1(String part1);
void builderPart2(String part2);
void builderPart3(String part3);
void builderPart4(String part4);
void builderPart5(String part5);
Product build();
}
class DefaultConcreteProductBuilder implements ProductBuilder {
private String productName;
private String companyName;
private String part1;
private String part2;
private String part3;
private String part4;
private String part5;
@Override
public void builderProductName(String productName) {
this.productName = productName;
}
@Override
public void builderCompanyName(String companyName) {
this.companyName = companyName;
}
@Override
public void builderPart1(String part1) {
this.part1 = part1;
}
@Override
public void builderPart2(String part2) {
this.part2 = part2;
}
@Override
public void builderPart3(String part3) {
this.part3 = part3;
}
@Override
public void builderPart4(String part4) {
this.part4 = part4;
}
@Override
public void builderPart5(String part5) {
this.part5 = part5;
}
@Override
public Product build() {
return new Product(this.productName, this.companyName, this.part1, this.part2, this.part3, this.part4, this.part5);
}
}
class Director {
private ProductBuilder builder;
public Director(ProductBuilder builder) {
this.builder = builder;
}
public Product makeProduct(String productName, String companyName, String part1, String part2, String part3, String part4, String part5) {
builder.builderProductName(productName);
builder.builderCompanyName(companyName);
builder.builderPart1(part1);
builder.builderPart2(part2);
builder.builderPart3(part3);
builder.builderPart4(part4);
builder.builderPart5(part5);
return builder.build();
}
}
class Product {
private String productName;
private String companyName;
private String part1;
private String part2;
private String part3;
private String part4;
private String part5;
public Product() {
}
public Product(String productName, String companyName, String part1, String part2, String part3, String part4, String part5) {
this.productName = productName;
this.companyName = companyName;
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.part4 = part4;
this.part5 = part5;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public String getPart3() {
return part3;
}
public void setPart3(String part3) {
this.part3 = part3;
}
public String getPart4() {
return part4;
}
public void setPart4(String part4) {
this.part4 = part4;
}
public String getPart5() {
return part5;
}
public void setPart5(String part5) {
this.part5 = part5;
}
@Override
public String toString() {
return "Product{" +
"productName='" + productName + '\'' +
", companyName='" + companyName + '\'' +
", part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3='" + part3 + '\'' +
", part4='" + part4 + '\'' +
", part5='" + part5 + '\'' +
'}';
}
}
4. 原型模式
知识点
- Cloneable接口/Object#clone方法讲解
- 浅拷贝/深拷贝
- 序列化机制实现深拷贝
定义
指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
应用场景
当代码不应该依赖于需要赋值的对象的具体类时,请使用 Prototype 模式
优点
- 可以不耦合具体类的情况下克隆对象
- 避免重复的初始化代码
- 更方便的构建复杂对象
package com.zdx.prototype;
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User("tom", "123456", new Base("男"));
User clone = user.clone();
user.getBase().setSex("女");
System.out.println("旧数据" + user);
System.out.println("copy 数据" + clone);
}
}
class Base implements Cloneable{
private String sex;
public Base(String sex) {
this.sex = sex;
}
public Base() {
}
public String getSex() {
return sex;
}
@Override
protected Base clone() throws CloneNotSupportedException {
return ((Base) super.clone());
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Base{" +
"sex='" + sex + '\'' +
'}';
}
}
class User implements Cloneable{
private String username;
private String password;
private Base base;
public User() {
}
public User(String username, String password, Base base) {
this.username = username;
this.password = password;
this.base = base;
}
public Base getBase() {
return base;
}
public void setBase(Base base) {
this.base = base;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.setBase(user.getBase().clone());
return user;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", base=" + base +
'}';
}
}
5. 享元模式
定义
运用共享技术有效地支持大量细粒度的对象
优点
如果系统有大量类似的对象,可以节省大量的内存及cpu资源
public class FlyWeightTest {
public static void main(String[] args) {
new TreeNode(1, 4, TreeFactory.getTree("aaa", "xxxxxxxx"));
new TreeNode(1, 4, TreeFactory.getTree("aaa", "xxxxxxxx"));
new TreeNode(1, 4, TreeFactory.getTree("bbb", "xxxxxxxx"));
new TreeNode(1, 4, TreeFactory.getTree("bbb", "xxxxxxxx"));
}
}
class TreeFactory {
private static Map<String, Tree> treeMap = new ConcurrentHashMap<>();
public static Tree getTree(String name, String data) {
if (treeMap.containsKey(name)) {
return treeMap.get(name);
}
Tree tree = new Tree(name, data);
treeMap.put(name, tree);
return tree;
}
}
class TreeNode {
private int x;
private int Y;
private Tree tree;
public TreeNode(int x, int y, Tree tree) {
this.x = x;
Y = y;
this.tree = tree;
}
}
class Tree {
private final String name;
private final String data;
public Tree(String name, String data) {
System.out.println("树被创建");
this.name = name;
this.data = data;
}
public String getName() {
return name;
}
public String getData() {
return data;
}
}
6 门面模式(外观模式)
定义
为子系统中的一组接口提供一个一致的接口, Facade 模式定义啦一个高层接口,这个接口使得子系统更加容易使用
应用场景
- 当您需要使用复杂子系统的有限直接的接口时,请使用 Facade 模式
- 当您需要将子系统组织成层时,请使用 Facade 模式
public class FacadeTest {
public static void main(String[] args) {
Facade facade = new Facade();
facade.m1();
}
}
class Facade {
private Coffee coffee = new Coffee();
private Meal meal = new Meal();
private Tidy tidy = new Tidy();
public void m1() {
coffee.m1();
coffee.m2();
coffee.m3();
meal.m1();
meal.m2();
meal.m3();
tidy.m1();
tidy.m2();
tidy.m3();
}
}
class Coffee {
public void m1() {
System.out.println("磨料");
}
public void m2() {
System.out.println("烧水");
}
public void m3() {
System.out.println("泡水");
}
}
class Meal {
public void m1() {
System.out.println("准备食材");
}
public void m2() {
System.out.println("开火");
}
public void m3() {
System.out.println("做饭");
}
}
class Tidy {
public void m1() {
System.out.println("清理咖啡杯子");
}
public void m2() {
System.out.println("洗碗");
}
public void m3() {
System.out.println("清理灶台");
}
}
7. 适配器模式
定义
将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原来由于接口不兼容而不能一起工作的哪些类可以一起工作
应用场景
- 当你希望使用某些现有类,但其接口与您的其它代码不兼容时,请使用适配器类
- 当您希望重用几个现有的子类,这些子类缺少一些不能添加到超类中的公共功能时,请使用该模式
优点
- 符合单一职责原则
- 符合开闭原则
对象适配器
public class AdapterTest1 {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target adapter = new Adapter(adaptee);
System.out.println(adapter.output5V());
}
}
class Adaptee {
public int output220V() {
return 220;
}
}
interface Target {
int output5V();
}
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public int output5V() {
System.out.println(String.format("原始电压:%d -> 输出电压%d", 220, 5));
return adaptee.output220V() / 44;
}
}
类适配器
public class AdapterTest2 {
public static void main(String[] args) {
Target adapter = new Adapter();
System.out.println(adapter.output5V());
}
}
class Adaptee {
public int output220V() {
return 220;
}
}
interface Target {
int output5V();
}
class Adapter extends Adaptee implements Target {
@Override
public int output5V() {
System.out.printf("原始电压:%d -> 输出电压%d%n", 220, 5);
return super.output220V() / 44;
}
}
8.装饰者模式
定义
在不改变原有对象的基础上,将功能附加到对象上
应用场景
扩展一个类的功能或给一个类添加附加职责
优点
- 不改变原有对象的情况下给一个类扩展功能
- 使用不同组合可以实现不同的效果
- 符合开闭原则
public class DecoratorTest {
public static void main(String[] args) {
Component component = new ConreteDecorator2(new ConreteDecorator1(new ConcreteComponent()));
component.operation();
}
}
interface Component {
void operation();
}
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("拍照");
}
}
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
}
class ConreteDecorator1 extends Decorator {
public ConreteDecorator1(Component component) {
super(component);
}
@Override
public void operation() {
System.out.println("添加美颜效果");
component.operation();
}
}
class ConreteDecorator2 extends Decorator {
public ConreteDecorator2(Component component) {
super(component);
}
@Override
public void operation() {
System.out.println("添加滤镜效果");
component.operation();
}
}
9. 策略模式
定义
定义啦算法族,分别封装起来,让它们之间可以互相替换,此模式的变化独立于算法的使用者
public class StrategyTest {
public static void main(String[] args) {
Zombie zombie = new NormalZombie();
zombie.display();
zombie.move();
zombie.attack();
System.out.println("--------");
zombie.setAttackable(new HitAttack());
zombie.display();
zombie.move();
zombie.attack();
}
}
interface Moveable {
void move();
}
interface Attackable {
void attack();
}
abstract class Zombie {
abstract public void display();
public Zombie() {
}
public Zombie(Moveable moveable, Attackable attackable) {
this.moveable = moveable;
this.attackable = attackable;
}
Moveable moveable;
Attackable attackable;
abstract void move();
abstract void attack();
public Moveable getMoveable() {
return moveable;
}
public void setMoveable(Moveable moveable) {
this.moveable = moveable;
}
public Attackable getAttackable() {
return attackable;
}
public void setAttackable(Attackable attackable) {
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 HitAttack implements Attackable {
@Override
public void attack() {
System.out.println("打");
}
}
class NormalZombie extends Zombie {
public NormalZombie() {
super(new StepByStepMove(), new BiteAttack());
}
public NormalZombie(Moveable moveable, Attackable attackable) {
super(moveable, attackable);
}
@Override
public void display() {
System.out.println("普通僵尸");
}
@Override
void move() {
moveable.move();
}
@Override
void attack() {
attackable.attack();
}
}
class FlagZombie extends Zombie {
public FlagZombie() {
super(new StepByStepMove(), new BiteAttack());
}
@Override
public void display() {
System.out.println("旗手僵尸");
}
@Override
void move() {
moveable.move();
}
@Override
void attack() {
attackable.attack();
}
}
10 模版方法模式
定义
定义一个操作的算法骨架,而将一些步骤延迟到子类汇总。 Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
public class TemplateMethodTest {
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.operation();
}
}
abstract class AbstractClass {
public void operation() {
System.out.println("pre ....");
System.out.println("step1...");
System.out.println("step2...");
templateMethod();
System.out.println("close");
}
protected abstract void templateMethod();
}
class SubClass extends AbstractClass {
@Override
protected void templateMethod() {
System.out.println("自己的实现");
}
}
11 观察者模式
定义
定义啦对象之前的一对多的依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,他的所有依赖都会收到通知并更新
应用场景
当更改一个对象的状态可能需要更改其他对象,并且实际的对象集事先未知或动态更改时,请使用观察者模式
优点:
- 符合开闭原则
- 可以在运行时建立对象之间的关系
public class ObServerTest {
public static void main(String[] args) {
Subject subject = new Subject();
subject.addObserver(new Task1());
subject.addObserver(new Task2());
subject.notifyObserver("xxxxxx ");
}
}
class Subject {
List<Observer> container = new ArrayList<>();
public void addObserver(Observer observer) {
container.add(observer);
}
public void remove(Observer observer) {
container.remove(observer);
}
public void notifyObserver(Object obj) {
for (Observer observer : container) {
observer.update(obj);
}
}
}
interface Observer {
void update(Object obj);
}
class Task1 implements Observer {
@Override
public void update(Object obj) {
System.out.println("task1 :" + obj);
}
}
class Task2 implements Observer {
@Override
public void update(Object obj) {
System.out.println("task2 : " + obj);
}
}
12 责任链模式
定义
为请求创建一个接受者对象的链
应用场景
一个请求的处理需要多个对象当中的一个过几个协作处理
优点
- 请求的发送者和接受者解耦
- 可以控制执行顺序
- 符合开闭原则和单一职责原则
public class ChainOfResponsibilityTest {
public static void main(String[] args) {
Request build = new Request.RequestBuilder().loggedOn(false)
.frequentOk(true).build();
RequestFrequentHandler handler = new RequestFrequentHandler(new LoginHandler(null));
if (handler.process(build)) {
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 boolean isLoggedOn() {
return loggedOn;
}
public void setLoggedOn(boolean loggedOn) {
this.loggedOn = loggedOn;
}
public boolean isFrequentOk() {
return frequentOk;
}
public void setFrequentOk(boolean frequentOk) {
this.frequentOk = frequentOk;
}
public boolean isPermits() {
return isPermits;
}
public void setPermits(boolean permits) {
isPermits = permits;
}
public boolean isContainsSensitiveWords() {
return containsSensitiveWords;
}
public void setContainsSensitiveWords(boolean containsSensitiveWords) {
this.containsSensitiveWords = containsSensitiveWords;
}
public String getRequestBody() {
return requestBody;
}
public void setRequestBody(String requestBody) {
this.requestBody = 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;
public RequestBuilder loggedOn(boolean loggedOn) {
this.loggedOn = loggedOn;
return this;
}
public RequestBuilder frequentOk(boolean frequentOk) {
this.frequentOk = frequentOk;
return this;
}
public RequestBuilder isPermits(boolean isPermits) {
this.isPermits = isPermits;
return this;
}
public RequestBuilder containsSensitiveWords(boolean containsSensitiveWords) {
this.containsSensitiveWords = containsSensitiveWords;
return this;
}
public Request build() {
return new Request(loggedOn, frequentOk, isPermits, containsSensitiveWords);
}
}
}
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 RequestFrequentHandler extends Handler {
public RequestFrequentHandler(Handler next) {
super(next);
}
@Override
boolean process(Request request) {
System.out.println("访问频率控制");
if (request.isFrequentOk()) {
Handler handler = getNext();
if (handler == null) {
return true;
}
if (!next.process(request)) {
return false;
} else {
return true;
}
}
return false;
}
}
class LoginHandler extends Handler {
public LoginHandler(Handler next) {
super(next);
}
@Override
boolean process(Request request) {
System.out.println("登录");
if (request.isLoggedOn()) {
Handler handler = getNext();
if (handler == null) {
return true;
}
if (!handler.process(request)) {
return false;
} else {
return true;
}
}
return false;
}
}