Functional approach to a shopping basket - functional-programming

I was reading http://www.infoq.com/interviews/trelford-functional and trying to understand the alternative approach to OO.
Q I see you’re doing a talk here at GOTOCon on functional
architecture, what is that? I thought all architectures were object
oriented?
A Well, they’re not; I wanted to highlight the idea that your choice
of language and platform does affect your architecture in the way you
think; how picking a functional language or architecture can really
benefit the system.
If I just take a simple example say we write a retail application, if
you think just about objects and mutation, then you would think when
you’re constructing a basket of items, as you add an item you'd
increase the quantity and if somebody returns an item or cancels an
item, you'd decrease the quantity, you’d be doing it wrong.
With retail system, you need to track what’s actually been done so you
can detect fraud, it’s one of the key elements of the system; so you
actually add new values each this time, you never mutate.
So just from one of the most basic systems that we interact with
everyday, functional immutable style is actually close to the
architecture you want.
If you were to adopt a more functional style wrt a shopping basket app, how would you be thinking about the problem? eg Would you still have a shopping basket object and rather than mutate its contents you'd create a new one or something?
Many thx

It would be a container data structure who's invariants modelled those of a basket (e.g. a bag -like data type). The container would be persistent, so you could transparently roll back to older versions (to allow the user to undo actions, or save for a later visit).
By not destructively updating the basket, you get rollback, undo and persistence for free.
By using a richer data type, there is less book keeping to do, and thus less chance of bugs.

Related

Is this a bad DynamoDB database schema?

