一、观察者模式
1.1概述
1.2结构
1.3实现
抽象观察者
package com.yanyu.Subscribe;
public interface Observer {
void update(String message);
}
具体观察者
package com.yanyu.Subscribe;
import java.util.ArrayList;
import java.util.List;
public class SubscriptionSubject implements Subject {
//储存订阅公众号的微信用户
private List<Observer> weixinUserlist = new ArrayList<Observer>();
@Override
public void attach(Observer observer) {
weixinUserlist.add(observer);
}
@Override
public void detach(Observer observer) {
weixinUserlist.remove(observer);
}
@Override
public void notify(String message) {
for (Observer observer : weixinUserlist) {
observer.update(message);
}
}
}
抽象主题类
package com.yanyu.Subscribe;
public interface Subject {
//增加订阅者
public void attach(Observer observer);
//删除订阅者
public void detach(Observer observer);
//通知订阅者更新消息
public void notify(String message);
}
具体主题
package com.yanyu.Subscribe;
import java.util.ArrayList;
import java.util.List;
public class SubscriptionSubject implements Subject {
//储存订阅公众号的微信用户
private List<Observer> weixinUserlist = new ArrayList<Observer>();
@Override
public void attach(Observer observer) {
weixinUserlist.add(observer);
}
@Override
public void detach(Observer observer) {
weixinUserlist.remove(observer);
}
@Override
public void notify(String message) {
for (Observer observer : weixinUserlist) {
observer.update(message);
}
}
}
客户端类
package com.yanyu.Subscribe;
public class Client {
public static void main(String[] args) {
SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
//创建微信用户
WeixinUser user1=new WeixinUser("孙悟空");
WeixinUser user2=new WeixinUser("猪悟能");
WeixinUser user3=new WeixinUser("沙悟净");
//订阅公众号
mSubscriptionSubject.attach(user1);
mSubscriptionSubject.attach(user2);
mSubscriptionSubject.attach(user3);
//公众号更新发出消息给订阅的微信用户
mSubscriptionSubject.notify("\n专栏更新了");
}
}
1.4优缺点
1.5应用场景
1.6JDK中提供的实现
在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。
1,Observable类
Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象,下面来介绍它最重要的 3 个方法。
- void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。
- void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。
- void setChange() 方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为true时,notifyObservers() 才会通知观察者。
2,Observer 接口
Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 update 方法,进行相应的工作。
【例】警察抓小偷
警察抓小偷也可以使用观察者模式来实现,警察是观察者,小偷是被观察者。代码如下:
小偷是一个被观察者,所以需要继承Observable类
package com.yanyu.Subscribe1;
import java.util.Observable;
public class Thief extends Observable {
private String name;
public Thief(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void steal() {
System.out.println("小偷:我偷东西了,有没有人来抓我!!!");
super.setChanged(); //changed = true
super.notifyObservers();
}
}
警察是一个观察者,所以需要让其实现Observer接口
package com.yanyu.Subscribe1;
import java.util.Observable;
import java.util.Observer;
public class Policemen implements Observer {
private String name;
public Policemen(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println("警察:" + ((Thief) o).getName() + ",我已经盯你很久了,你可以保持沉默,但你所说的将成为呈堂证供!!!");
}
}
客户端代码
package com.yanyu.Subscribe1;
public class Client {
public static void main(String[] args) {
//创建小偷对象
Thief t = new Thief("隔壁老王");
//创建警察对象
Policemen p = new Policemen("小李");
//让警察盯着小偷
t.addObserver(p);
//小偷偷东西
t.steal();
}
}
二、中介者模式
2.1概述
2.2结构
2.3实现
【例】租房
现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。
类图如下:
抽象中介者(Mediator)角色
package com.yanyu.mediator;
//抽象中介者
public abstract class Mediator {
//申明一个联络方法
public abstract void constact(String message,Person person);
}
具体中介者(ConcreteMediator)角色
package com.yanyu.mediator;
// 中介机构
public class MediatorStructure extends Mediator {
// 首先中介结构必须知道所有房主和租房者的信息
private HouseOwner houseOwner; // 房主
private Tenant tenant; // 租房者
// 获取房主信息
public HouseOwner getHouseOwner() {
return houseOwner;
}
// 设置房主信息
public void setHouseOwner(HouseOwner houseOwner) {
this.houseOwner = houseOwner;
}
// 获取租房者信息
public Tenant getTenant() {
return tenant;
}
// 设置租房者信息
public void setTenant(Tenant tenant) {
this.tenant = tenant;
}
// 联系方法,发送信息给对应的人
public void constact(String message, Person person) {
if (person == houseOwner) { // 如果是房主,则租房者获得信息
tenant.getMessage(message);
} else { // 反之则是房主获得信息
houseOwner.getMessage(message);
}
}
}
抽象同事类(Colleague)角色
package com.yanyu.mediator;
//抽象同事类
public abstract class Person {
protected String name;
protected Mediator mediator;
public Person(String name,Mediator mediator){
this.name = name;
this.mediator = mediator;
}
}
具体同事类(Concrete Colleague)角色
package com.yanyu.mediator;
//具体同事类 房屋拥有者
public class HouseOwner extends Person {
public HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}
//与中介者联系
public void constact(String message){
mediator.constact(message, this);
}
//获取信息
public void getMessage(String message){
System.out.println("房主" + name +"获取到的信息:" + message);
}
}
package com.yanyu.mediator;
//具体同事类 承租人
public class Tenant extends Person {
public Tenant(String name, Mediator mediator) {
super(name, mediator);
}
//与中介者联系
public void constact(String message){
mediator.constact(message, this);
}
//获取信息
public void getMessage(String message){
System.out.println("租房者" + name +"获取到的信息:" + message);
}
}
客户端角色
package com.yanyu.mediator;
//测试类
public class Client {
public static void main(String[] args) {
//一个房主、一个租房者、一个中介机构
MediatorStructure mediator = new MediatorStructure();
//房主和租房者只需要知道中介机构即可
HouseOwner houseOwner = new HouseOwner("张三", mediator);
Tenant tenant = new Tenant("李四", mediator);
//中介结构要知道房主和租房者
mediator.setHouseOwner(houseOwner);
mediator.setTenant(tenant);
tenant.constact("需要租三室的房子");
houseOwner.constact("我这有三室的房子,你需要租吗?");
}
}
2.4优缺点
2.5应用场景
三·、访问者模式
3.1概述
3.2结构
3.3实现
【例】给宠物喂食
现在养宠物的人特别多,我们就以这个为例,当然宠物还分为狗,猫等,要给宠物喂食的话,主人可以喂,其他人也可以喂食。
- 访问者角色:给宠物喂食的人
- 具体访问者角色:主人、其他人
- 抽象元素角色:动物抽象类
- 具体元素角色:宠物狗、宠物猫
- 结构对象角色:主人家
抽象访问者(Visitor)角色
package com.yanyu.visitor;
public interface Person {
void feed(Cat cat);
void feed(Dog dog);
}
具体访问者角色
package com.yanyu.visitor;
public class Owner implements Person {
@Override
public void feed(Cat cat) {
System.out.println("主人喂食猫");
}
@Override
public void feed(Dog dog) {
System.out.println("主人喂食狗");
}
}
抽象元素(Element)角色
package com.yanyu.visitor;
public interface Animal {
void accept(Person person);
}
具体元素角色
package com.yanyu.visitor;
public class Dog implements Animal {
@Override
public void accept(Person person) {
person.feed(this);
System.out.println("好好吃,汪汪汪!!!");
}
}
package com.yanyu.visitor;
public class Cat implements Animal {
@Override
public void accept(Person person) {
person.feed(this);
System.out.println("好好吃,喵喵喵!!!");
}
}
对象结构(Object Structure)角色
package com.yanyu.visitor;
import java.util.ArrayList;
import java.util.List;
public class Home {
private List<Animal> nodeList = new ArrayList<Animal>();
public void action(Person person) {
for (Animal node : nodeList) {
node.accept(person);
}
}
//添加操作
public void add(Animal animal) {
nodeList.add(animal);
}
}
客户端角色
package com.yanyu.visitor;
public class Client {
public static void main(String[] args) {
Home home = new Home();
home.add(new Dog());
// home.add(new Cat());
Owner owner = new Owner();
home.action(owner);
Someone someone = new Someone();
home.action(someone);
}
}
3.4 优缺点
3.5使用场景
3.6扩展
访问者模式用到了一种双分派的技术。
1,分派:
变量被声明时的类型叫做变量的静态类型,有些人又把静态类型叫做明显类型;而变量所引用的对象的真实类型又叫做变量的实际类型。比如 Map map = new HashMap()
,map变量的静态类型是 Map
,实际类型是 HashMap
。根据对象的类型而对方法进行的选择,就是分派(Dispatch),分派(Dispatch)又分为两种,即静态分派和动态分派。
静态分派(Static Dispatch) 发生在编译时期,分派根据静态类型信息发生。静态分派对于我们来说并不陌生,方法重载就是静态分派。
动态分派(Dynamic Dispatch) 发生在运行时期,动态分派动态地置换掉某个方法。Java通过方法的重写支持动态分派。
2,动态分派:
通过方法的重写支持动态分派。
public class Animal {
public void execute() {
System.out.println("Animal");
}
}
public class Dog extends Animal {
@Override
public void execute() {
System.out.println("dog");
}
}
public class Cat extends Animal {
@Override
public void execute() {
System.out.println("cat");
}
}
public class Client {
public static void main(String[] args) {
Animal a = new Dog();
a.execute();
Animal a1 = new Cat();
a1.execute();
}
}
3,静态分派:
通过方法重载支持静态分派。
public class Animal {
}
public class Dog extends Animal {
}
public class Cat extends Animal {
}
public class Execute {
public void execute(Animal a) {
System.out.println("Animal");
}
public void execute(Dog d) {
System.out.println("dog");
}
public void execute(Cat c) {
System.out.println("cat");
}
}
public class Client {
public static void main(String[] args) {
Animal a = new Animal();
Animal a1 = new Dog();
Animal a2 = new Cat();
Execute exe = new Execute();
exe.execute(a);
exe.execute(a1);
exe.execute(a2);
}
}
四、观察者模式实验
抽象观察者
package step1;
public interface IDisplayElement {
void display();
}
具体观察者
package step1;
public class CurrentConditionsDisplay implements IObserver,IDisplayElement{
private float temperature;
private float humidity;
@Override
public void display() {
System.out.println ("现状: " + temperature + "F度和" + humidity + "% 湿度");
}
@Override
public void Update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}
package step1;
public class StatisticsDisplay implements IObserver,IDisplayElement{
private float maxTemp = 0.0f;
private float minTemp = 200;
private float tempSum = 0.0f;
private int numReadings;
@Override
public void display() {
System.out.println ("平均/最高/最低温度 = " + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp);
}
@Override
public void Update(float temperature, float humidity, float pressure) {
tempSum += temperature;
numReadings++;
if (temperature > maxTemp)
{
maxTemp = temperature;
}
if (temperature < minTemp)
{
minTemp = temperature;
}
display();
}
}
package step1;
public class ForecastDisplay implements IObserver,IDisplayElement{
private float currentPressure = 29.92f;
private float lastPressure;
@Override
public void display() {
String info="";
if (currentPressure > lastPressure) {
info="气温正在上升";
}
else if (currentPressure == lastPressure) {
info="气温没有变化";
}
else{
info="气温正变得凉爽";
}
System.out.println("预测: "+info);
}
@Override
public void Update(float temperature, float humidity, float pressure) {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
}
package step1;
public class HeatIndexDisplay implements IObserver,IDisplayElement{
float heatIndex = 0.0f;
@Override
public void display() {
System.out.println("热指数 " + heatIndex);
}
@Override
public void Update(float temperature, float humidity, float pressure) {
heatIndex = computeHeatIndex(temperature, humidity);
display();
}
private float computeHeatIndex(float t, float rh){
float index = (float)((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh)
+ (0.00941695 * (t * t)) + (0.00728898 * (rh * rh))
+ (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
(rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
(0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
0.000000000843296 * (t * t * rh * rh * rh)) -
(0.0000000000481975 * (t * t * t * rh * rh * rh)));
return index;
}
}
抽象主题
package step1;
public interface IObserver {
void Update(float temperature, float humidity, float pressure);
}
package step1;
public interface ISubject {
void RegisterObserver(IObserver o);//注册观察者
void RemoveObserver(IObserver o);//注销观察者
void notifyObservers();///数据发生变化时,通知观察者
}
具体主题
package step1;
import java.util.ArrayList;
public class WeatherData implements ISubject {
private float temperature;//温度
private float humidity;//湿度
private float pressure;//压力
private ArrayList<IObserver> observers= new ArrayList<>();
@Override
public void RegisterObserver(IObserver o) {
/********** Begin ****注册观察者*****/
observers.add(o);
/********** End *********/
}
@Override
public void RemoveObserver(IObserver o) {
/********** Begin ****注销观察者*****/
observers.remove(o);
/********** End *********/
}
@Override
public void notifyObservers() {
/********** Begin ****通知观察者*****/
for (IObserver observer : observers) {
observer.Update(temperature, humidity, pressure); // Notify each observer
}
/********** End *********/
}
public void setMeasurements(float temperature, float humidity, float pressure)
{
/********** Begin ****数据接口*****/
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
/********** End *********/
}
private void measurementsChanged()
{
notifyObservers();
}
}
客户端类
package step1;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
/********** Begin ****请搭建天气Subject及观察者的结构*****/
WeatherData weatherData = new WeatherData(); // 创建天气数据主题
CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(); // 创建当前天气显示观察者
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(); // 创建统计显示观察者
ForecastDisplay forecastDisplay = new ForecastDisplay();
// 创 建气温预测显示观察者
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(); // 创建热力值显示观察者
weatherData.RegisterObserver(currentConditionsDisplay);
weatherData.RegisterObserver(statisticsDisplay);
weatherData.RegisterObserver(forecastDisplay);
weatherData.RegisterObserver(heatIndexDisplay);
/********** End *********/
以下将模拟天气数据发生n次变化/
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
float temp,humidity,pressure;
for (int i = 0; i <n ; i++) {
temp= scanner.nextFloat();
humidity= scanner.nextFloat();
pressure= scanner.nextFloat();
/********** Begin *********/
通知所有的观察者
weatherData.setMeasurements(temp, humidity, pressure); // 更新天气数据
weatherData.notifyObservers();
/********** End *********/
}
}
}
五、中介者模式实验
抽象中介者(Mediator)角色
package step1;
///抽象中介者
public interface Mediator {
// 通知方法,用于传递事件信息给中介者
/*
该方法接收四个参数:发送者 (sender)、事件名 (event)、受影响的土地 (land) 和影响因素 (pest)。
*/
void notify(Object sender, String event, String land, String pest);
}
具体中介者(ConcreteMediator)角色
package step1;
import java.util.Hashtable;
/**
* FarmlandManagementSystem充当中介者,串联起各子系统。
*/
public class FarmlandManagementSystem implements Mediator {
private Hashtable farmlands = new Hashtable();
private PestDetectionSystem pestDetectionSystem;
private ExpertAdviceSystem expertAdviceSystem;
/**
* 添加农田到系统中。
* @param farmland 要添加的农田。
*/
public void addFarmland(Farmland farmland) {
if (!farmlands.contains(farmland)) {
farmlands.put(farmland.getName(), farmland);
}
}
/**
* 从系统中移除农田。
* @param farmland 要移除的农田。
*/
public void removeFarmland(Farmland farmland) {
farmlands.remove(farmland);
}
/**
* 设置用于中介者的虫害检测系统。
* @param pestDetectionSystem 要设置的虫害检测系统。
*/
public void setPestDetectionSystem(PestDetectionSystem pestDetectionSystem) {
this.pestDetectionSystem = pestDetectionSystem;
}
/**
* 设置用于中介者的农民建议系统。
* @param expertAdviceSystem 要设置的农民建议系统。
*/
public void setExpertAdviceSystem(ExpertAdviceSystem expertAdviceSystem) {
this.expertAdviceSystem = expertAdviceSystem;
}
/**
* 通知中介者有关事件,并采取适当的行动。
* @param sender 发送通知的对象。
* @param event 被通知的事件。
* @param land 与事件相关的土地。
* @param pest 与事件相关的虫害。
*/
@Override
public void notify(Object sender, String event, String land, String pest) {
if (event.equals("pestDetected")) {
Farmland farmland = (Farmland) farmlands.get(land);
expertAdviceSystem.provideAdvice(farmland, pest);
}
}
}
抽象同事类(Colleague)角色
package step1;
import java.util.List;
public class Farmland {
private String name;
private double size;
private List<String> crops;///土地上种植的作物
public Farmland(String location, double size, List<String> crops) {
this.name = location;
this.size = size;
this.crops = crops;
}
public String getName() {
return name;
}
public double getSize() {
return size;
}
public List<String> getCrops() {
return crops;
}
}
具体同事类(Concrete Colleague)角色
package step1;
public class ExpertAdviceSystem {
private Mediator mediator;
public ExpertAdviceSystem(Mediator mediator) {
this.mediator = mediator;
}
public void provideAdvice(Farmland farmland, String pest) {
// 模拟向农民提供预防和治疗建议的过程
String advice = "请及时采取相应的防治措施";
System.out.println("农民" + farmland.getName() + "收到了关于" + pest + "的建议:" + advice);
}
}
package step1;
public class PestDetectionSystem {
private Mediator mediator;
public PestDetectionSystem(Mediator mediator) {
this.mediator = mediator;
}
public void detectPest(String farmland, String pest) {
// 模拟程序中病虫害检测功能忽略,直接发出警报
mediator.notify(this, "pestDetected", farmland, pest);
}
}
客户端类
package step1;
import java.util.Hashtable;
/**
* FarmlandManagementSystem acts as a mediator to connect various subsystems.
* FarmlandManagementSystem充当中介者,串联起各子系统。
*/
public class FarmlandManagementSystem implements Mediator {
private Hashtable farmlands = new Hashtable(); // Hashtable用于存储农田信息
private PestDetectionSystem pestDetectionSystem; // 用于虫害检测的子系统
private ExpertAdviceSystem expertAdviceSystem; // 用于农民建议的子系统
/**
* Add a farmland to the system.
* 将农田添加到系统中。
* @param farmland The farmland to be added. 要添加的农田
*/
public void addFarmland(Farmland farmland) {
if (!farmlands.contains(farmland)) {
farmlands.put(farmland.getName(), farmland); // 将农田信息存入Hashtable
}
}
/**
* Remove a farmland from the system.
* 从系统中移除农田。
* @param farmland The farmland to be removed. 要移除的农田
*/
public void removeFarmland(Farmland farmland) {
farmlands.remove(farmland); // 从Hashtable中移除农田信息
}
/**
* Set the pest detection system for the mediator.
* 为中介者设置虫害检测系统。
* @param pestDetectionSystem The pest detection system to be set. 要设置的虫害检测系统
*/
public void setPestDetectionSystem(PestDetectionSystem pestDetectionSystem) {
this.pestDetectionSystem = pestDetectionSystem; // 设置虫害检测子系统
}
/**
* Set the farmer advice system for the mediator.
* 为中介者设置农民建议系统。
* @param expertAdviceSystem The expert advice system to be set. 要设置的农民建议系统
*/
public void setFarmerAdviceSystem(ExpertAdviceSystem expertAdviceSystem) {
this.expertAdviceSystem = expertAdviceSystem; // 设置农民建议子系统
}
/**
* Notify the mediator about an event and take appropriate action.
* 通知中介者有关事件,并采取适当的行动。
* @param sender The object that sends the notification. 发送通知的对象
* @param event The event being notified. 被通知的事件
* @param land The land related to the event. 与事件相关的土地
* @param pest The pest related to the event. 与事件相关的虫害
*/
@Override
public void notify(Object sender, String event, String land, String pest) {
if (event.equals("pestDetected")) { // 如果事件是虫害检测
Farmland farmland = (Farmland) farmlands.get(land); // 获取与事件相关的农田信息
expertAdviceSystem.provideAdvice(farmland, pest); // 调用农民建议子系统提供建议
}
}
}
六、访问者模式实验
抽象元素(Element)角色
package step1;
public interface Crop {
void accept(CropVisitor visitor);
}
具体元素(ConcreteElement)角色
package step1;
public class CucumberCrop implements Crop{
private String name;
// 省略其它属性和方法
public String getName() {
return name;
}
public CucumberCrop(String cropname)
{
name = cropname;
}
@Override
public void accept(CropVisitor visitor) {
visitor.visit(this);
}
}
package step1;
public class TomatoCrop implements Crop{
private String name;
// 省略其它属性和方法
public String getName() {
return name;
}
public TomatoCrop(String cropname)
{
name = cropname;
}
public void accept(CropVisitor visitor) {
visitor.visit(this);
}
}
抽象访问者(Visitor)角色
package step1;
public interface CropVisitor {
void visit(TomatoCrop tomatoCrop);
void visit(CucumberCrop cucumberCrop);
void visit(CauliflowerCrop cauliflowerCrop);
}
具体访问者角色:
package step1;
public class GrowthVisitors implements CropVisitor{
@Override
public void visit(TomatoCrop tomatoCrop) {
System.out.println(tomatoCrop.getName() + "生长监控完成");
}
@Override
public void visit(CucumberCrop cucumberCrop) {
System.out.println(cucumberCrop.getName() + "生长监控完成");
}
@Override
public void visit(CauliflowerCrop cauliflowerCrop) {
System.out.println(cauliflowerCrop.getName() + "生长监控完成");
}
}
package step1;
/********** Begin *********/
public class PestsVisitors implements CropVisitor{
@Override
public void visit(TomatoCrop tomatoCrop) {
System.out.println(tomatoCrop.getName() + "病虫害监控完成");
}
@Override
public void visit(CucumberCrop cucumberCrop) {
System.out.println(cucumberCrop.getName() + "病虫害监控完成");
}
@Override
public void visit(CauliflowerCrop cauliflowerCrop) {
System.out.println(cauliflowerCrop.getName() + "病虫害监控完成");
}
}
/********** End *********/
对象结构(Object Structure)角色
package step1;
import java.util.ArrayList;
import java.util.Iterator;
/**
* CropGroup represents a group of crops and provides methods to add, remove, and accept visitors.
* CropGroup表示一组农作物,提供添加、移除和接受访问者的方法。
*/
public class CropGroup {
private ArrayList list = new ArrayList(); // 用ArrayList存储农作物
/**
* Accept a visitor to visit all crops in the group.
* 接受访问者访问组中的所有农作物。
* @param visitor The visitor to be accepted. 要接受的访问者
*/
public void accept(CropVisitor visitor) {
Iterator i = list.iterator(); // 使用迭代器遍历所有农作物
while (i.hasNext()) {
((Crop) i.next()).accept(visitor); // 调用每个农作物的accept方法,让访问者访问该农作物
}
}
/**
* Add a crop to the group.
* 将一个农作物添加到组中。
* @param crop The crop to be added. 要添加的农作物
*/
public void addCrop(Crop crop) {
list.add(crop); // 将农作物添加到ArrayList中
}
/**
* Remove a crop from the group.
* 从组中移除一个农作物。
* @param crop The crop to be removed. 要移除的农作物
*/
public void removeProduct(Crop crop) {
list.remove(crop); // 从ArrayList中移除农作物
}
}
客户端类
package step1;
public class Client {
public static void main(String[] args) {
CucumberCrop cucumberCrop=new CucumberCrop("黄瓜实验田1");
CauliflowerCrop cauliflowerCrop = new CauliflowerCrop("花菜实验田2");
TomatoCrop tomatoCrop = new TomatoCrop("番茄实验田3");
CropGroup cropgroup = new CropGroup();
cropgroup.addCrop(cucumberCrop);
cropgroup.addCrop(cauliflowerCrop);
cropgroup.addCrop(tomatoCrop);
CropVisitor visitor = new GrowthVisitors();
cropgroup.accept(visitor);
/********** Begin *********/
CropVisitor visitor2 = new PestsVisitors();
cropgroup.accept(visitor2);
/********** End *********/
}
}