Tuesday, May 14, 2019

MVVM and Flutter

I've been working a bit with Flutter lately and when I start with a new platform I look for some of the normal enterprise patterns that I implement in my projects: unit testing, mocking, dependency injection an enterprise qualify framework, build services, etc. For all of these I found a reasonable solution except for an enterprise quality framework. There were a few out there that I found, but I didn't feel they fit my needs. Because of this I made my own that did fit my requirements based off the MVVM pattern.

As a reminder MVVM stands for Model-View-ViewModel and is a pattern that is found in many client side applications which makes Flutter an ideal platform. For any of you who are unfamiliar with the pattern you can find information about it here: MVVM Pattern.

To create the framework I wanted to achieve the following design goals to make an enterprise ready framework:
  • The only logic in a view (widget) should be presentation logic, viewmodels represent the app structure and Models are business entities. These concepts should be kept separate and represent the app layers.
  • Views can know about viewmodels or models. Viewmodels can know about models but nothing about what views may be used to display them. Models similarly will know nothing about the viewmodels or views that may use them.
  • Viewmodels and models will not know about anything on a 'higher' layer, but instead raise events when pertinent information changes to anything that may be interested.
  • Views can use a concept of data binding to bind to viewmodels and views and have automatic and potentially bidirectional updates. That is to say, a binding between a view and a viewmodel's property will update the UI when the viewmodel's property changes and the view model's property will be updated when the value in the view changes.
  • There needs to be a way to reformat information in a viewmodel or model in a way that that is needed by the view (value conversion).
  • The framework should have a concept of inversion of control / dependency injection.
  • Navigation is an app structure concept and should be controlled by the viewmodel. Since viewmodels shouldn't know about the Views that use them, navigation moves from viewmodel to viewmodel. It is the job of the framework to decide what view to used for a viewmodel.
  • Much of the default functionality of the framework should be overridable.
The result of this is a framework I call fmvvm (Flutter MVVM). I tried to make it pretty easy to implement. Here are some quick examples on using it:

Bootstrapping

Once the fmvvm package is added to your app, bootstrapping is just as easy as extending from FmvvmApp and overriding a few methods:

1:  void main() {  
2:   runApp(MyApp());  
3:  }  
4:  class MyApp extends FmvvmApp {  
5:   @override   
6:   void registerComponents(ComponentResolver componentResolver) {  
7:    super.registerComponents(componentResolver);  
8:    // Add component registrations (Inversion of control)   
9:   }  
10:   @override  
11:   String getInitialRoute() {  
12:    // return initial route name  
13:   }  
14:   @override  
15:   Route getRoutes(RouteSettings settings) {  
16:    // return a route object that handles the requested route.  
17:   }  
18:   @override  
19:   String getTitle() {  
20:    // return the app title.  
21:   }  
22:   @override  
23:   ThemeData getTheme() {  
24:    // optionally override to return a theme for your app.
25:   }  
26:  }  

To start fmvvm we've extended from the FmvvmApp object and a few overrides later, we are ready to go.

Creating a model

Models can really inherit from anything, but they should inherit from BindableBase if you want them to take advantage of data binding. For example:

1:  import 'package:fmvvm/fmvvm.dart';  
2:  class Event extends BindableBase {  
3:   static PropertyInfo descriptionProperty = PropertyInfo('description', String, '');  
4:   String get description => getValue(descriptionProperty);  
5:   set description(String value) => setValue(descriptionProperty, value);  
6:  }  

The static PropertyInfo class combined with a getter and setter is what makes two way data binding possible. If the description property changes, an event will be raised so a view that is bound to this object can be updated automatically.

Creating a viewmodel

Creating a viewmodel is similar. ViewModels are items that can be navigated to and are what normally backs a view. Models can also back widgets that are part of a larger view backed by a viewmodel.

1:  class EventsViewModel extends ViewModel {  
2:   final IGalaEventService _galaEventService;  
3:   EventsViewModel(this._galaEventService)   
4:    events = _galaEventService.getEvents();  
5:   }  
6:   @override  
7:   void init(Object parameter) {  
8:    events = _galaEventService.getEvents();  
9:   }  
10:   static PropertyInfo eventsProperty = PropertyInfo('events', NotificationList);  
11:   NotificationList<Event> get events => getValue(eventsProperty);  
12:   set events(NotificationList<Event> value) => setValue(eventsProperty, value);  
13:  }  

There are a couple of things to notice here:

* We have constructor injection! An instance of the GalaEventService is being injected into the constructor of the viewmodel.
* We have a lifecycle event, init(). This allows parameters to be passed between view models. It is called after the viewmodel is created but before it is displayed. This is intended to do any fetching of data.
* We have something called the NotificationList. This class derives from the normal List but raises events when items are added or removed from the list, this can be used for data binding.

