栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

实施工厂设计模式时如何避免“ instanceof”?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实施工厂设计模式时如何避免“ instanceof”?

您可以实现Visitor模式。

详细答案

这个想法是使用多态来执行类型检查。每个子类都覆盖该accept(Visitor)方法,该方法应在超类中声明。当我们遇到如下情况时:

void add(Vehicle vehicle) {    //what type is vehicle??}

我们可以将一个对象传递到中声明的方法中Vehicle。如果vehicle类型为Car,并class Car覆盖我们将对象传递给的方法,则该对象现在将在Car类中声明的方法内进行处理。我们利用它的优势:创建一个Visitor对象并将其传递给重写的方法:

abstract class Vehicle {    public abstract void accept(AddToListVisitor visitor);}class Car extends Vehicle {    public void accept(AddToListVisitor visitor) {        //gets handled in this class    }}

这Visitor应该准备好访问类型Car。您想要避免使用的任何类型instanceof都必须在中指定Visitor。

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关键字传递自己。由于我们在class中Car,因此visit(Car)将调用该方法。现在我们知道了对象的类型,就可以在访问者内部执行所需的操作。

因此,从顶部开始:

您创建一个Visitor,执行所需的操作。访问者应该visit为要对其执行操作的每种对象类型提供一个方法。在这种情况下,我们正在为车辆创建访客:

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方法,并将自身传递给参数:

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);    }}

这就是类型检查的地方。visit会调用正确的方法,该方法包含根据方法的参数执行的正确代码。

最后一个问题是VehicleVisitor与列表进行交互。这就是您的VehicleManager来历:它封装了列表,使您可以通过一种VehicleManager#add(Vehicle)方法添加载具。

创建访问者时,我们可以将管理器传递给它(可能通过它的构造函数),这样,既然我们知道对象的类型,就可以执行所需的操作。本VehicleManager应包含的游客和拦截VehicleManager#add(Vehicle)来电:

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;    }}

现在,我们可以为这些AddTransportVisitor#visit方法编写实现:

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);    }}

我强烈建议删除add每种车辆的吸气剂方法并声明重载方法。这样可以减少不需要时的“访问”开销,例如manager.add(new Car()):

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;    }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/440873.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号