Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Tuesday, February 9, 2016

Where do new methods go?

Where do new methods go?


Let's say I have an object, Car, and it has sets of methods that are... disparate? Maybe getting Blob-like? (as in the antipattern, "blob") These methods operate in distinct enough sets and don't really criss-cross functionally.

Car  # methods related to suburban driving    ->foo1    ->foo2  # methods related city driving    ->bar3    ->bar4  

Now let's say I wanted to add "off road driving" as one of the cases that my car object can support. If I add methods to the Car object, isn't that making it more blob like?

Car (augmented)  # methods related to suburban driving    ->foo1    ->foo2  # methods related city driving    ->bar3    ->bar4  # methods related off road driving    ->blah5    ->blah6  

Should I:

A: Subclass Car. I can make an OffRoadCar extends Car object. But what if Car and OffRoadCar share the same data/state, and only differ by methods? OffRoadCar only "acts" more specifically than car, but isn't described any more specifically nor does it have unique fields. So instantiating an OffRoadCar is meaningless.

OffRoadCar extends Car  # methods related off road driving    ->blah5    ->blah6  

B: Consume Car with a Static Method. Like OffRoadAdventure->Embark(Car). So the OffRoadAdventure class takes a Car object and has its way with it.

In C# this would be called an extension method.

I guess put another way is what is the solution to the Blob antipattern? Is it subclassing? Is it extension methods?

Also, another reason I wanted to silo out these methods is what if their implementation incurs some cost, like the inclusion of other classes/packages? I wouldn't want users of the core class to constantly pay for something they would never use. I figure making the cost explicit for the minority is worth the savings for the majority. And it makes the dependency graph more precise (and not blob-like).

PS - Implementation language is Perl.

Answer by Diego for Where do new methods go?


I think you are in the right track. An elegant solution is to have OffRoadCar inherit from Car and override its Drive() method. That way, you can say:

Car myCar = new OffRoadCar();  myCar.Drive();  

This will call the overridden Drive() method in the subclass, and you don't end up with a gazillion methods in a single "blob". Here's how the Drive() method in OffRoadCar may look like:

@Override  public void Drive()  {  /* code */  }  

Answer by Oesor for Where do new methods go?


With Perl you should be taking a good look at Moose and roles.

package Suburban;  use Moose::Role;    requires 'wheels';    sub 'foo1' {    ...  }      sub 'foo2' {    ...  }    package City;  use Moose::Role;    requires 'wheels';    sub 'bar3' {    ...  }      sub 'bar4' {    ...  }    package Offroad;  use Moose::Role;    requires 'wheels';    sub 'blah5' {    ...  }      sub 'blah6' {    ...  }    package UltraCar;  use Moose;    with qw/ Offroad City Suburban /;  has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );    package RentalCar;  use Moose;    with qw/ City Suburban /;  has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );    package Tricycle;  use Moose;    with qw/ Offroad /;  has 'wheels' => ( is => 'rw', isa => 'Int', default => 3 );  

You can even add and remove roles at runtime.

Answer by cmbuckley for Where do new methods go?


Instead of subclassing the Car class, you could use some form of Decorator pattern.

Here, the base ORM class and the decorators (say OffRoadDecorator) implement some common interface, and the behaviour of each decorator can be dynamically added to the original class.

The key difference here is that multiple decorators can be used on the same Car class, and it's up to your implementation to say how those should interact. There's nothing to stop you decorating your class using the OffRoadDecorator as well as the SuburbanDecorator, and you can decide exactly what that means for the car within the decorators.

(P.S. sorry I don't provide any code examples; my Perl is simply terrible. Have a look at this page for some other examples.)

Answer by tangent for Where do new methods go?


Not really an answer Mark and I'm not sure how deeply you want to go into this, but you could look into the idea of Method Resolution Order. Instead of the standard depth first search for methods, using mro allows you to perform a breadth first search. See this page on CPAN and brian d foy's article Use the C3 method resolution order in multiple inheritance for more.

Answer by user1168577 for Where do new methods go?


Suburban, City and Offroad Driving sound like algorithms. Strategy Pattern might help here with Context being Car.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.