This is a small taste of what is in the fmvvm box. It is intended to create an enterprise app structure that can be used in your applications.

For more information on how to use the framework, including setting up databinding, inversion of control and navigation see the package site: fmvvm.

If you have ideas on ways to improve fmvvm I'd love to hear them. Of course, push requests are always welcomed.


Wednesday, March 6, 2019

Machine Learning and the Expectation of Mistakes

Traditionally in software development we've considered anytime an application creates an incorrect result to a bug. A bug is considered an error in a system; not that the application simply made a mistake, but that there is a fundamental flaw in the system itself. Why is this important? Because mistakes are something that can be learned from and can be self corrected while bugs are fundamental flaws in the system where the only way they can be corrected is by outside intervention to change the operation of the system itself.

Last year Elaine Herzberg was struck and killed by an Uber self driving car. Was this a bug in Uber's software or was it a mistake that the software made? This is an important distinction and one for us to recognize is a real question. Traditionally most applications do exactly what the code tells them to do, no less, no more. But machine learning changes that. We have to ask ourselves if the software in that car took the wrong action based on the data that had been used to create the model to date; if the results of this action were fed back in would the updated model in same situation make decisions that lead to a positive outcome (no crash). If the answer to that is no, the base software needs to change, then we have a bug. But if the answer is yes, we have a self driving car that made a mistake based on a new situation that past experience didn't prepare it for and it may not happen given the same situation a second time.



To do complex automation tasks like autonomous vehicles, where the application will encounter unexpected situations, requires machine learning and the concept of mistakes to be successful. To treat all unexpected outcomes as bugs is not sustainable, there is no way that developers will be able to code in every situation into an application a self driving car may encounter or keep updating it as new situations are discovered. But if we are willing to treat them as mistakes that can be learned from with the model updated based on new situations then we have something that is within the realm of reality.

Software that doesn't just have bugs but also can make mistakes leads to some interesting mental shifts that we need to make as an industry and in society at large. Any application that uses machine learning internally should take a look at any unexpected outcomes and ask themselves the fundamental question, "Is there a mechanism to feed back results into the system whereas the model can be updated and lead to a better (or at least different) result next time?" If the answer is yes then no other action may be required other than monitoring or recreating the situation to see if better results are created. This is a big shift in our thinking.

It is also a big shift for society. Families of people killed by self driving cars may not want to hear that the software made a mistake. They likely want 100% accuracy in correct decision making. A standard that we don't apply to people and self driving cars won't be able to meet it either. There are some other and obvious legal and liability questions that will come to play as well.

I can also see that organizations that don't do well with their people making mistakes, likely are going to have a hard time accepting software that can make mistakes as well. They will categorize them as bugs, just like they do when their people make mistakes. This will be another area where organizations who are more accepting of mistakes will likely have a competitive advantage as their culture will be more accepting of the fundamental learning process that machine learning requires.  Requiring the model to be perfect out of the gate is just not a realistic situation in a complex world with nearly infinite possibilities and situations.



So what should organizations keep in mind when starting with machine learning:

- Understand there is a difference between a bug and a mistake.
- Software that has no way to feed back in the accuracy of the model results can only have bugs. Mistakes require the capacity to learn, to improve.
- Mistakes require different remediation action than bugs. Checking to see if a model learned from the incorrect outcome may become a QA question. If it is found that the model can't learn from the situation, then that would become a bug; a flaw in the ability of the system to learn.
- Machine learning models deal in probabilities. The model may return that it is 95% sure a picture has my face in it. Is 95% good enough? Probably, the threshold of acceptability will need to be defined somewhere. But that should not be the end of the discussion. The best applications will have a way to feed back into the model if the results are correct or not so next time the same picture is guessed more accurately.
- Mistakes need to be tolerated, not just by the development team but the management team, the users of the applications and anyone in society at large that interacts with them. Mistakes may feel like the personification of software systems, but the mental shift is recognizing that a system that can learn from bad outcomes has the capacity to make mistakes and requires no self awareness.
- Many models, particularly ones created with deep learning, are black boxes. They cannot be fixed the same way application code can.
- Without allowing for the concept of mistakes, our current software development capabilities will not be able to create systems that can effectively work in complex environments with uncounted and unknown situations they may experience.

The rise in use of machine learning has the capacity to automate things that we have never been able to automate before. One of the likely victims of that upheaval is the understanding that all problems are flaws or bugs. We will have to be more accepting of mistakes, just as we are of our fellow humans.

Wednesday, December 12, 2018

AI and the Productivity Paradox

