本专栏将从基础开始,循序渐进,由浅入深讲解常见的设计模式,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
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
- 引入依赖
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
</dependencies>
- 使用如下
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());
}
}