Showing posts with label GOF Patterns. Show all posts
Showing posts with label GOF Patterns. Show all posts

Friday, August 4, 2017

Friday Challenge #5: Fixed Gear or 3-speed?

When I first encountered an OO language (Java) there was a tutorial that used bicycles to explain polymorphism. All bikes have some behaviors in common - you pedal them to move forward, you turn one of the two wheels using the handlebars to steer. While there are exceptions - pedal-less bikes for kids, sit down bikes with levers to steer, pedal assist (actually a moped) - the common case serves as great fodder for object oriented programming. With that, let's start the next challenge!

You don't have to use Java to take on this challenge, there are many many object oriented languages and many that have support for classes. Use whatever you would like to use - learn a new lang maybe!


Given the following types of bikes:

3-speed cruiser, id=1, type=MultiSpeedBicycle
10-speed mountain bike, id=2, type=MultiSpeedBicycle
BMX - fixed gear, id=3, type=SingleSpeedBicycle


Write a method that takes in a bike id and returns the bike. The method signature should have the base/parent type as the return type.


Bicycle getBicycle(int id);

Bicycle is an abstract type.

You can either make a static method on Bicycle if your language allows it, or make a BicycleFactory to house the method.


The basic bike (the abstract Bicycle type) has 3 methods - pedal(int pressure), applyBrakes(int pressure), steer(float angle).


A bike with gears EXTENDEDS the basic bike with two additional methods: shiftUp(), shiftDown().

*If you'd like, you can add some additional methods like getCurrentGear(), getMaxGear()...or you could return a bool from shiftUp and shiftDown to say if it changed or not...or return the resultant gear of the action. The more the internals of the object are protected the better, the consumer should not know what gear the bike is in, only that they can shift gears up or down.

Whatever you use to call getBicycle will eventually want to check what type that bicycle is...as far as it knows it only has the basic bicycle methods. Until it does know, shifting isn't an option.

Let's say we have a UI for this bicycle. Actually we would want a different UI for each type since users will interact differently with each type. The shiftable bicycles will have some way to shift gears in the UI - maybe a certain keypress or tapping the screen a certain way...how about pressing shift levers?


Fetch the proper UI for the type inside a method that has this signature...

BikeView getView(Bicycle bike); 


Inside that method, interrogate the type of bicycle and return the view for that type. Put that method into a BicycleViewFactory - do you think the constructor for it takes in all the views or maybe something that knows how to load all the views? Just stub out something for now - create the various view classes and have the method return the right one for the type of bicycle. Maybe you really only need two types of bicycles, maybe you want three - that's entirely up to you and far you want to go with the details.


So that's the challenge...write up those classes and put it altogether with some way to exercise (pun intended) the methods and verify that the right View is returned in the end. The View doesn't actually need to have anything in it, neither do the methods on Bicycle...stubs will work just fine. The lesson here is in how getBicycle and getView are implemented.