Recently I was on a panel discussion at the Greenwich CIO Executive Leadership Summit (CIO Summit) on how innovation and new technologies like AI and machine learning can benefit the enterprise. During the discussion one of the audience members asked a question about the Productivity Paradox and how we can reconcile it with spending more on technology innovation. This is a type a question that a former coworker of mine would lovingly refer to as a "Stump the Chump" question as it is an economics question and none of us on the panel were economists; instead we were management, marketing and technology types.



I really don't feel any of us really nailed a great response but I did some research on the topic and have come to the conclusion that as an enterprise question it is somewhat meaningless. But it is something that we should understand as it tends to come up from time to time in industry and economics articles. Since it does, some in senior management will always think that it is a reason, perhaps, to cut back or remove technology spending. It is not.

Before we get too far, what is the Productivity Paradox? In simple terms it is the idea that as technology spending has increased, from an economic perspective there has not been a similar increase in the productivity of the economy as a whole. The cynical interpretation is that our technology spending is wasted. This is now coming up in relation to new spending on artificial intelligence and machine learning.

Why is the Productivity Paradox happening? These are some of the common answers.

The technology isn't as impressive as we think it is - On the surface this is the most obvious answer, and as I said, the cynical one. We are spending all this money on technology and by extension AI and machine learning but these expenditures are not gaining us anything. Sure, could be.

We don't know how to use the technologies yet or productivity trails adoption - This isn't the first time we have heard of the Productivity Paradox. It had popped up in the 1980's as well. Then the late 1990's happened and economic productivity went through the roof. Not only did everyone have computers, but they were all connected through the internet and all kinds of new possibilities opened for us. This could be where we are at now, on the cusp of some large economic surge as other technologies come together with AI and ML to change the landscape. Similarly, it could be.

We are measuring the wrong things - The economic measure of productivity primarily deals with output of goods and services. Is economic productivity the only thing that makes or breaks a society. Probably not. Facebook, from a business perspective, is primarily an online ad revenue supported company. The economic measure of productivity would not measure in any way the benefit (or lack thereof) of social media. Similarly it doesn't measure a lot of subjective quality of life activities. It may measure the creation of a video game but not anything to do with the use of that game. Similarly if machine learning can make our shopping experiences subjectively "better" it would not measure that either. This could also be at play.



While these are all very interesting rationals, I don't think they have any day to day impact on your business. The real answer is, it just doesn't matter ... or at least it shouldn't matter. Why do I say this? Because the Productivity Paradox is dealing with a macroeconomic question of the best use of scarce resources. Individual companies probably do not measure their success on maximizing the productivity output of the world economy. Instead they likely do have a mission and that mission will be negatively impacted if they can't gain mind and/or market share.

For the sake of argument let's just say the emergence of companies like Uber and Lyft didn't change the size of the pay for ride market at all. Let's say their new business model enabled by new technology didn't increase overall productivity of the economy one bit. If you were a cab or other ride based transportation company, did you care?

My argument is they didn't laugh off Uber and Lyft saying, "look at those idiots spending all that money on technology, don't they know that isn't going to raise the productivity of the economy?". No instead they were pulling out their hair with the realization that Lyft and Uber were taking away large portions their market share. That is why the Productivity Paradox is, and will likely remain, an irrelevant question for the enterprise. Corporate missions and goals do not deal with overall economic productivity and as long as technology can deliver competitive advantage it will continue to be relevant for the enterprise.

Tuesday, August 14, 2018

A Confluence of Enabling Technologies

In the years leading  up to the release of the iPhone, all the technologies that made it possible were already in existence. We had touchscreens, cell phones, GPS devices, MP3 players, smart(ish) phones and even attempts at tablets. Everything was there, but no one could figure out how to put it all together. We had separate devices for GPS, listening to music, browsing the internet, reading email and making calls. While we had all the technologies and even could use them in commercial products, no one had figured out how to best put them together in a new and innovative product that really made these technologies work.

Now we've got new technologies and devices like this one (Microsoft's Hololens):


And this one (Amazon Echo with Alexa):


This guy (Nest):


And even this on our phones:

There are many, many more examples.

It feels like we are in a place very similar to where we were prior to 2007 and the introduction of the iPhone. There are a lot of enabling technologies like machine learning, bots, augmented reality, virtual reality, IoT and other ways for increasingly intelligent devices to interact with and change the world around us.

We might think, "Sure I can do a lot of this stuff now on my Alexa and Android or iPhone and I just got an Occulus Rift." But like the world prior to 2007 it doesn't feel like the current batch of products really has this all right. Not in the way that the early PCs did for in home computers, or the way the Mac fundamentally changed how we interacted with them in 1984, or even how battery, display, processor and OS improvements led the way to the laptop. It wasn't the existence of the internet that brought us online, it was the standardization of HTML, the web browser and distribution technologies like DSL that put it all together.

