【设计模式】中介者模式、观察者模式(通知模式,观察者是被通知对象)以及访问者模式(数据和操作分开)

本专栏将从基础开始,循序渐进,由浅入深讲解常见的设计模式,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。

1 中介者模式

package design;

import lombok.AllArgsConstructor;
import lombok.Data;

class ChatRoom{
    
    
    public void showMsg(User user,String msg){
    
    
        System.out.println("["+user.getName()+"]"+msg);
    }
}

@Data
@AllArgsConstructor
class User{
    
    
    private String name;
    private ChatRoom chatRoom;

    public void sendMessage(String msg){
    
    
        this.chatRoom.showMsg(this,msg);
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        ChatRoom room = new ChatRoom();

        User tom = new User("Tom",room);
        User jerry = new User("Jerry",room);
        tom.sendMessage("AAAAAAAAAAA");
        jerry.sendMessage("BBBBBBBBBBBB");
    }

}

2 观察者模式(通知模式,观察者是被通知对象)

2.1 常用形式

package design;

import java.util.ArrayList;
import java.util.List;

public class Client {
    
    
    //抽象观察者(被通知)
    public interface IObserver<E>{
    
    
        void update(E event);
    }

    //抽象主题者(通知方)
    public interface ISubject<E>{
    
    
        boolean attach(IObserver<E> observer);
        boolean detach(IObserver<E> observer);
        void notify(E event);
    }

    static class ConcreteObserver<E> implements IObserver<E>{
    
    
        public void update(E event) {
    
    
            System.out.println("receive event "+event);
        }
    }

    //具体主题者
    static class ConcreteSubject<E> implements ISubject<E>{
    
    

        private List<IObserver<E>> observers = new ArrayList<IObserver<E>>();

        public boolean attach(IObserver<E> observer) {
    
    
            return !this.observers.contains(observer) && this.observers.add(observer);
        }

        public boolean detach(IObserver<E> observer) {
    
    
            return this.observers.remove(observer);
        }

        public void notify(E event) {
    
    
            for (IObserver<E> observer : this.observers) {
    
    
                observer.update(event);
            }
        }
    }

    public static void main(String[] args) {
    
    
        //通知方
        ISubject<String> observable = new ConcreteSubject<String>();
        //被通知方
        IObserver<String> observer = new ConcreteObserver<String>();
        //注册
        observable.attach(observer);
        //通知
        observable.notify("hello");
    }

}

2.2 Guava

  1. 引入依赖
<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>31.0.1-jre</version>
    </dependency>
</dependencies>
  1. 使用如下
package design;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

class GuavaEnent{
    
    
    @Subscribe
    public void subscribe(String str){
    
    
        //业务逻辑
        System.out.println("执行subscribe方法,传入的参数是:"+str);
    }
}

public class Client {
    
    
    public static void main(String[] args) {
    
    
        EventBus eventBus = new EventBus();
        GuavaEnent guavaEnent = new GuavaEnent();
        eventBus.register(guavaEnent);
        eventBus.post("Tom");
    }
}

3 访问者模式(数据和操作分开)

package design;

//访问者模式,对于不同的访问者,访问的形式不一样,如CTO关注工程师的代码量、经理的新产品数量;CEO 关注工程师的KPI、经理的KPI及新产品数量。

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

interface IVisitor{
    
    
    //访问工程师类型
    void visit(Engineer engineer);

    //访问经理类型
    void visit(Manager manager);
}


abstract class Employee{
    
    
    public String name;
    public int kpi;

    public Employee(String name) {
    
    
        this.name = name;
        this.kpi = new Random().nextInt(10);
    }

    public abstract void accept(IVisitor visitor);
}

class Engineer extends Employee{
    
    

    public Engineer(String name) {
    
    
        super(name);
    }

    public int getCodeLines(){
    
    
        return new Random().nextInt(10*10000);
    }

    @Override
    public void accept(IVisitor visitor) {
    
    
        visitor.visit(this);
    }
}

class Manager extends Employee{
    
    

    public Manager(String name) {
    
    
        super(name);
    }

    public int getProducts(){
    
    
        return new Random().nextInt(10);
    }

    public void accept(IVisitor visitor) {
    
    
        visitor.visit(this);
    }
}

class BusinessReport{
    
    
    private List<Employee> employees = new LinkedList<Employee>();

    public BusinessReport(){
    
    
        employees.add(new Manager("经理-A"));
        employees.add(new Engineer("工程师-A"));

    }

    public void showReport(IVisitor visitor){
    
    
        for(Employee employee : employees){
    
    
            employee.accept(visitor);
        }
    }
}

class CEOVisitor implements IVisitor{
    
    

    public void visit(Engineer engineer) {
    
    
        System.out.println("工程师:" + engineer.name + ",KPI:" + engineer.kpi);
    }

    public void visit(Manager manager) {
    
    
        System.out.println("经理:" + manager.name + ",KPI:" + manager.kpi + ",新产品数量:" + manager.getProducts());
    }
}

class CTOVisitor implements IVisitor{
    
    

    public void visit(Engineer engineer) {
    
    
        System.out.println("工程师:" + engineer.name + ",代码行数:" + engineer.getCodeLines());
    }

    public void visit(Manager manager) {
    
    
        System.out.println("经理:" + manager.name + ",新产品数量:" + manager.getProducts());
    }
}

public class Client
{
    
    
    public static void main(String[] args) {
    
    
        BusinessReport report = new BusinessReport();
        System.out.println("========CEO看报表=============");
        report.showReport(new CEOVisitor());
        System.out.println("========CTO看报表=============");
        report.showReport(new CTOVisitor());
    }


}

猜你喜欢

转载自blog.csdn.net/Learning_xzj/article/details/125027675
今日推荐