Java 如何避免';instanceof';在实施工厂设计模式时?
我正在尝试实现我的第一个Factory设计模式,我不确定在将Factory生成的对象添加到列表时如何避免使用instanceof。这就是我想做的:Java 如何避免';instanceof';在实施工厂设计模式时?,java,design-patterns,factory,factory-pattern,instanceof,Java,Design Patterns,Factory,Factory Pattern,Instanceof,我正在尝试实现我的第一个Factory设计模式,我不确定在将Factory生成的对象添加到列表时如何避免使用instanceof。这就是我想做的: for (ABluePrint bp : bluePrints) { AVehicle v = AVehicleFactory.buildVehicle(bp); allVehicles.add(v); // Can I accomplish this without using 'instanceof'? if (
for (ABluePrint bp : bluePrints) {
AVehicle v = AVehicleFactory.buildVehicle(bp);
allVehicles.add(v);
// Can I accomplish this without using 'instanceof'?
if (v instanceof ACar) {
cars.add((ACar) v);
} else if (v instanceof ABoat) {
boats.add((ABoat) v);
} else if (v instanceof APlane) {
planes.add((APlane) v);
}
}
从我所读到的来看,使用“instanceof”是一种代码味道。是否有更好的方法来检查工厂创建的车辆类型,而不使用“instanceof”
我欢迎任何关于我的实施的反馈/建议,因为我甚至不确定我是否以正确的方式进行
完整示例如下:
import java.util.ArrayList;
class VehicleManager {
public static void main(String[] args) {
ArrayList<ABluePrint> bluePrints = new ArrayList<ABluePrint>();
ArrayList<AVehicle> allVehicles = new ArrayList<AVehicle>();
ArrayList<ACar> cars = new ArrayList<ACar>();
ArrayList<ABoat> boats = new ArrayList<ABoat>();
ArrayList<APlane> planes = new ArrayList<APlane>();
/*
* In my application I have to access the blueprints through an API
* b/c they have already been created and stored in a data file.
* I'm creating them here just for example.
*/
ABluePrint bp0 = new ABluePrint(0);
ABluePrint bp1 = new ABluePrint(1);
ABluePrint bp2 = new ABluePrint(2);
bluePrints.add(bp0);
bluePrints.add(bp1);
bluePrints.add(bp2);
for (ABluePrint bp : bluePrints) {
AVehicle v = AVehicleFactory.buildVehicle(bp);
allVehicles.add(v);
// Can I accomplish this without using 'instanceof'?
if (v instanceof ACar) {
cars.add((ACar) v);
} else if (v instanceof ABoat) {
boats.add((ABoat) v);
} else if (v instanceof APlane) {
planes.add((APlane) v);
}
}
System.out.println("All Vehicles:");
for (AVehicle v : allVehicles) {
System.out.println("Vehicle: " + v + ", maxSpeed: " + v.maxSpeed);
}
System.out.println("Cars:");
for (ACar c : cars) {
System.out.println("Car: " + c + ", numCylinders: " + c.numCylinders);
}
System.out.println("Boats:");
for (ABoat b : boats) {
System.out.println("Boat: " + b + ", numRudders: " + b.numRudders);
}
System.out.println("Planes:");
for (APlane p : planes) {
System.out.println("Plane: " + p + ", numPropellers: " + p.numPropellers);
}
}
}
class AVehicle {
double maxSpeed;
AVehicle(double maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
class ACar extends AVehicle {
int numCylinders;
ACar(double maxSpeed, int numCylinders) {
super(maxSpeed);
this.numCylinders = numCylinders;
}
}
class ABoat extends AVehicle {
int numRudders;
ABoat(double maxSpeed, int numRudders) {
super(maxSpeed);
this.numRudders = numRudders;
}
}
class APlane extends AVehicle {
int numPropellers;
APlane(double maxSpeed, int numPropellers) {
super(maxSpeed);
this.numPropellers = numPropellers;
}
}
class AVehicleFactory {
public static AVehicle buildVehicle(ABluePrint blueprint) {
switch (blueprint.type) {
case 0:
return new ACar(100.0, 4);
case 1:
return new ABoat(65.0, 1);
case 2:
return new APlane(600.0, 2);
default:
return new AVehicle(0.0);
}
}
}
class ABluePrint {
int type; // 0 = car; // 1 = boat; // 2 = plane;
ABluePrint(int type) {
this.type = type;
}
}
import java.util.ArrayList;
高级车辆管理员{
公共静态void main(字符串[]args){
ArrayList蓝图=新的ArrayList();
ArrayList allVehicles=新的ArrayList();
ArrayList cars=新的ArrayList();
ArrayList=新的ArrayList();
ArrayList平面=新的ArrayList();
/*
*在我的应用程序中,我必须通过API访问蓝图
*b/c它们已经创建并存储在数据文件中。
*我在这里创建它们只是举个例子。
*/
ABluePrint bp0=新ABluePrint(0);
ABluePrint bp1=新的ABluePrint(1);
ABluePrint bp2=新的ABluePrint(2);
蓝图。添加(bp0);
蓝图。添加(bp1);
蓝图。添加(bp2);
用于(ABluePrint bp:蓝图){
AVehicle v=AVehicleFactory.buildVehicle(bp);
所有车辆。添加(v);
//我可以不用“instanceof”来完成这个任务吗?
if(ACar的v实例){
增加((ACar)v);
}else if(v ABoat实例){
添加((ABoat)v);
}else if(APlane的v实例){
添加((平面)v);
}
}
系统输出打印项次(“所有车辆:”);
适用于(车辆五:所有车辆){
系统输出打印项次(“车辆:+v+”,最大速度:+v.maxSpeed);
}
System.out.println(“Cars:”);
适用于(ACar c:汽车){
System.out.println(“车:+c+”,numCylinders:+c.numCylinders);
}
System.out.println(“船:”);
对于(ABoat b:船){
System.out.println(“船:+b+”,numruders:+b.numruders);
}
System.out.println(“平面:”);
对于(APlane p:飞机){
System.out.println(“平面:+p+”,numPropellers:+p.numPropellers);
}
}
}
类车辆{
双最大速度;
A车辆(双最大速度){
this.maxSpeed=maxSpeed;
}
}
ACar类扩展车辆{
国际货币基金组织;
ACar(双最大速度,整数气缸){
超级(最大速度);
this.numcylinds=numcylinds;
}
}
类ABoat扩展了AVehicle{
整数乳房;
ABoat(双最大速度,整数个乳房){
超级(最大速度);
this.numRudders=numRudders;
}
}
APlane类扩展了AVehicle{
国际货币基金组织;
APlane(双最大速度,整数){
超级(最大速度);
this.numPropellers=numPropellers;
}
}
阿维类山核桃工厂{
公共静态车辆制造车辆(ABluePrint蓝图){
开关(blueprint.type){
案例0:
返回新的ACar(100.0,4);
案例1:
返回新的ABoat(65.0,1);
案例2:
返回新APlane(600.0,2);
违约:
返回新车辆(0.0);
}
}
}
ABluePrint类{
int type;//0=汽车;//1=船;//2=飞机;
ABluePrint(整型){
this.type=type;
}
}
您可以将方法添加到车辆类以打印文本。然后重写每个专用汽车类中的方法。然后只需将所有车辆添加到车辆列表中。然后循环列表以打印文本。对代码进行了一些重构。希望对你有用。选中此项:
import java.util.ArrayList;
class VehicleManager {
public static void main(String[] args) {
ArrayList<ABluePrint> bluePrints = new ArrayList<ABluePrint>();
ArrayList<AVehicle> allVehicles = new ArrayList<AVehicle>();
ArrayList<ACar> cars = null;
ArrayList<ABoat> boats = null;
ArrayList<APlane> planes = null;
/*
* In my application I have to access the blueprints through an API
* b/c they have already been created and stored in a data file.
* I'm creating them here just for example.
*/
ABluePrint bp0 = new ABluePrint(0);
ABluePrint bp1 = new ABluePrint(1);
ABluePrint bp2 = new ABluePrint(2);
bluePrints.add(bp0);
bluePrints.add(bp1);
bluePrints.add(bp2);
for (ABluePrint bp : bluePrints) {
AVehicle v = AVehicleFactory.buildVehicle(bp);
allVehicles.add(v);
// Can I accomplish this without using 'instanceof'?
// dont add objects to list here, do it from constructor or in factory
/*if (v instanceof ACar) {
cars.add((ACar) v);
} else if (v instanceof ABoat) {
boats.add((ABoat) v);
} else if (v instanceof APlane) {
planes.add((APlane) v);
}*/
}
cars = ACar.getCars();
boats = ABoat.getBoats();
planes = APlane.getPlanes();
System.out.println("All Vehicles:");
for (AVehicle v : allVehicles) {
System.out.println("Vehicle: " + v + ", maxSpeed: " + v.maxSpeed);
}
System.out.println("Cars:");
for (ACar c : cars) {
System.out.println("Car: " + c + ", numCylinders: " + c.numCylinders);
}
System.out.println("Boats:");
for (ABoat b : boats) {
System.out.println("Boat: " + b + ", numRudders: " + b.numRudders);
}
System.out.println("Planes:");
for (APlane p : planes) {
System.out.println("Plane: " + p + ", numPropellers: " + p.numPropellers);
}
}
}
class AVehicle {
double maxSpeed;
AVehicle(double maxSpeed) {
this.maxSpeed = maxSpeed;
}
void add(){}
}
class ACar extends AVehicle {
static ArrayList<ACar> cars = new ArrayList<ACar>();
int numCylinders;
ACar(double maxSpeed, int numCylinders) {
super(maxSpeed);
this.numCylinders = numCylinders;
}
void add(){
cars.add(this);
}
public static ArrayList<ACar> getCars(){
return cars;
}
}
class ABoat extends AVehicle {
static ArrayList<ABoat> boats = new ArrayList<ABoat>();
int numRudders;
ABoat(double maxSpeed, int numRudders) {
super(maxSpeed);
this.numRudders = numRudders;
}
void add(){
boats.add(this);
}
public static ArrayList<ABoat> getBoats(){
return boats;
}
}
class APlane extends AVehicle {
static ArrayList<APlane> planes = new ArrayList<APlane>();
int numPropellers;
APlane(double maxSpeed, int numPropellers) {
super(maxSpeed);
this.numPropellers = numPropellers;
}
void add(){
planes.add(this);
}
public static ArrayList<APlane> getPlanes(){
return planes;
}
}
class AVehicleFactory {
public static AVehicle buildVehicle(ABluePrint blueprint) {
AVehicle vehicle;
switch (blueprint.type) {
case 0:
vehicle = new ACar(100.0, 4);
break;
case 1:
vehicle = new ABoat(65.0, 1);
break;
case 2:
vehicle = new APlane(600.0, 2);
break;
default:
vehicle = new AVehicle(0.0);
}
vehicle.add();
return vehicle;
}
}
class ABluePrint {
int type; // 0 = car; // 1 = boat; // 2 = plane;
ABluePrint(int type) {
this.type = type;
}
}
import java.util.ArrayList;
高级车辆管理员{
公共静态void main(字符串[]args){
ArrayList)。您可以实现
详细答案
其思想是使用来执行类型检查。每个子类重写accept(Visitor)
方法,该方法应在超类中声明。当出现以下情况时:
void add(Vehicle vehicle) {
//what type is vehicle??
}
我们可以将一个对象传递到Vehicle
中声明的方法中。如果Vehicle
类型为Car
,并且类Car
覆盖了我们传递对象的方法,那么该对象现在将在Car
类中声明的方法中进行处理。我们利用这个优势:创建访问者代码>对象并将其传递给重写的方法:
abstract class Vehicle {
public abstract void accept(AddToListVisitor visitor);
}
class Car extends Vehicle {
public void accept(AddToListVisitor visitor) {
//gets handled in this class
}
}
此访问者
应准备好访问类型汽车
。任何想要避免使用实例
查找实际类型的类型都必须在访问者
中指定
class AddToListVisitor {
public void visit(Car car) {
//now we know the type! do something...
}
public void visit(Plane plane) {
//now we know the type! do something...
}
}
这里是进行类型检查的地方!
当Car
接收访问者时,它应该使用this
关键字传入。由于我们在类Car
,将调用方法visit(Car)
。在访问者内部,我们可以执行我们想要的操作,现在我们知道了对象的类型
因此,从顶部:
您创建了一个执行所需操作的访问者
。访问者应包含一个访问者
方法,用于您要对其执行操作的每种类型的对象。在这种情况下,我们为车辆创建访问者:
interface VehicleVisitor {
void visit(Car car);
void visit(Plane plane);
void visit(Boat boat);
}
我们要执行的操作是将车辆添加到某些内容中。我们将创建一个AddTransportVisitor
;一个管理添加运输的访问者:
class AddTransportVisitor implements VehicleVisitor {
public void visit(Car car) {
//add to car list
}
public void visit(Plane plane) {
//add to plane list
}
public void visit(Boat boat) {
//add to boat list
}
}
每辆车都应能够接待车辆访客:
abstract class Vehicle {
public abstract void accept(VehicleVisitor visitor);
}
当访客被传递到车辆时,车辆应调用其visit
方法,传递itsel
class Car extends Vehicle {
public void accept(VehicleVisitor visitor) {
visitor.visit(this);
}
}
class Boat extends Vehicle {
public void accept(VehicleVisitor visitor) {
visitor.visit(this);
}
}
class Plane extends Vehicle {
public void accept(VehicleVisitor visitor) {
visitor.visit(this);
}
}
class VehicleManager {
private List<Car> carList = new ArrayList<>();
private List<Boat> boatList = new ArrayList<>();
private List<Plane> planeList = new ArrayList<>();
private AddTransportVisitor addVisitor = new AddTransportVisitor(this);
public void add(Vehicle vehicle) {
vehicle.accept(addVisitor);
}
public List<Car> getCarList() {
return carList;
}
public List<Boat> getBoatList() {
return boatList;
}
public List<Plane> getPlaneList() {
return planeList;
}
}
class AddTransportVisitor implements VehicleVisitor {
private VehicleManager manager;
public AddTransportVisitor(VehicleManager manager) {
this.manager = manager;
}
public void visit(Car car) {
manager.getCarList().add(car);
}
public void visit(Plane plane) {
manager.getPlaneList().add(plane);
}
public void visit(Boat boat) {
manager.getBoatList().add(boat);
}
}
class VehicleManager {
private List<Car> carList = new ArrayList<>();
private List<Boat> boatList = new ArrayList<>();
private List<Plane> planeList = new ArrayList<>();
private AddTransportVisitor addVisitor = new AddTransportVisitor(this);
public void add(Vehicle vehicle) {
vehicle.accept(addVisitor);
}
public void add(Car car) {
carList.add(car);
}
public void add(Boat boat) {
boatList.add(boat);
}
public void add(Plane plane) {
planeList.add(plane);
}
public void printAllVehicles() {
//loop through vehicles, print
}
}
class AddTransportVisitor implements VehicleVisitor {
private VehicleManager manager;
public AddTransportVisitor(VehicleManager manager) {
this.manager = manager;
}
public void visit(Car car) {
manager.add(car);
}
public void visit(Plane plane) {
manager.add(plane);
}
public void visit(Boat boat) {
manager.add(boat);
}
}
public class Main {
public static void main(String[] args) {
Vehicle[] vehicles = {
new Plane(),
new Car(),
new Car(),
new Car(),
new Boat(),
new Boat()
};
VehicleManager manager = new VehicleManager();
for(Vehicle vehicle : vehicles) {
manager.add(vehicle);
}
manager.printAllVehicles();
}
}
Map<Class<? extends AVehicle>, List<? extends AVehicle>> lists = new HashMap<>();
lists.put(ACar.class, new ArrayList<ACar>());
lists.put(ABoat.class, new ArrayList<ABoat>());
lists.put(APlane.class, new ArrayList<APlane>());
for (ABluePrint bp : bluePrints) {
AVehicle v = AVehicleFactory.buildVehicle(bp);
allVehicles.add(v);
lists.get(v.getClass()).add(v);
}