I'm not saying that tomorrow there is going to be some new revolutionary device and we're all going to stop using our smart phones. But it does feel like there is increasing momentum for something new. All these new technologies are not being used to their fullest and the current standard device platforms for delivering these technologies seem clunky at best. The smart phone is no longer the revolutionary platform that it was, it hasn't been for a while. It may take several years for this to bubble over in a usable way but it's time to start preparing. If you haven't started to learn machine learning or about augmented reality, perhaps now is the time to start investigating how these technologies work.

Wednesday, April 4, 2018

Even For Small Teams, AppCenter Helps Press the Easy Button



Opening up Xcode, Android Studio, Visual Studio, Atom or whatever integrated development environment we use and starting coding away is always easy enough. Sure, we can create an application, go through the process of manually signing it and get an app in the store. This is OK if we are working alone but at some point, many of us are going to be in a situation of working on a team or have a complex enough application where more formal testing and deployment is required. Then we start putting together disparate tools to do mobile DevOps, deploy test versions of the app, handle crash reporting, analytics, etc. Getting all this to work together can be difficult, particularly the build servers for automated builds which can be time consuming to setup and maintain for groups that don't have a lot of experience in that space.

This is the space where Microsoft's App Center really shines. For small teams, who may be new to mobile, they need to know very little about setting up these processes to use App Center. One of the strengths of this is that it falls under Microsoft's new philosophy of embracing technologies outside of their stack, so it isn't just for .Net folks. If you work in Xcode on Swift, no problem, Java in Android, no problem, React Native, no problem. App Center takes a variety of infrastructure needs common to most mobile apps and presents it as a all in one solution where all the parts are easy to use, work well together or can just be taken a-la-carte.

To see how many different capabilities Microsoft has provided on a variety of platforms consider the following:

Feature
Xamarin iOS and Android
Native Android
Native iOS
UWP
React Native
iOS and Android
Cordova
iOS and Android
MacOS
Build
 X
 X
 X
 X
 X

 X
Test
 X
 X
 X

 X
 X

Distribute
 X
 X
 X
 X
 X
 X
 X
Crash Reporting
 X
 X
 X
 X
 X
 X
 X
Analytics
 X
 X
 X
 X
 X
 X
 X
Push Notifications
 X
 X
 X
 X
 X
 X
 X
Code Push




 X
 X


Microsoft has gone to great lengths to make most of the features work with many different mobile development platforms. I don't have space to get into how these features work here, but if you want more information you can watch my AppCenter class on Lynda.com or Linked-In Leaning:



Here's how I think about the good, bad and ugly parts of App Center

The Good


  • We get continuous integration and continuous deployment setup quickly without needing to know a lot about how to do it
  • There is a lot of extendability and capability to tie in other process tools with API and REST interfaces
  • It has reasonable pricing for the features that are not outright free
  • If you are you blue about managing all the devices in your Ad-Hoc provisioning profiles, AppCenter can make this easy
  • Do you only have a few devices to test on? AppCenter has thousands
  • This even offers an entire framework for live code pushing React Native and Cordova Javascript code
  • Crash reporting and analytics can be set up easily on all supported development platforms
  • There just is a lot in this box to like. With AppCenter and a public git style repository of the right type there really is no reason not to have at least a basic CI process

The Bad


  • There are limitations around customization of build process (there are three places where custom scripts can be inserted)
  • No tie in for builds to kick off custom automated testing (must use scripts and API/REST interface)
  • Appium tests can only be written in Java
  • The testing feature does not allow for manual testing, there is no direct interaction with the devices for exploratory testing
  • There are some other limitations
    • Android React Native build only looks two directory levels deep in the repository for workspaces
    • Deployment feature still not as full featured as Hockey App
    • Features like iOS store deployment that require access to the Apple store account need two factor authentication to be turned off

The Ugly


  • To use the build services, it only has Git integration, if you use another source control tool, too bad. You also better be on VSTS, BitBucket or GitHub
  • On that note, repositories cannot be on-premise either
  • Builds cannot easily be tied into a gated check-in concept
  • The REST / API to create builds is fire and forget so it is hard to kick off an AppCenter build from another tool and know when the build is done to know if it failed.
That may seem like a lot of bad and ugly, but some of this is by design. The implication of making it super easy to set up builds that almost anyone can do, is that we may loose some flexibility. But that's kind of the point of AppCenters wide feature set. While organizations of any size and complexity may be tempted to use certain features of AppCenter, AppCenter also brings more complex things like the creation of build processes to even the smallest of teams. If your build needs are super complex then Microsoft has the much more flexible VSTS build services that can be used. But if your build needs are somewhat generic and simple, boy can you get that going with AppCenter quickly. The box of features is large, the breadth of toolsets supported is wide, there just is something for everyone to be found in there.