Oh! I almost forgot! There's one more thing you can do - you'll want something to load the bike and return the proper views...a BicycleController! First it needs to load up an input view to receive the bike id (maybe list them all - listBicycles() and have the user select one if you'd like). Once an id is sent to getBicycle, that method should call your _bicycleFactory.getBicycle() method to load up the bike. Pass that instance to the ViewFactory to get the view...if you got back a BicycleView return it to the user - else maybe return an ErrorView...the BicycleController should take in both the BicycleFactory and the BicycleViewFactory and hold internal references to those...they should both be set up and ready to use before they are passed into the controller.

Feel free to implement the UI in any way you see fit - heck try going for multiple UIs! Everything should be re-usable at this point...the only things that should change based on the UI you want to implement are the Views!

Let's take that a bit further... Consider different UIs. Maybe the user has certain preferences. Or maybe it's a different view per screen type. Perhaps there's a VR view with actual pedals and steering wheel as input...a stationary bike! Got it!? Those would have different Views for different user interfaces.

Alright, have fun! Happy Coding!

This challenge is all about polymorphism, factory pattern, MVC pattern, encapsulation, Dependency Injection.







Tuesday, January 5, 2016

Abtracting Service Calls Using the Adapter Pattern

Consider the following scenario:

Given an environment which contains the following:

UserResource - a service which allows clients to lookup users and user information.
AdminResource - a service which allows clients to lookup admin details.
TaskApplication - an application which consumes the UserResource.
DocumentApplication - an application which consumes the UserResource.
AdminApplication - an application which consumes the UserResource and AdminResource.

And each of these applications have variances in their domain specific usage of the data provided by the UserResource.

When the applications are developed
Then you may want to build domain specific classes to represent the data you are using in each application.


For Example:

Suppose the AdminApplication needs to make a distinction between SystemAdminUser and User such that it would be appropriate to create a subtype of User for the SystemAdminUser (with additional detail) which the UserResource does not provide, the additional data would come from the AdminResource.

It may be better to create a new type rather than a subtype, I'll get into why in a bit. For now let's create a subtype from the UserResource like so...


namespace AdminApplication.Objects
{
    public class SystemAdminUser : User
    {
        public int[] SystemIds { get; set; }
    }
}
.
.
.
namespace AdminApplication.Adapters
{
    public interface ISystemUserResource
    {
        SystemAdminUser GetSystemAdminUser(int id);
    }

    public class SystemUserResource : ISystemUserResource
    {
        IUserResource _userResource;
        IAdminResource _adminResource;
        public SystemUserResource(IUserResource userResource, IAdminResource adminResource)
        {
            _userResource = userResource;
            _adminResource = adminResource;
        }

        public SystemAdminUser GetSystemAdminUser(int id)
        {
             var user = _userResource.GetUser(id);
             var admin = _adminResource.GetSystemAdmin(id);
             return Mapper.MergeMap(user, admin);
        }
    }
}

And when this adapter is consumes in the application, the application code no longer will need to have the dependency on the IUserResource and IAdminResource interfaces (assume this example uses DI/IoC to inject the concrete classes) but only on the one ISystemUserResource interface. There is an added benefit to the simplicity and reuse that will make the rest of the application code flow more naturally.

However, we do have a deeper issue with this choice. To illustrate, note the following consumer of ISystemUserResource:



using AdminApplication.Adapters;
using AdminApplication.Objects;
using UserResource.Proxies;

namespace AdminApplication.Web
{
    public class HomeController
    {
        ...
    }
    ...
}

See how we have the dependency on the UserResource library due to the class being derived from one of its types? This dependency will bleed all over the application code, the test code, etc. Additionally, we may also be passing quite a bit of information around the application that we do not need by way of properties on the User instances. Additionally, though not likely in this specific scenario, there may be differences in terminology in different domains for the same thing. It would be confusing to have an EmployeeId when in the context it is always referred to as the UserId.

In order to minimize the bleeding of dependencies through consumer code, it would serve well to abstract the services behind a domain specific adapter using an Adapter pattern, Façade pattern, or a combination of both.




namespace AdminApplication.Objects
{
    public class SystemAdminUser
    {
        public int UserId { get; set; }
        public string UserName{ get; set; }
        public int[] SystemIds { get; set; }
    }
}
.
.
.
namespace AdminApplication.Adapters
{
    public interface ISystemUserResource
    {
        SystemAdminUser GetSystemAdminUser(int id);
    }

    public class SystemUserResource : ISystemUserResource
    {
        IUserResource _userResource;
        IAdminResource _adminResource;
        public SystemUserResource(IUserResource userResource, IAdminResource adminResource)
        {
            _userResource = userResource;
            _adminResource = adminResource;
        }

        public SystemAdminUser GetSystemAdminUser(int id)
        {
             var user = _userResource.GetUser(id);
             var admin = _adminResource.GetSystemAdmin(id);
             return Mapper.MergeMap(user, admin);
        }
    }
}


There will be a slight increase in code complexity at first. But the long-term benefits of being able to upgrade services without much change, testability, and the reduction of the reference bleeding will be a future asset worth investing in.