3

I am trying to categorize vehicles but I'm not sure about what is the best way to do it.

Why am I confused? If you think about it, vehicles can be categorized in a number of ways:

1) Nature of Vehicle: Land Vehicle, WaterCrafts & AirCrafts. 2) Another way of categorizing: Powered Vehicles and NonPowered Vehicles like Tractor (Non powered and just attached with truck), Truck etc. 3) Loading nature of vehicle: Vehicle can be loaded or not.

Let me take an example: Vehicle -> Land Vehicle -> Powered/NonPowered -> Loadable/NonLoadable.

If you see, I am creating many subclasses but what use of it other than property difference that it is loadable or not. I can do that using interfaces also. Implements Loadable?powered interfaces to vehicle which can allow loading.

For example: vehicle -> LandVehicle -> Tractor LandVehicle will implement interfaces like isPowered and isLoadable, which will be overriden by tractor as false and true resp.

I know that Inheritance is for "isa" relationship and interfaces for "can do" but how that make difference here because it can be used interchangeably.

What is the best way to solve such kind of problems.

SpaceCore186
  • 586
  • 1
  • 8
  • 22
user3089214
  • 267
  • 3
  • 14
  • 1
    The best way to solve these problems is to use *composition* rather than *inheritance*. Someone might write an answer to your specific question, but see: http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – WW. Feb 12 '16 at 00:47
  • Thanks WW. I don't think that Composition can help me here or might i need to think again if that really helps. – user3089214 Feb 12 '16 at 00:54
  • Multiple attributes + multiple combinations of attributes == Decorator Pattern. – dbugger Feb 12 '16 at 00:57
  • You'de have to explain how they differ in behavior and attributes... – plalx Feb 12 '16 at 13:07
  • What do you do with a seaplane? – David Osborne Feb 12 '16 at 14:34
  • Has your question been answered yet? If so, please select the answer that was most helpful. – 4castle Mar 22 '16 at 14:07

3 Answers3

1

The best way to solve this kind of problem is to use the KISS rule: Keep It Simple Silly!

In this case, use inheritance for the "major" divisions in categorization, and use interfaces for the "minor" divisions in categorization. This is because Java only allows single-inheritance (the major division), but puts no limit on the number of interfaces (the minor divisions) the class can implement.

However, if you aren't looking to add behaviors for each category and just want some descriptions of the Vehicle, use composition by doing something like:

public class Vehicle {
    private List<VehicleDescription> descriptions = new ArrayList<VehicleDescription>();

    public void addDescription(VehicleDescription description) {
        descriptions.add(description);
    }

    public boolean hasDescription(VehicleDescription description) {
        return descriptions.indexOf(description) > -1;
}

public enum VehicleDescription {
    Land, Water, Air, Powered, NonPowered, Loadable, NonLoadable
}

You can add as many "Description" type enum lists in your Vehicle class as you want (so that you could prevent doing things like being both Loadable & NonLoadable), and you would only need a few classes!

In summary, use composition when possible.

4castle
  • 32,613
  • 11
  • 69
  • 106
0

Are these Vehicles differ by capabilities or attributes?

  1. Attributes: Use Builder_pattern to build different type of vehicles with different attributes.

  2. Capabilities: Use interface to provide different capabilities and define Decorator to add capabilities.

If you need mix of both, use Builder + Decorator pattern properly.

You can use Composite_pattern for list of capabilities in Vehicle class. Vehicle class will maintain List < Capability >

Have a look at these examples:

Keeping builder in separate class (fluent interface)

When to Use the Decorator Pattern?

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
0

Composition matches better in your case. Imagine that your vehicles consist of components like ignition system, fuel system, transmission, cabin etc. As you can see many of types have unique components: 2, 3, 4 wheels, tracks, hover/ fwd, rwd, awd / combustion engine (fuel system meant) or electric (electric system). Inheritance will make your architecture very constrained and hard to modify.

With composition you don't even need to categorize your vehicles. Just add components to them. If your want to use filter to search vehicles by params like number of wheel, type of drive - you can implement ISearchable interface with a method which accepts criteria and make lookup of its vehicle components whether all of them match the criteria.

Dzianis Yafimau
  • 2,034
  • 1
  • 27
  • 38