After a watching a few videos regarding DynamoDB and its best practices, I decided to give it a try; however, I cannot help but feel what I'm doing may be an anti-pattern. As I understand it, the best practice is to leverage as few tables as possible while also taking advantage of GSIs to do some 'heavy' lifting. Unfortunately, I'm working with a use case that doesn't actually have strictly defined access patterns yet since we're still in early development.
Some early access patterns that we may see are:
Retrieve the number of wins for a particular game: rock paper scissors, boxing, etc. [1 quick lookup]
Retrieve the amount of coins a user has. [1 quick lookup]
Retrieve all the items that someone has purchased (don't care about date). [Not sure?]
Possibly retrieve all the attributes associated with a user (rps wins, box wins, coins, etc). [I genuinely don't know.]
Additionally, there may be 2 operations we will need to complete. For example, if the user wins a particular game they may receive "coins". Effectively, we'll need to add coins to the user "coins" attribute & update their number of wins for the game.
Do you think I should revisit this strategy? Additionally, we'll probably start creating 'logs' associated with various games and each individual play.
Designing a DynamoDB data model without fully understanding your applications access patterns is the anti-pattern.
Take the time to define your entities (Users, Games, Orders, etc), their relationship to one another and your applications key access patterns. This can be hard work when you are just getting started, but it's absolutely critical to do this when working with DynamoDB. How else can we (or you, or anybody) evaluate whether or not you're using DDB correctly?
When I first worked with DDB, I approached the process in a similar way you are describing. I was used to working with SQL databases, where I could define a few tables and rely on the magic of SQL to support my access patterns as my understanding of the application access patterns evolved. I quickly realized this was not going to work if I wanted to use DynamoDB!
Instead, I started from the front-end of my application. I sketched out the different pages in my app and nailed down the most important concepts in my application. Granted, I may not have covered all the access patterns in my application, but the exercise certainly nailed down the minimal access patterns I'd need to have a usable app.
If you need to rapidly prototype your application to get a better understanding of your acecss patterns, consider using the skills you and your team already have. If you already understand data modeling with SQL databses, go with that for now. You can always revisit DynamoDB once you have a better understanding of your access patterns and determine that your application can benefit from using a NoSQL databse.

Ideas to keep user stories small

There seems to competing best practices for user stories that I have not been able to come up with a way to deal with. Mainly:
Keep user stories small.
User stories should deliver customer values and therefore engineering focused item such as refactoring should not be separate user story and should be part of on-going work.
I feel like it's hard to achieve both of these at the same time.
For example, sometimes you need to refactor things. Some code is complex and just takes time. If it's done as part of the feature user story, then that user story will get bigger. But the refactor should not be a user story since it doesn't deliver customer values. You could argue that maybe we shouldn't let the code got checked-in in the first place, but requirement changes and therefore assumption changes so I don't think that's realistic expectation.
Another example could be dealing with starting a new project; we need to setup the repository, the project, the CI/CD pipelines. All of these are infrastructure work items and does not deliver any direct customer values. I guess in this case, we could use "engineer" as the customer but there are some debate out there whether that's a good practice or not.
Now I could bend the rule and have these as user stories. But I am curious if people are following the scrum rule strictly, is there tips and tricks to achieve both of these requirements?
Scrum does not prescribe any format for the Product Backlog items. So your Product Backlog can contain user stories but also any other kind of items.
As you are saying user stories should deliver value, typically meeting the INVEST acronym but your Product Backlog can contain items related to make functionality possible, such as upgrading libraries, implementing a log system or whatever help the team to potentially release the product. Taking into account that in your Product Backlog there will be bugs too, so it´s not just about new functionalities. So don´t fool yourself making up users who don´t exist.
Being saying that, usually a big refactor is a smell of a problem not tackled at the proper time (generating a high technical debt, a weak DoD and so on). That´s the reason many authors say that you should refactor at the same time your are developing new functionalities (your code should be in good form).
Finally, if you are in such a scenario that you need a big refactor, my advice is to try to decompose the refactor in small pieces and create a good harness of test to refactor with confidence.
I can think of several ways you can cut stories. However, keep in mind that these are ideas that can work but can also make no sense depending on the work. I only want to share my experience.
think about the three basic areas: User Interface, Data Calculation, Data Retrieval, try to cut the story along these lines
if you have to do repetitions, create a story for each iteration
try to do the first implementation as basic as possible, then create more stories for upgrading and fine tuning
even if a story seems to be straightforward, try to cut it; it is amazing how much better you can discuss as a team about smaller items and how much better you can refine it, and you it forces you to think about the details and this really can make a difference

Calculating ratings/points in a community driven site

To learn ASP.NET MVC, I am thinking of creating a community forum like SO where people can rate posts, users etc. and the user can thereby gain points. I just can't figure out if the points should be added to the user profile whenever an action is done (post rated up/down, user created new post etc.) or if it should be calculated from the different activities the user has done.
I have a few pro's and con's for both ways of doing it:
Add rating:
Pro:
Easier to implement, and much faster and less resource intensive.
Con:
If the value of the different activities change, you can't do anything about it.
No way of showing a history on how you have gotten your points.
Calculating rating:
Pro:
Much easier to have a point-history for both the user and people viewing the account.
Possibility to change the amount of points for a given activity.
Con:
A little more difficult to implement.
More resource extensive (can be prevented by caching the data, or creating a job which calculates the points).
I think you've pretty much thought of everything. I can just offer some engineering tips. All things equal, always start of with what's easier to implement.
Now there are some cons with that as you say, so they're not equal, they don't offer the same functionality. So can you live without the history? If not, implement calculating first. Your model will be tight and well defined, which is always nice.
IF you determine later on that this is too cpu intensive, only then do you go about fixing it with a cache or a job. Good ideas, both, btw. 90% of the time, unless you really measure it, you'll be laboring on optimizations that are not necessary. Unnecessary optimizations are wrong.
It looks like you are trying to build something like stackoverflow, and Stackoverflow does have a history where your points came from. When you will use linq, the calculation method could be done purely in SQL, without a lot of effort on programming skills. (although it'd be a bit more advanced than the normal linq querys)
I'd go for the second option, merely because it's more interesting, you'll learn more about linq, caching, and MVC overall.
You can use ActionFilter classs to catch every action that adds/deletes user points. Like AuditActionFilter class. This can be done just by putting action filter attribute on top of corresponding methods. In the audit action filter class, you can figure out which method is executed easility using filterContext object and track the progress of points for each user in a flat file or xml, which you can show/parse when he wants to see his history.

Domain Object in Views

We've been having a discussion at work about whether to use Domain Objects in our views (asp.net mvc 2) or should every view that requires data be sent a ViewModel?
I was wondering if anyone had any pros/cons on this subject that they could shed some light on?
Thank you
I like to segregate my Domain Objects from my Views. As far as I'm concerned, my Domain Objects are solely for the purpose of representing the Domain of the application, now how the application is displayed.
The presentation layer should not contain any domain logic. Everything they display should be pre-determined by their Controller. The ideal way to ensure this is always adhered to is to ensure the view only receives these flattened ViewModels.
I did ask a similar question myself. Here's a quote from the answer I accepted:
I think that there are merits to
having a different design in the
domain than in the presentation layer.
So conceptually you are actually
looking at two different models, one
for the domain layer and one for the
presentation layer. Each of the models
is optimized for their purpose.
If I have the domain objects for Customer > Sales > Dispatch Address, then I don't want to have to deal with the object traversal in my view. I create a flattened view model that contains all of the properties. There's almost no extra work in mapping to and from this flattened view/presentation model if you use the excellent open source project AutoMapper.
Also, why would you want to pass an entire domain object back to a view if you can create an optimised representation of that model?
If you use NHibernate or similar - your domain objects will most likely be proxies, serializing these dun work. You should always use a ViewModel and map your domain objects to DTOs within your viewmodel. Don't take shortcuts here. Setting the convention will alleviate the pain you'll suffer later on.
It's a standard pattern for a reason.
w://
It depends. In some case it will be fine to use instances of model classes. In other cases a separate ViewModel is the better choice. In my experience it is perfectly acceptable to have different models in your domain and in your views. Or to use the domain model in the view. Do what works best for you. Do a spike for each option, see what works and then decide. You can even choose a different option for each view (and/or partial).
There are definitely going to be simple little apps where it's fine to use the same models across all layers. Generally little forms over data apps. But for a proper domain, my thoughts on the subject are to keep the domain models and view models separate because you don't want them to ever impact each other when changed.
If the domain logic needs a small change to process some new business logic on the back end, you don't want to risk that altering your view. Conversely, if marketing or someone wants to make changes to a view, you don't want those changes leaking back into your domain (having to populate fields and maintain data for no other purpose than some view somewhere is going to use it).
I have a good comparision currently because I'm working on two projects using different approaches. I'm far from stating that "this is bad and this is good" because this is written in some patterns. I know patterns, I like patterns, but I never blindly follow them just to be right. I always use what do I need currently to achieve current goals.
In first app, using domain objects in view, development is very quick. Few changes in few places and you have additional properties, form inputs etc. You don't bother about the layers, just extends/change the code and pass to another problem.
In the second app, where there are always object for use here, there and somewhere else, there's a dozens of classes looking the same, doing the same, and a ton of conversion code between various version of the same objects. More bad is that some developers do some logic on "this version" of class, and other logic is done on "that version". Development is very painful and requires a lot of testing afterwards. Changing a simple thing requires a lot of attention and a lot of code need to be changed. I really don't like this app for that, because I've never yet seen a business benefits from this approach, at least during last year (and we are in the production stage from the year). This app is three-four times more expensive to develop and maintain than the first one.
So, my funny answer on the question is: it depends. If you work in 10-20 people team, you like to come into the work, drink few coffies, talk with friend, do few simple things and go home, a lot of intermediate objects and conversion code will be good for you. If your goal is to be fast and cheap, if you want to focus on business layer, new features, quick changes following, and more if you touch software business and want to cash your project (we do all this stuff to be finally sold, right?), the second approach would be probably better.

Architecture for Satellite Parts of a Larger Application

I work for a firm that provides certain types of financial consulting services in most states in the US. We currently have a fairly straightforward CRUD application that manages clients and information about assets and services we perform for each. It only concerns itself with the fundamental data points and processes that are common to all locations--the least common denominator.
Now we want to implement support for tracking disparate data points and processes that vary from state to state while preserving the core nationally-oriented system. Like this:
(source: flickr.com)
The stack I'm working with is ASP.Net and SQL Server 2008. The national application is a fairly straightforward web forms thing. Its data access layer is a repository wrapper around LINQ to SQL entities and datacontext. There is little business logic beyond CRUD operations currently, but there would be more as the complexities of each state were introduced.
So, how to impelement the satellite pieces...
Just start glomming on the functionality and pursue a big ball of mud
Build a series of satellite apps that re-use the data-access layer but are otherwise stand-alone
Invest (money and/or time) in a rules engine (a la Windows Workflow) and isolate the unique bits for each state as separate rule-sets
Invest (time) in a plugin framework a la MEF and implement each state's functionality as a plugin
Something else
The ideal user experience would appear as a single application that seamlessly adapts its presentation and processes to whatever location the user is working with. This is particularly useful because some users work with assets in multiple states. So there is a strike against number two.
I have no experience with MEF or WF so my question in large part is whether or not mine is even the type of problem either is intended to address. They both kinda sound like it based on the hype, but could turn out to be a square peg for a round hole.
In all cases each state introduces new data points, not just new processes, so I would imagine the data access layer would grow to accommodate the addition of new tables and columns, but I'm all for alternatives to that as well.
Edit: I tried to think of some examples I could share. One might be that in one state we submit certain legal filings involving client assets. The filing has attributes and workflow that are different from other states that may require similar filings, and the assets involved may have quite different attributes. Other states may not have comparable filings at all, still others may have a series of escalating filings that require knowledge of additional related entities unique to that state.
Start with the Strategy design pattern, which basically allows you outline a "placeholder", to be replaced by concrete classes at runtime.
You'll have to sketch out a clear interface between the core app and the "plugins", and you have each strategy implement that. Then, at runtime, when you know which state the user is working on, you can instantiate the appropriate state strategy class (perhaps using a factory method), and call the generic methods on that, e.g. something like
IStateStrategy stateStrategy = StateSelector.GetStateStrategy("TX"); //State id from db, of course...
stateStrategy.Process(nationalData);
Of course, each of these strategies should use the existing data layer, etc.
The (apparent) downside with this solution, is just that you'll be hardcoding the rules for each state, and you cannot transparently add new rules (or new states) without changing the code. Don't be fooled, that's not a bad thing - your business logic should be implemented in code, even if its dependent on runtime data.
Just a thought: whatever you do, completely code 3 states first (with 2 you're still tempted to repeat identical code, with more it's too time-consuming if you decide to change the design).
I must admit I'm completely ignorant about rules or WF. But wouldn't it be possible to just have one big stupid ASP.Net include file with instructions for states separated from main logic without any additional language/program?
Edit: Or is it just the fact that each state has quote a lot a completely different functionality, not just some bits?

Resources