I need to model a Region that has a contains(point) method. That method determines whether a point falls within the boundaries of the Region.
I currently see two implementations of Region:
One where the region is defined by a start and end postalcode.
One where the region is defined by a lat/lng and a radius.
Now, my main problem is how to define the interface for the contains() method.
Possible solution #1:
One easy solution is to let a point also be defined by a Region:
PostalcodeRegion implements Region
region = new PostalcodeRegion(postalStart: 1000, postalEnd: 2000);
point = new PostalcodeRegion(postalStart: 1234, postalEnd: 1234);
region.contains(point); // true
The interface could look like this:
Region
+ contains(Region region):bool
The problem with this is that the contains() method is not specific, and that we abuse Region to let it be something it is not: a Point.
Possible solution #2:
Or, we define a new point class:
PostalcodeRegion implements Region {}
PostalcodePoint implements Point {}
region = new PostalcodeRegion(postalStart: 1000, postalEnd: 2000);
point = new PostalcodePoint(postalCode: 1234);
region.contains(point); // true
Interface:
Region
+ contains(Point point)
There are several problems with this method:
contains() method is still not specific
There is a pointless Point concept. In and of itself it is/does nothing, it is just a marker interface.
Clarification:
Ok, so this is the first time I encounter where I provide my line of thinking, in the form of possible solutions, that is actually counter productive. My apologies.
Let me try and describe the use case: The system this use case is part of is used to handle insurance claims (amongst other things). When someone claims water damages from a leaking pipe f.e., this system handles the entire workflow from entry by the customer, all the way to sending a repair company etc to close the file.
Now, depending on circumstances, there are two ways to find eligible repair companies: by postal code, or by lat lng.
In the first case (postal code), we could find eligible repair companies with the following code:
region = new PostalCodeRegion(customer.postalCode - 500, customer.postalCode + 500)
region.contains(new PostalCodePoint(repairCompany1.postalCode))
region.contains(new PostalCodePoint(repairCompany2.postalCode))
Or, in the second case:
region = new LatLngRegion(customer.latLng, 50) // 50 km radius
region.contains(new LatLngPoint(repairCompany1.latLng))
region.contains(new LatLngPoint(repairCompany2.latLng))
I want to be able to safely pass around Regions and Points, so I can make sure they are Regions and Points. But I don't actually care about their sub-types.
One thing I would like, but I am not sure it is possible, is to not have to do a runtime check on the passed point in the contains() method. Preferably it would be enforced by contract that I get the correct data (fitting to the chosen Region implementation) to work with.
I'm mostly just thinking out loud. I am inclined to go with method #2, and do a runtime type check of the passed point var in contains() implementation.
I would like to hear some thoughts over one or the other, or even better: a new suggestion I haven't thought of.
It shouldn't be really relevant, but the target platform is PHP. So I can't use generics for example.
Given that a Region would have to operate on two abstractions that have nothing in common (Point and Postcode) then a generic interface is one way of crafting a clean strongly typed common interface, but you should question whether that abstraction is useful to model or not. As developers it's easy to get lost in too much abstractions e.g. maybe a Region<T> is just a Container<T>, etc. and all of a sudden the concepts you work with are nowhere to be found in your domain's Ubiquitous Language.
public interface Region<T> {
public boolean contains(T el);
}
class PostalRegion implements Region<Postcode> {
public boolean contains(Postcode el) { ... }
}
class GeographicRegion implements Region<Point> {
public boolean contains(Point el) { ... }
}
The issue with such question is that it's focusing on how to achieve a specific design rather than explaining the real business problem and that makes it difficult to judge whether or not the solution is appropriate or which alternate solution would.
How would the system leverage the common interface if such interface was implemented? Would it make the model easier to work with?
Since we are forced to assume a problem domain, here's a fictional scenario about developing a city zonage system (I know nothing about this domain so the example may be silly).
In the context of city zonage management, we have uniquely
identified regions that are defined by a postal code range and a
geographical area. We need a system that can answer whether or not a
postal code and/or a point is contained within a specific region.
That gives us a little more context to work with and come up with a model that can fulfill the needs.
We can assume that an application service such as RegionService could maybe look like:
class RegionService {
IRegionRepository regionRepository;
...
boolean regionContainsPoint(regionId, lat, lng) {
region = regionRepository.regionOfId(regionId);
return region.contains(new Point(lat, lng));
}
boolean regionContainsPostcode(regionId, postcode) {
region = regionRepository.regionOfId(regionId);
return region.contains(new Postcode(postcode));
}
}
Then, maybe the design would benefit from applying the Interface Segregation Principle (ISP) where you'd have a Locator<T> interface or explicit PostcodeLocator and PointLocator interfaces, implemented either by Region or other services and used by the RegionService or be a service of their own.
If answering the questions requires complex processing, etc. then maybe the logic should be extracted from a PostalRange and an Area. Applying the ISP would help keeping the design more flexible.
It's important to note that a domain model shines on the write side to protect invariants and compute complex rules & state transitions, but querying needs are often better expressed as stateless services that leverages powerful infrastructure components (e.g. database).
EDIT 1:
I had not realized you mentioned "no generics". Still leaving my answer there b/c I think it still gives good modeling insights and warns about not so useful abstractions. Always think about how the client will be using the API as it helps to determine the usefulness of an abstraction.
EDIT 2 (after clarification added):
It seems that the Specification Pattern could be a useful modeling tool here.
Customers could be said to have a repair company eligibility specification...
E.g.
class Customer {
...
repairCompanyEligibilitySpec() {
//The factory method for creating the specification doesn't have to be on the Customer
postalRange = new PostalRange(this.postalCode - 500, this.postCode + 500);
postalCodeWithin500Range = new PostalCodeWithinRange(postalRange);
locationWithin50kmRadius = new LocationWithinRadius(this.location, Distance.ofKm(50));
return postalCodeWithin500Range.and(locationWithin50kmRadius);
}
}
//Usage
repairCompanyEligibilitySpec = customer.repairCompanyEligibilitySpec();
companyEligibleForRepair = repairCompanyEligibilitySpec.isSatisfiedBy(company);
Note that I haven't really understood what you mean by "I want to be able to safely pass around Regions and Points" or at least failed to understand why this requires a common interface so perhaps the proposed design wouldn't be suitable. Making the policy/rule/spec explicit has several advantages and the specification pattern is easily extensible to support features such as describing why a company was not eligible, etc.
e.g.
unsatisfiedSpec = repairCompanyEligibilitySpec.remainderUnsatisfiedBy(company);
reasonUnsatisfied = unsatisfiedSpec.describe();
Ultimately the specification itself doesn't have to implement the operations. You could use the Visitor Pattern in order to add new operations to a set of specifications and/or to segregate operations by logical layer.
I think it's better not to have the implementation of contains in the data object and to create a seperate class for each of the contains implementations. Something like:
class Region
{
...
}
class RegionCheckManager
{
function registerCheckerForPointType(string $pointType, RegionCheckerInterface $checkerImplementation): void
{
...
}
function contains(PointInterface $point, Region $region): bool
{
return $this->getCheckerForPoint($point)->check($region, $point);
}
/** get correct checker for point type **/
private function getCheckerForPoint(PointInterface $point): RegionCheckerInterface
{
...
}
}
interface RegionCheckerInterface
{
public function contains(PointInterface $point): bool;
}
class PostcodeChecker implements RegionCheckerInterface
{
...
}
class PointChecker implements RegionCheckerInterface
{
...
}
Postcode and Point are different conceptual things, they are two different types. Postcode is a scalar value, Point is a geographic item. In fact, your PostalCodeRegion class is a range of scalar value, your LatLngRegion class is a geographic area that has center coordinates and radius. You try to combine two incompatible abstractions. Attempt to make one interface for two absolutely different things is the wrong way which leads to unobvious code and implicit abstractions. You should rethink your abstractions. For example:
What is a postcode? It is a positive number in the simplest case. You can create a Postcode class as a value object and implement simple methods to work with its data.
class Postcode
{
private $number;
public function __constuct(int $number)
{
assert($value <= 0, 'Postcode must be greater than 0');
$this->number = $number;
}
public function getNumber(): int
{
return $this->number;
}
public function greatOrEqual(Postalcode $value): bool
{
return $this->number >= $value->getNumber();
}
public function lessOrEqual(Postalcode $value): bool
{
return $this->number <= $value->getNumber();
}
}
What is a postcode range? It a set of postcodes that contains start postcode and end postcode. So you can also create a value object of a range and implement contains method in it.
class PostcodeRange
{
private $start;
private $end;
public function __construct(Postcode $start, Postcode $end)
{
assert(!$start->lessOrEqual($end));
$this->start = $start;
$this->end = $end;
}
public function contains(Postcode $value): bool
{
return $value->greatOrEqual($this->start) && $value->lessOrEqual($this->end);
}
}
What is a point? It is a geographic item that has some coordinates.
class Point
{
private $lan;
private $lng;
public function __constuct(float $lan, float $lng)
{
$this->lan = $lan;
$this->lng = $lng;
}
public function getLan(): float
{
return $this->lan;
}
public function getLng(): float
{
return $this->lng;
}
}
What is an area? It is a geographic region that has some borders. In your case, those borders defined with a circle that has a center point and some radius.
class Area
{
private $center;
private $radius;
public function __constuct(Point $center, int $radius)
{
$this->center = $center;
$this->radius = $radius;
}
public function contains(Point $point): bool
{
// implementation of method
}
}
So, each company has a postcode and some location defined by its coordinates.
class Company
{
private $postcode;
private $location;
public function __construct(Postcode $postcode, Point $location)
{
$this->postcode = $postcode;
$this->location = $location;
}
public function getPostcode(): Postcode
{
return $this->postcode;
}
public function getLocation(): Point
{
return $this->location;
}
}
So, how you said you have a list of companies and try to find it by postcode range or area. So you can create company collection which can contain all companies and can implement algorithms to search by necessary criteria.
class CompanyCollection
{
private $items;
public function __constuct(array $items)
{
$this->items = $items;
}
public function findByPostcodeRange(PostcodeRange $range): CompanyCollection
{
$items = array_filter($this->items, function(Company $item) use ($range) {
return $range->contains($item->getPostcode());
});
return new static($items);
}
public function findByArea(Area $area): CompanyCollection
{
$items = array_filter($this->items, function(Company $item) use ($area) {
return $area->contains($item->getLocation());
});
return new static($items);
}
}
Example of usage:
$collection = new CompanyCollection([
new Company(new Postcode(1200), new Point(1, 1)),
new Company(new Postcode(1201), new Point(2, 2)),
])
$range = new PostcodeRange(new Postcode(1000), new Postcode(2000));
$area = new Area(new Point(0, 0), 50);
// find only by postcode range
$collection->findByPostcodeRange($range);
// find only by area
$collection->findByArea($area);
// find by postcode range and area
$collection->findByPostcodeRange($range)->findByArea($area);
If I understand the problem correctly, you have some module M, which needs to accept some 3 objects:
implementation of region (postcodes vs radius, let's call them R1 vs R2)
implementation of point (postcode vs lat/lng, P1 vs P2)
some API C to check the point is within the region
and it then applies the 3rd object on the first 2.
(Could be that C is R1 or R2, that's immaterial for the problem definition).
So spelling out the problem: you can apply C on R1+P1 or R2+P2, but not R1+P2 or R2+P1.
I'm afraid the only way to implement it in a type-safe manner is as follows:
C is an interface, apply().
C1 implements C, and has fields of type R1, P1.
C2 implements C, and has fields of type R2, P2.
The caller builds either C1 or C2, passes it to M, and M calls c.apply().
Note how M doesn't even see points, only the checker interface C. That's because there is nothing common between P1 and P2 that anyone other than then C can use.
Related
A Model object which has some private internal state. A component of this state is exposed to the clients. But one of the clients wants a different component of the internal state to be exposed. How should this be dealt with?An example
public GarageModel {
private Vehicle car;
private Vehicle truck;
public Vehicle getMostInterestingVehicle() {
//exposes car as the most interesting vehicle but
//one of the client wants this to return a truck
return car;
}
}
It is hard to say given your sample, you could apply a strategy pattern on your GarageModel class for each different client and override that single method to cater to each of their needs. This only works if you can provide different garage models to your clients though.
Polymorphism is always the answer as a teacher of mine used to say
An example would be
public TruckGarageModel: GarageModel {
public override Vehicle getMostInterestingVehicle(){
return truck;
}
}
public CarGarageModel: GarageModel {
public override Vehicle getMostInterestingVehicle(){
return car;
}
}
Then you would pass the appropriate decorated version of your GarageModel to each different client
You could provide method with parameters which will define criteria by which your client sees most interesting vehicle.
public Vehicle getMostInterestingVehicleByCriteria(VehicleCriteria vehicleCriteria){
// logic which selects correct vehicle in simple way it will be just
if(vehicleCriteria.getMostInterestingVehicleType().equals(VehicleType.TRUCK){
//do your logic
}
// In case of multiple objects you should refactor it with simple inheritance/polymorphism or maybe use some structural pattern
}
public class VehicleCriteria{
VehicleType mostInterestingVehicle; // enum with desired vehicle type
public VehicleCriteria(VehicleType mostInterestingVehicle){
this.mostInterestingVehicle = mostInterestingVehicle;
}
}
If the client knows what type it wants, then let the client say so with a generic argument (C# assumed):
public T getMostInterestingVehicle<T>() where T : Vehicle { }
You can then use a dictionary of 'things' (factories maybe?) that will get a vehicle, keyed by the type they return. This could be a static collection created on construction or resolved by IoC:
private Dictionary<T, Vehicle> _things;
You can then use this to do the work:
public T getMostInterestingVehicle<T>() where T : Vehicle
{
FactoryThing thing;
if (_things.TryGetValue(T, out thing))
{
return thing.GetVehicle();
}
}
Apologies if it's not C# you're working with and if the syntax/usage is incorrect, but I think you'll get my point...
You might have to consider quite a few things before making a decision about the implementation, some questions are these-
Do you expect newer implementations of Vehicle to be added later?: If yes, you might have to provide a factory that could register newer types without you making changes in the factory again and again. This provides an example. That way you avoid many if-else as well.
Do you want to decide what Vehicle to return at runtime?: Then Strategy Pattern helps as pointed in other answers.
Hope this helps a little bit.
I'm trying to recreate Hearthstone cards as objects in Java, but I'm having trouble doing this in a good and efficient way.
All cards have some common properties like a 'name'. But the problem is that there is about 300 cards to generate, and there is about 30 different abilities that each card may or may not have. Now, do I have to create a basic card class with all the possible abilities set to false and then set all its specific ability parameters to true? This approach seems to get very messy with all the getters and all the extra information that some abilities needs to specify... So my question is if there's there a better way to solve this kind of problem?
I would like to create these card objects so that I'm only 'adding' the specific abilities as fields, but I can't figure out how to do this in a good way.
Thankful for help!
Like Dave said, it's a little difficult to be sure what the best solution to your problem is without more context. However, from what I can gather, your problem is a pretty common one. For common problems, programmers often create efficient solutions that can be used over and over again called design patterns.
Design patterns aren't needed in every case, so be careful not to overuse them, but it seems like they could help you here. Both solutions mentioned by Dave may work, but the problem with making each ability an object is that it requires you to make as many classes as you have abilities. Furthermore, if each ability is a simple variable, it may be overkill to create classes for all of them, particularly since so many classes can become difficult to maintain. Although having these abilities inherit from an interface somewhat helps with maintainability, I think an easier solution can probably be found in the builder pattern.
I won't explain it in detail here, but here's a tutorial that seems reasonably simple. It's basic purpose is to
For your particular example it would look something like this:
public class Card
{
private final String name;
private final Ability soundAbility;
private final Ability animationAbility;
private final Ability customMessageAbility;
private final String technology;
// The constructor is private in this case to restrict instantiation to the builder.
private Card(CardBuilder builder)
{
this.name = builder.name;
this.soundAbility = builder.soundAbility;
this.animationAbility = builder.animationAbility;
this.customMessageAbility = builder.customMessageAbility;
this.technology = builder.technology;
}
// Getters
public String getName()
{
return this.name;
}
public Ability getSoundAbility()
{
return this.soundAbility;
}
// ... More getters and stuff ...
#Override
public String toString()
{
String text = "";
text += this.name + ":";
text += "\n\t" + this.soundAbility;
text += "\n\t" + this.animationAbility;
text += "\n\t" + this.customMessageAbility;
text += "\n\tI have the ability of " + this.technology + "!";
return text;
}
// Nested builder class
public static class CardBuilder
{
private final String name;
private Ability soundAbility;
private Ability animationAbility;
private Ability customMessageAbility;
private String technology;
public CardBuilder(String name)
{
this.name = name;
}
public CardBuilder soundAbility(Ability soundAbility)
{
this.soundAbility = soundAbility;
return this;
}
public CardBuilder animationAbility(Ability animationAbility)
{
this.animationAbility = animationAbility;
return this;
}
public CardBuilder customMessageAbility(Ability customMessageAbility)
{
this.customMessageAbility = customMessageAbility;
return this;
}
public CardBuilder technology(String technology)
{
this.technology = technology;
return this;
}
public Card build()
{
return new Card(this);
}
}
}
Then to run the program:
package builderTest;
class BuilderMain
{
public static void main(String[] args)
{
// Initialize ability objects.
Ability a1 = new SoundAbility();
Ability a2 = new AnimationAbility();
Ability a3 = new CustomMessageAbility();
// Build card
Card card = new Card.CardBuilder("Birthday Card")
.soundAbility(a1)
.animationAbility(a2)
.customMessageAbility(a3)
.technology("Flash")
.build();
System.out.println(card);
}
}
The output would be something along the lines of:
Birthday Card:
I have the ability of sound!
I have the ability of animation!
I have the ability of customizing messages!
I have the ability of Flash!
Keep in mind that I'm working without much context, so what you need might be significantly different.
Although previous answers are very good, there is still another way of achieve this Object creation
with very many optional fields
I found myself in similar situation when dealing with DB complexity and Command design pattern. As you know some table columns values are mandatory - some are not. I'm using this Effective Java book
for such cases.
So, useful here is the Consider a builder when faced with many constructor parameters. By doing so, you avoid
first, the Telescoping constructor pattern (does not scale well) - it works, but it is hard to write client code when there are many parameters, and harder still to read it.
second, the JavaBeans Pattern, which is good, but allows inconsistency and mandates mutability. It may be in an inconsistent state partway through its construction and precludes the possibility of making a class immutable too.
The Builder pattern as used simulates named optional parameters as found in Ada and Python.Like a constructor, a builder can impose invariants on its parameters. But it is critical that they be checked after copying the parameters from the builder to the object, and that they be checked on
the object fields rather than the builder fields.
Cheers.
As input I have a list of Books. As output I expect a SimilarBookCollection.
A SimilarBookCollection has an author, publishYear and list of Books. The SimilarBookCollection can't be created if the author of the books is different or if the publishYear is different.
The solution so far in PHP:
client.php
----
$arrBook = array(...); // array of books
$objValidator = new SimilarBookCollectionValidator($arrBook);
if ($objValidator->IsValid()) {
$objSimilarBookCollection = new SimilarBookCollection($arrBook);
echo $objSimilarBookCollection->GetAuthor();
}
else {
echo 'Invalid input';
}
SimilarBookCollection.php
---
class SimilarBookCollection() {
public function SimilarBookCollection(array $arrBook) {
$objValidator = new SimilarBookCollectionValidator($arrBook);
if ($objValidator->IsValid()) {
throw new Exception('Invalid books to create collection');
}
$this->author = $arrBook[0]->GetAuthor();
$this->publishYear = $arrBook[0]->GetPublishYear();
$this->books = $arrBook;
}
public function GetAuthor() {
return $this->author;
}
public function GetPublishYear() {
return $this->publishYear;
}
public function GetBooks() {
return $this->books;
}
}
SimilarBookCollectionValidator.php
---
class SimilarBookCollectionValidator() {
public function IsValid() {
$this->ValidateAtLeastOneBook();
$this->ValidateSameAuthor();
$this->ValidateSameYear();
return $this->blnValid;
}
... //actual validation routines
}
The goal is to have a "special" collection with only books that have the same author and publishYear. The idea is to easily access the repeating information like author or year from the object.
How would you name the SimilarBookCollection? The current name is to
generic. Using a name like SameYearAuthorBookCollection looks a bit
long and strange(if more conditions will be added then name will increase)
Would you use a Validator in SimilarBookCollection constructor using a
defensive programming style?
Would you change the design of the code? If yes how?
It all depends ;)
So if I were to aim for a generic adaptable solution I would do the following:
Validator in constructor
On one hand you are validating twice; that is informative in case of a broken precondition/contract (not giving a valid list), but is double the code to run - for what purpose exactly?
If you want to use this in a system depends on its size, how critical it is, product phase, and likely more criterias.
But then it also is controller logic fitted into a model meaning you are spreading your code around.
I would not put it in the constructor.
Name / Design
I would say keep the BookCollection generic as it is, and have any validation strictly in the controller space, instead of bloating the collection which essentially seems to be an array with the extra field of author.
If you want to differentiate between different collection types use either (multiple) inheritance or some sort of additional field "collectionType"; the former if you expect many derivatives or varying functionality to come (also keeps the logic where different nicely separated).
You could also consider your collection as a set on which you perform queries and for convenience's sake you could maintain some sort of meta data like $AuthorCount = N, $publicationDates = array(...) from which you can quickly derive the collection's nature. This approach would also keep your validator-code minimal (or non-existent), as it'd be implicitly in the collection and you could just do the validation in the controller keeping the effective logic behind it clearly visible.
That would also make it more comfortable for you in the future. But the question really is what you want and need it for, and what changes you expect, because you are supposed to fit your design to your requirements and likely changes.
For your very particular problem the constraints as I understand are as follows:
There is only one collection type class in the system at any given
point in time.
The class's items have several attributes, and for a particular, possibly changing subset of these (called identical attributes), the collection only accepts item lists where the chosen attributes of all items are identical.
The class provides getters for all identical attributes
The class must not be usable in any other way than the intended way.
If not for point 1 I would use a generic base class that is either parametrized (ie you tell it upon instantiation which is the set of identical attributes) or uses multiple inheritance (or in php traits) to compose arbitrary combinations with the needed interfaces. Children might rely on the base class but use a predefined subset of the identical attributes.
The parametrized variant might look something as follows:
class BookCollection {
public function __construct($book_list, $identical_fields=array())
{
if (empty($book_list))
{
throw new EmptyCollectionException("Empty book list");
}
$default = $book_list[0];
$this->ia = array();
foreach($identical_fields as $f)
{
$this->ia[$f] = $default->$f;
}
foreach($book_list as $book)
{
foreach($identical_fields as $f)
{
if ($this->ia[$f] !== $book->$f)
{
throw new NotIdenticalFieldException("Field $f is not identical for all");
}
}
}
$this->book_list = $book_list;
}
public function getIdentical($key)
{
$this->ia[$key];
}
}
final class BC_by_Author extends BookCollection{
public function __construct($book_list)
{
parent::__construct($book_list,array('author'));
}
public function getAuthor(){ $this->ia['author']; }
}
or fooling around with abstract and final types (not sure if it's valid like this)
abstract class BookCollection{
public final function __construct($book_list){...}
abstract public function getIdenticalAttributes();
}
final class BC_by_Author {
public function getIdenticalAttributes(){ return array('author'); }
public function getAuthor(){ return $this->ia['author']; }
}
If you rely on getters that do not necessarily match the field names I would go for multiple inheritance/traits.
The naming then would be something like BC_Field1Field2Field3.
Alternatively or additionally, you could also use exactly the same classname but develop your solutions in different namespaces, which would mean you wouldn't have to change your code when you change the namespace, plus you can keep it short in the controllers.
But because there will only ever be one class, I would name it BookCollection and not unnecessarily discuss it any further.
Because of constraint 4, the white box constraint, the given book list must be validated by the class itself, ie in the constructor.
I'm trying to follow the Law Of Demeter ( see http://en.wikipedia.org/wiki/Law_of_Demeter , http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/ ) as I can see the benefits, however I've become a little stuck when it comes to domain objects.
Domain objects do naturally have a chain and sometimes it's necessary to display the information about the entire chain.
For instance, a shopping basket:
Each order contains a user, delivery info and a list of items
Each order item contains a product and quantity
Each product has a name and price.
Each user contains a name and address
The code which displays the order information has to use all the information about the order, users and products.
Surely it's better and more reusable to get this information through the order object e.g. "order.user.address.city" than for some code higher up to do queries for all the objects I listed above then pass them into the code separately?
Any comments/suggestions/tips are welcome!
One problem with using chained references, such as order.user.address.city, is that higher-order dependencies get "baked into" the structure of code outside the class.
Ideally, in cases when you refactor your class, your "forced changes" should be limited to the methods of the class being refactored. When you have multiple chained references in the client code, refactoring drives you to make changes in other places of your code.
Consider an example: suppose that you'd like to replace User with an OrderPlacingParty, an abstraction encapsulating users, companies, and electronic agents that can place an order. This refactoring immediately presents multiple problems:
The User property will be called something else, and it will have a different type
The new property may not have an address that has city in cases when the order is placed by an electronic agent
The human User associated with the order (suppose that your system needs one for legal reasons) may be related to the order indirectly, - for example, by being a designated go-to person in the definition of the OrderPlacingParty.
A solution to these problems would be to pass the order presentation logic everything that it needs directly, rather than having it "understand" the structure of the objects passed in. This way you would be able to localize the changes to the code being refactored, without spreading the changes to other code that is potentially stable.
interface OrderPresenter {
void present(Order order, User user, Address address);
}
interface Address {
...
}
class PhysicalAddress implements Address {
public String getStreetNumber();
public String getCity();
public String getState();
public String getCountry();
}
class ElectronicAddress implements Address {
public URL getUrl();
}
interface OrderPlacingParty {
Address getAddress();
}
interface Order {
OrderPlacingParty getParty();
}
class User implements OrderPlacingParty {
}
class Company implements OrderPlacingParty {
public User getResponsibleUser();
}
class ElectronicAgent implements OrderPlacingParty {
public User getResponsibleUser();
}
I think, when chaining is used to access some property, it is done in two (or at least two) different situation. One is the case that you have mentioned, for example, in your presentation module, you have an Order object and you would like to just display the owner's/user's address, or details like city. In that case, I think it is of not much problem if you do so. Why? Because you are not performing any business logic on the accessed property, which can (potentially) cause tight coupling.
But, things are different if you use such chaining for the purpose of performing some logic on the accessed property. For example, if you have,
String city = order.user.address.city;
...
order.user.address.city = "New York";
This is problematic. Because, this logic is/should more appropriately be performed in a module closer to the target attribute - city. Like, in a place where the Address object is constructed in the first place, or if not that, at least when the User object is constructed (if say User is the entity and address the value type). But, if it goes farther than that, the farther it goes, the more illogical and problematic it becomes. Because there are too many intermediaries are involved between the source and the target.
Thus, according to the the Law of Demeter, if you are performing some logic on the "city" attribute in a class, say OrderAssmebler, which accesses the city attribute in a chain like order.user.address.city, then you should think of moving this logic to a place/module closer to the target.
You're correct and you'll most likely model your value objects something like this
class Order {
User user;
}
class User {
Address shippingAddress;
Address deliveryAddress;
}
class Address {
String city;
...
}
When you start considering how you will persist this data to a database (e.g. ORM) do you start thinking about performance. Think eager vs lazy loading trade offs.
Generally speaking I adhere to the Law of Demeter since it helps to keep changes in a reduced scope, so that a new requirement or a bug fix doesn't spread all over your system. There are other design guidelines that help in this direction, e.g. the ones listed in this article. Having said that, I consider the Law of Demeter (as well as Design Patterns and other similar stuff) as helpful design guidelines that have their trade-offs and that you can break them if you judge it is ok to do so. For example I generally don't test private methods, mainly because it creates fragile tests. However, in some very particular cases I did test an object private method because I considered it to be very important in my app, knowing that that particular test will be subject to changes if the implementation of the object changed. Of course in those cases you have to be extra careful and leave more documentation for other developers explaining why you are doing that. But, in the end, you have to use your good judgement :).
Now, back to the original question. As far as I understand your problem here is writing the (web?) GUI for an object that is the root of a graph of objects that can be accessed through message chains. For that case I would modularize the GUI in a similar way that you created your model, by assigning a view component for each object of your model. As a result you would have classes like OrderView, AddressView, etc that know how to create the HTML for their respective models. You can then compose those views to create your final layout, either by delegating the responsibility to them (e.g. the OrderView creates the AddressView) or by having a Mediator that takes care of composing them and linking them to your model. As an example of the first approach you could have something like this (I'll use PHP for the example, I don't know which language you are using):
class ShoppingBasket
{
protected $orders;
protected $id;
public function getOrders(){...}
public function getId(){...}
}
class Order
{
protected $user;
public function getUser(){...}
}
class User
{
protected $address;
public function getAddress(){...}
}
and then the views:
class ShoppingBasketView
{
protected $basket;
protected $orderViews;
public function __construct($basket)
{
$this->basket = $basket;
$this->orederViews = array();
foreach ($basket->getOrders() as $order)
{
$this->orederViews[] = new OrderView($order);
}
}
public function render()
{
$contents = $this->renderBasketDetails();
$contents .= $this->renderOrders();
return $contents;
}
protected function renderBasketDetails()
{
//Return the HTML representing the basket details
return '<H1>Shopping basket (id=' . $this->basket->getId() .')</H1>';
}
protected function renderOrders()
{
$contents = '<div id="orders">';
foreach ($this->orderViews as $orderView)
{
$contents .= orderViews->render();
}
$contents .= '</div>';
return $contents;
}
}
class OrderView
{
//The same basic pattern; store your domain model object
//and create the related sub-views
public function render()
{
$contents = $this->renderOrderDetails();
$contents .= $this->renderSubViews();
return $contents;
}
protected function renderOrderDetails()
{
//Return the HTML representing the order details
}
protected function renderOrders()
{
//Return the HTML representing the subviews by
//forwarding the render() message
}
}
and in your view.php you would do something like:
$basket = //Get the basket based on the session credentials
$view = new ShoppingBasketView($basket);
echo $view->render();
This approach is based on a component model, where the views are treated as composable components. In this schema you respect the object's boundaries and each view has a single responsibility.
Edit (Added based on the OP comment)
I'll assume that there is no way of organizing the views in subviews and that you need to render the basket id, order date and user name in a single line. As I said in the comment, for that case I would make sure that the "bad" access is performed in a single, well documented place, leaving the view unaware of this.
class MixedView
{
protected $basketId;
protected $orderDate;
protected $userName;
public function __construct($basketId, $orderDate, $userName)
{
//Set internal state
}
public function render()
{
return '<H2>' . $this->userName . "'s basket (" . $this->basketId . ")<H2> " .
'<p>Last order placed on: ' . $this->orderDate. '</p>';
}
}
class ViewBuilder
{
protected $basket;
public function __construct($basket)
{
$this->basket = $basket;
}
public function getView()
{
$basketId = $this->basket->getID();
$orderDate = $this->basket->getLastOrder()->getDate();
$userName = $this->basket->getUser()->getName();
return new MixedView($basketId, $orderDate, $userName);
}
}
If later on you rearrange your domain model and your ShoppingBasket class can't implement the getUser() message anymore then you will have to change a single point in your application, avoid having that change spread all over your system.
HTH
The Law Of Demeter is about calling methods, not accessing properties/fields. I know technically properties are methods, but logically they're meant to be data. So, your example of order.user.address.city seems fine to me.
This article is interesting further reading: http://haacked.com/archive/2009/07/13/law-of-demeter-dot-counting.aspx
I am new to OOP. Though I understand what polymorphism is, but I can't get the real use of it. I can have functions with different name. Why should I try to implement polymorphism in my application.
Classic answer: Imagine a base class Shape. It exposes a GetArea method. Imagine a Square class and a Rectangle class, and a Circle class. Instead of creating separate GetSquareArea, GetRectangleArea and GetCircleArea methods, you get to implement just one method in each of the derived classes. You don't have to know which exact subclass of Shape you use, you just call GetArea and you get your result, independent of which concrete type is it.
Have a look at this code:
#include <iostream>
using namespace std;
class Shape
{
public:
virtual float GetArea() = 0;
};
class Rectangle : public Shape
{
public:
Rectangle(float a) { this->a = a; }
float GetArea() { return a * a; }
private:
float a;
};
class Circle : public Shape
{
public:
Circle(float r) { this->r = r; }
float GetArea() { return 3.14f * r * r; }
private:
float r;
};
int main()
{
Shape *a = new Circle(1.0f);
Shape *b = new Rectangle(1.0f);
cout << a->GetArea() << endl;
cout << b->GetArea() << endl;
}
An important thing to notice here is - you don't have to know the exact type of the class you're using, just the base type, and you will get the right result. This is very useful in more complex systems as well.
Have fun learning!
Have you ever added two integers with +, and then later added an integer to a floating-point number with +?
Have you ever logged x.toString() to help you debug something?
I think you probably already appreciate polymorphism, just without knowing the name.
In a strictly typed language, polymorphism is important in order to have a list/collection/array of objects of different types. This is because lists/arrays are themselves typed to contain only objects of the correct type.
Imagine for example we have the following:
// the following is pseudocode M'kay:
class apple;
class banana;
class kitchenKnife;
apple foo;
banana bar;
kitchenKnife bat;
apple *shoppingList = [foo, bar, bat]; // this is illegal because bar and bat is
// not of type apple.
To solve this:
class groceries;
class apple inherits groceries;
class banana inherits groceries;
class kitchenKnife inherits groceries;
apple foo;
banana bar;
kitchenKnife bat;
groceries *shoppingList = [foo, bar, bat]; // this is OK
Also it makes processing the list of items more straightforward. Say for example all groceries implements the method price(), processing this is easy:
int total = 0;
foreach (item in shoppingList) {
total += item.price();
}
These two features are the core of what polymorphism does.
Advantage of polymorphism is client code doesn't need to care about the actual implementation of a method.
Take look at the following example.
Here CarBuilder doesn't know anything about ProduceCar().Once it is given a list of cars (CarsToProduceList) it will produce all the necessary cars accordingly.
class CarBase
{
public virtual void ProduceCar()
{
Console.WriteLine("don't know how to produce");
}
}
class CarToyota : CarBase
{
public override void ProduceCar()
{
Console.WriteLine("Producing Toyota Car ");
}
}
class CarBmw : CarBase
{
public override void ProduceCar()
{
Console.WriteLine("Producing Bmw Car");
}
}
class CarUnknown : CarBase { }
class CarBuilder
{
public List<CarBase> CarsToProduceList { get; set; }
public void ProduceCars()
{
if (null != CarsToProduceList)
{
foreach (CarBase car in CarsToProduceList)
{
car.ProduceCar();// doesn't know how to produce
}
}
}
}
class Program
{
static void Main(string[] args)
{
CarBuilder carbuilder = new CarBuilder();
carbuilder.CarsToProduceList = new List<CarBase>() { new CarBmw(), new CarToyota(), new CarUnknown() };
carbuilder.ProduceCars();
}
}
Polymorphism is the foundation of Object Oriented Programming. It means that one object can be have as another project. So how does on object can become other, its possible through following
Inheritance
Overriding/Implementing parent Class behavior
Runtime Object binding
One of the main advantage of it is switch implementations. Lets say you are coding an application which needs to talk to a database. And you happen to define a class which does this database operation for you and its expected to do certain operations such as Add, Delete, Modify. You know that database can be implemented in many ways, it could be talking to file system or a RDBM server such as MySQL etc. So you as programmer, would define an interface that you could use, such as...
public interface DBOperation {
public void addEmployee(Employee newEmployee);
public void modifyEmployee(int id, Employee newInfo);
public void deleteEmployee(int id);
}
Now you may have multiple implementations, lets say we have one for RDBMS and other for direct file-system
public class DBOperation_RDBMS implements DBOperation
// implements DBOperation above stating that you intend to implement all
// methods in DBOperation
public void addEmployee(Employee newEmployee) {
// here I would get JDBC (Java's Interface to RDBMS) handle
// add an entry into database table.
}
public void modifyEmployee(int id, Employee newInfo) {
// here I use JDBC handle to modify employee, and id to index to employee
}
public void deleteEmployee(int id) {
// here I would use JDBC handle to delete an entry
}
}
Lets have File System database implementation
public class DBOperation_FileSystem implements DBOperation
public void addEmployee(Employee newEmployee) {
// here I would Create a file and add a Employee record in to it
}
public void modifyEmployee(int id, Employee newInfo) {
// here I would open file, search for record and change values
}
public void deleteEmployee(int id) {
// here I search entry by id, and delete the record
}
}
Lets see how main can switch between the two
public class Main {
public static void main(String[] args) throws Exception {
Employee emp = new Employee();
... set employee information
DBOperation dboper = null;
// declare your db operation object, not there is no instance
// associated with it
if(args[0].equals("use_rdbms")) {
dboper = new DBOperation_RDBMS();
// here conditionally, i.e when first argument to program is
// use_rdbms, we instantiate RDBM implementation and associate
// with variable dboper, which delcared as DBOperation.
// this is where runtime binding of polymorphism kicks in
// JVM is allowing this assignment because DBOperation_RDBMS
// has a "is a" relationship with DBOperation.
} else if(args[0].equals("use_fs")) {
dboper = new DBOperation_FileSystem();
// similarly here conditionally we assign a different instance.
} else {
throw new RuntimeException("Dont know which implemnation to use");
}
dboper.addEmployee(emp);
// now dboper is refering to one of the implementation
// based on the if conditions above
// by this point JVM knows dboper variable is associated with
// 'a' implemenation, and it will call appropriate method
}
}
You can use polymorphism concept in many places, one praticle example would be: lets you are writing image decorer, and you need to support the whole bunch of images such as jpg, tif, png etc. So your application will define an interface and work on it directly. And you would have some runtime binding of various implementations for each of jpg, tif, pgn etc.
One other important use is, if you are using java, most of the time you would work on List interface, so that you can use ArrayList today or some other interface as your application grows or its needs change.
Polymorphism allows you to write code that uses objects. You can then later create new classes that your existing code can use with no modification.
For example, suppose you have a function Lib2Groc(vehicle) that directs a vehicle from the library to the grocery store. It needs to tell vehicles to turn left, so it can call TurnLeft() on the vehicle object among other things. Then if someone later invents a new vehicle, like a hovercraft, it can be used by Lib2Groc with no modification.
I guess sometimes objects are dynamically called. You are not sure whether the object would be a triangle, square etc in a classic shape poly. example.
So, to leave all such things behind, we just call the function of derived class and assume the one of the dynamic class will be called.
You wouldn't care if its a sqaure, triangle or rectangle. You just care about the area. Hence the getArea method will be called depending upon the dynamic object passed.
One of the most significant benefit that you get from polymorphic operations is ability to expand.
You can use same operations and not changing existing interfaces and implementations only because you faced necessity for some new stuff.
All that we want from polymorphism - is simplify our design decision and make our design more extensible and elegant.
You should also draw attention to Open-Closed Principle (http://en.wikipedia.org/wiki/Open/closed_principle) and for SOLID (http://en.wikipedia.org/wiki/Solid_%28Object_Oriented_Design%29) that can help you to understand key OO principles.
P.S. I think you are talking about "Dynamic polymorphism" (http://en.wikipedia.org/wiki/Dynamic_polymorphism), because there are such thing like "Static polymorphism" (http://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism).
You don't need polymorphism.
Until you do.
Then its friggen awesome.
Simple answer that you'll deal with lots of times:
Somebody needs to go through a collection of stuff. Let's say they ask for a collection of type MySpecializedCollectionOfAwesome. But you've been dealing with your instances of Awesome as List. So, now, you're going to have to create an instance of MSCOA and fill it with every instance of Awesome you have in your List<T>. Big pain in the butt, right?
Well, if they asked for an IEnumerable<Awesome>, you could hand them one of MANY collections of Awesome. You could hand them an array (Awesome[]) or a List (List<Awesome>) or an observable collection of Awesome or ANYTHING ELSE you keep your Awesome in that implements IEnumerable<T>.
The power of polymorphism lets you be type safe, yet be flexible enough that you can use an instance many many different ways without creating tons of code that specifically handles this type or that type.
Tabbed Applications
A good application to me is generic buttons (for all tabs) within a tabbed-application - even the browser we are using it is implementing Polymorphism as it doesn't know the tab we are using at the compile-time (within the code in other words). Its always determined at the Run-time (right now! when we are using the browser.)