了解 forEach()
的来由。
简单来说,实作任意资料结构的 forEach()
,最常见的莫过於 Array
、List
等,其他像是 Linked List
、Stack
、Queue
、Tree
等也是可实作的资料结构,在模式内负责储存的物件称作 Aggregate。
这次的实作,采用 Array
(JS)、 List
(Java),放入名为 Car
的物件。
相关作法是:
Array
(JS)、 List
(Java) 方法,像是:
Array
(JS)、 List
(Java) 长度。Array
(JS)、 List
(Java) 负责储存物件。Car
物件後,搭配 While
模拟 forEach()
。以下范例以「依序检查车库内的二手车辆」为核心制作。
放入 Aggregate 内的物件:Car
private String name;
private String manufacturer;
private int productionYear;
private int gasolinePercent;
public Car(String name, String manufacturer, int productionYear, int gasolinePercent) {
this.name = name;
this.manufacturer = manufacturer;
this.productionYear = productionYear;
this.gasolinePercent = gasolinePercent;
}
public String getName() {
return name;
}
public String getManufacturer() {
return manufacturer;
}
public int getProductionYear() {
return productionYear;
}
public int getGasolinePercent() {
return gasolinePercent;
}
}
Aggregate 的虚拟层亲代:UsedCarDealerAggregate
public interface UsedCarDealerAggregate {
CarIterator createCarIterator();
int size();
Car getCar(int index);
void add(Car car);
}
Iterator 的虚拟层亲代:CarIterator
public interface CarIterator {
Car getFirst();
Car getCurrent();
Car getNext();
boolean isDone();
void reset();
}
Aggregate 的子代:UsedCarDealer
public class UsedCarDealer implements UsedCarDealerAggregate {
private List<Car> list;
public UsedCarDealer() {
this.list = new ArrayList<>();
}
@Override
public CarIterator createCarIterator() {
return new UsedCarDealerIterator(this);
}
@Override
public int size() {
return list.size();
}
@Override
public Car getCar(int index) {
return list.get(index);
}
@Override
public void add(Car car) {
list.add(car);
}
}
Iterator 的子代:UsedCarDealerIterator
public class UsedCarDealerIterator implements CarIterator {
private UsedCarDealer usedCarDealer;
private int currentIndex = 0;
public UsedCarDealerIterator(UsedCarDealer usedCarDealer) {
this.usedCarDealer = usedCarDealer;
}
@Override
public Car getFirst() {
return usedCarDealer.getCar(0);
}
@Override
public Car getCurrent() {
if (currentIndex < usedCarDealer.size()) {
return usedCarDealer.getCar(currentIndex);
} else {
return null;
}
}
@Override
public Car getNext() {
currentIndex++;
if (currentIndex < usedCarDealer.size()) {
return usedCarDealer.getCar(currentIndex);
} else {
return null;
}
}
@Override
public boolean isDone() {
return currentIndex < usedCarDealer.size();
}
@Override
public void reset() {
currentIndex = 0;
}
public void showCurrentDetails() {
Car currentCar = getCurrent();
System.out.println("车辆的型号是 " + currentCar.getName() + " ,制造商则是 " + currentCar.getManufacturer());
Calendar calendar = Calendar.getInstance();
if ((calendar.get(Calendar.YEAR) - currentCar.getProductionYear()) > 10) {
System.out.println("注意,车龄大於 10 年");
}
if (currentCar.getGasolinePercent() > 50) {
System.out.println("油量足够\n");
} else {
System.out.println("油量不足,该加油了\n");
}
}
}
测试,输入车库内的车辆资料後,逐一检查:UsedCarDealerIteratorSample
public class UsedCarDealerIteratorSample {
public static void main(String[] args) {
UsedCarDealer sellingCars = new UsedCarDealer();
sellingCars.add(new Car("RX450h", "Lexus", 2020, 100));
sellingCars.add(new Car("M3", "BMW", 2015, 90));
sellingCars.add(new Car("Camaro 2SS", "Chevrolet", 2017, 50));
sellingCars.add(new Car("Continental Flying Spur", "Bentley", 2008, 10));
sellingCars.add(new Car("Mustang", "Ford", 2020, 10));
sellingCars.add(new Car("MGB", "MG", 1979, 5));
sellingCars.add(new Car("Porsche", "Cayman S", 2014, 20));
sellingCars.add(new Car("S60 T5", "Volvo", 2020, 15));
sellingCars.add(new Car("Grand Cherokee Overland", "Jeep", 2017, 58));
UsedCarDealerIterator carIterator = new UsedCarDealerIterator(sellingCars);
while (carIterator.isDone()) {
carIterator.showCurrentDetails();
carIterator.getNext();
}
}
}
放入 Aggregate 内的物件:Car
class Car {
/**
* @param {string} name
* @param {string} manufacturer
* @param {number} productionYear
* @param {number} gasolinePercent
*/
constructor(name, manufacturer, productionYear, gasolinePercent) {
this.name = name;
this.manufacturer = manufacturer;
this.productionYear = productionYear;
this.gasolinePercent = gasolinePercent;
}
getName() {
return this.name;
}
getManufacturer() {
return this.manufacturer;
}
getProductionYear() {
return this.productionYear;
}
getGasolinePercent() {
return this.gasolinePercent;
}
}
Aggregate 的虚拟层亲代:UsedCarDealerAggregate
/** @interface */
class UsedCarDealerAggregate {
createCarIterator() { return; }
size() { return; }
/** @param {number} index */
getCar(index) { return; }
/** @param {Car} car */
add(car) { return; }
}
Iterator 的虚拟层亲代:CarIterator
/** @interface */
class CarIterator {
getFirst() { return; }
getCurrent() { return; }
getNext() { return; }
isDone() { return; }
reset() { return; }
}
Aggregate 的子代:UsedCarDealer
class UsedCarDealer extends UsedCarDealerAggregate {
constructor() {
super();
/** @type {Car[]} */
this.list = [];
}
/** @override */
createCarIterator() {
return new UsedCarDealerIterator(this);
}
/** @override */
size() {
return this.list.length;
}
/**
* @override
* @param {number} index
*/
getCar(index) {
return this.list[index];
}
/**
* @override
* @param {Car} car
*/
add(car) {
this.list.push(car);
}
}
Iterator 的子代:UsedCarDealerIterator
class UsedCarDealerIterator extends CarIterator {
/** @param {UsedCarDealer} usedCarDealer */
constructor(usedCarDealer) {
super();
this.usedCarDealer = usedCarDealer;
this.currentIndex = 0;
}
/** @override */
getFirst() {
return this.usedCarDealer.getCar(0);
}
/** @override */
getCurrent() {
if (this.currentIndex < this.usedCarDealer.size()) {
return this.usedCarDealer.getCar(this.currentIndex);
} else {
return null;
}
}
/** @override */
getNext() {
this.currentIndex++;
if (this.currentIndex < this.usedCarDealer.size()) {
return this.usedCarDealer.getCar(this.currentIndex);
} else {
return null;
}
}
/** @override */
isDone() {
return this.currentIndex < this.usedCarDealer.size();
}
/** @override */
reset() {
this.currentIndex = 0;
}
showCurrentDetails() {
const currentCar = this.getCurrent();
console.log("车辆的型号是 " + currentCar.getName() + " ,制造商则是 " + currentCar.getManufacturer());
const date = new Date();
if ((date.getFullYear() - currentCar.getProductionYear()) > 10) {
console.log("注意,车龄大於 10 年");
}
if (currentCar.getGasolinePercent() > 50) {
console.log("油量足够\n");
} else {
console.log("油量不足,该加油了\n");
}
}
}
测试,输入车库内的车辆资料後,逐一检查:UsedCarDealerIteratorSample
const usedCarDealerIteratorSample = () => {
const sellingCars = new UsedCarDealer();
sellingCars.add(new Car("RX450h", "Lexus", 2020, 100));
sellingCars.add(new Car("M3", "BMW", 2015, 90));
sellingCars.add(new Car("Camaro 2SS", "Chevrolet", 2017, 50));
sellingCars.add(new Car("Continental Flying Spur", "Bentley", 2008, 10));
sellingCars.add(new Car("Mustang", "Ford", 2020, 10));
sellingCars.add(new Car("MGB", "MG", 1979, 5));
sellingCars.add(new Car("Porsche", "Cayman S", 2014, 20));
sellingCars.add(new Car("S60 T5", "Volvo", 2020, 15));
sellingCars.add(new Car("Grand Cherokee Overland", "Jeep", 2017, 58));
const carIterator = new UsedCarDealerIterator(sellingCars);
while (carIterator.isDone()) {
carIterator.showCurrentDetails();
carIterator.getNext();
}
}
usedCarDealerIteratorSample();
Iterator 模式可说是历史的轨迹,1994 年的时候,forEach()
的概念尚未成为许多程序语言的内建语法,因此需要特地开一个模式教导他人如何实作。时光飞逝,forEach()
的概念已经变成许多语言的内建语法,这时候来看 Iterator 模式显得有点尴尬,因为看了似乎也没学到什麽,不看内心觉得没有脚踏实地阅读「物件导向设计模式」。
想到唯一的用途是,其他资料结构需要实作 forEach()
功能的话,就需要这个模式了
明天将介绍 Behavioural patterns 的第五个模式:Mediator 模式。
回顾一下我们这个月到底做了些什麽 从IDE到最後上架 元件、属性使用 MVP 架构以及布局的介绍 ...
Nan => Not a Number,要判断是不是NaN要用:isNaN(); 注意自动转...
早起运动Day8 - 身体习惯 不假思索的起床,做第一件事情以後就会带到第二件事情。 就像看...
这边简单介绍两者差异和选择: Parcelable: 效能比Serializable好,在记忆体开销...
-电子发现参考模型 证人(Witnesses )和证据(evidence)决定了司法结果。及时的电...