Does a read only BehaviorSubject interface exist in RX and if not, is it a bad idea to make one? - swift

Implementations of rx provide BehaviorSubject<T> and Variable<T> as mechanisms for modeling properties that change over time (a useful replacement for C# INotifyPropertyChanged).
Generally these are exposed as Observable<T> but it would be more useful to expose properties as something like:
class ObservableValue<T> : Observable<T>{
var currentValue:T { get }
}
This can be created along these lines in swift:
class ObservableValue<Element> : ObservableType {
typealias E = Element
private let subject:BehaviorSubject<E>
var currentValue:E {
get {
return try! subject.value()
}
}
init(subject:BehaviorSubject<E>) {
self.subject = subject
}
func subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
return self.subject.subscribe(observer)
}
}
Does this already exist? and if not is it because it's against the aims of Rx?
The only way around it is to expose a separate currentValue or write consumers that assume the concrete implementation behind the exposed Observable is a BehaviourSubject or somewhere in the chain a replay() has occured e.g. the following snippet doesn't make it explicit that as soon as I subscribe I will get a value:
class MyViewModel {
// 'I will notify you of changes perhaps including my current value'
myProperty:Observable<String>
}
so code has to be written as if its 'asynchronous' with an underlying assumption it will act in an almost synchronous manner rather than:
class MyViewModel {
// 'I have a current value and will notify you of changes going forward'
myProperty:ObservableValue<String>
}

Having thought it over and discussed it a bit more presumably the reason it doesn't (and perhaps shouldn't exist) is that it's an introduction of imperatively accessed state.
Other mechanisms of maintaining state (such as scan) do so within the confines of chained observables rather than as 'dead-end' direct calls such as 'give me the value right now'.
Perhaps it would have it's place in a hybrid reactive/imperative approach but it may just hinder full embracement of the reactive style.
It's analogous to using promises or tasks in half of the code then reverting to synchronous blocking code in other parts.

In most cases what people do is create a standard view model that exposes properties via INotifyPropertyChanged. This allows UI elements to bind to them and receive property change events and keep the UI in sync.
Then if you want an IObservable for said property you take advantage of standard Rx operators that turn events into IObservable. You can google this to find lots of different implementations. You would generally create and consume these observables from something that is observing the view model rather than expose them on the view model directly.

Related

Should I put my UserDefaults saving process into ViewModel? (good architecture)

I'm creating a simple NewsApp. I want to create the best app architecture I can made. So my question is that if I want save really simple data like username and maybe 5-6 tags as strings, should I put userDefaults logic into my viewModel or should I create a layer between ViewModel and UserDefaultsAPI which will take care about saving data?
I mean I will create StoreData protocol which UserDefaultsAPI will implement. And if I should do it how I can achieve that? I am using RxSwift and I don't now how to subscribe changing data in UserDefaults by UserDefaultsAPI.
You should create a layer between, but given an Rx/functional architecture, it shouldn't be something heavy weight like a protocol.
Learn How to Control the World and do something like this instead:
struct Storage {
static var shared = Storage()
var saveProperty: (Property) -> Void = { property in
UserDefaults.standard.set(try? JSONEncoder().encode(property), forKey: "property")
}
var deleteProperty: () -> Void = {
UserDefaults.standard.removeObject(forKey: "property")
}
var currentProperty: () -> Observable<Property?> = {
UserDefaults.standard.rx.observe(Data.self, "property")
.map { $0.flatMap { try? JSONDecoder().decode(Property.self, from: $0) } }
.distinctUntilChanged()
}
}
struct Property: Codable, Equatable { }
It depends what your doing creating a seperate layer gives you, the opportunity to have different sources for data that implement the same protocol could be useful, and your data may be complex types than need to be encoded and decoded, so it makes sense to encapsulate that out, you may also want to provide some limit range to some of your values, but UserDefaults is just a service like NotificationCenter, you are not going to automatically wrap NotificationCenter in ever class, just do what is simplest, but doesn't run the risk of painting yourself in a corner later on. You are not going to get every issue decided at the get go right, the skill is to make sure you can quickly change if the need arises, and knowing about what possibility's you will need to take advantage of in the future and how can you avoid needing to make complex changes in the moment that don't add squat. There are lots of things you need to do, and being able to prioritise them is an important part of what you do, don't try make cleaver designs, be cleaver in making designs that can be easy for other to understand and modify.

How to make a Publisher that sends multiple values in Combine

Could you help me with a Combine issue?
I'd like to make a Publisher which sends multiple values during its lifetime. In more detail, I want to wrap a method with a completion handler into a Publisher, and the completion handler is supposed to be called multiple times. For example, it's a method used for receiving messages via WebSocket like this:
webSocketClient.receiveMessage { message, error in
// this closure is called multiple times, everytime a message comes
...
}
How can I wrap this into a Publisher? I want something like AnyPublisher<String, Error> in the end.
Wrapping these is super easy when I use other FRP libraries. For example, in ReactiveSwift, it can be achieved by using SignalProducer.init(_ startHandler:). In RxSwift, it's Observable.create method.
In Combine, I found Future can be used when there's only one value to emit, but it doesn't suit my current case. I couldn't find any initializer for Publisher for this use case.
Also, I found Effect.run in TCA (The Composable Architecture) which can be used for this case. It seems custom publishers are used in its implementation, which seems a bit complicated for simple usage, but is this the only way? Are there any other easy ways to achieve the similar behavior?
I feel this is a quite common scenario, so I'd like to know how Combine users are handling this case in practice.
Thank you in advance!
Basically there are two options.
In a SwiftUI environment make the class which contains the code conform to ObservableObject and add a #Published property
class ViewModel : ObservableObject {
#Published var message = ""
func loadData() {
webSocketClient.receiveMessage { message, error in
self.message = message
...
}
}
}
In the view create a #StateObject of the view model to be notified about new messages.
Or declare a subject to send values
class ViewModel {
let subject = PassthroughSubject<String,Never>()
func loadData() {
webSocketClient.receiveMessage { message, error in
self.subject.send(message)
...
}
}
}
To receive the notifications get an instance of the class, call sink on the subject and store the result into a strong reference.

Composing IObservables and cleaning up after registrations

I have some code in a class that takes FileSystemWatcher events and flattens them into an event in my domain:
(Please note, the *AsObservable methods are extensions from elsewhere in my project, they do what they say 🙂.)
watcher = new FileSystemWatcher(ConfigurationFilePath);
ChangeObservable = Observable
.Merge(
watcher.ChangedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Edited,
};
}),
watcher.DeletedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Deleted,
};
}),
watcher.RenamedAsObservable().Select((args) =>
{
return new ConfigurationChangedArgs
{
Type = ConfigurationChangeType.Renamed,
};
})
);
ChangeObservable.Subscribe((args) =>
{
Changed.Invoke(this, args);
});
Something that I'm trying to wrap my head around as I'm learning are best practices around naming, ownership and cleanup of the IObservable and IDisposable returned by code like this.
So, some specific questions:
Is it okay to leak IObservables from a class that creates them? For example, is the property I'm assigning this chain to okay to be public?
Does the property name ChangeObservable align with what most people would consider best practice when using the .net reactive extensions?
Do I need to call Dispose on any of my subscriptions to this chain, or is it safe enough to leave everything up to garbage collection when the containing class goes out of scope? Keep in mind, I'm observing events from watcher, so there's some shared lifecycle there.
Is it okay to take an observable and wire them into an event on my own class (Changed in the example above), or is the idea to stay out of the native .net event system and leak my IObservable?
Other tips and advice always appreciated! 😀
Is it okay to leak IObservables from a class that creates them? For
example, is the property I'm assigning this chain to okay to be
public?
Yes.
Does the property name ChangeObservable align with what most
people would consider best practice when using the .net reactive
extensions?
Subjective question. Maybe FileChanges? The fact that it's an observable is clear from the type.
Do I need to call Dispose on any of my subscriptions to
this chain, or is it safe enough to leave everything up to garbage
collection when the containing class goes out of scope?
The ChangeObservable.Subscribe at the end could live forever, preventing the object from being garbage collected if the event is subscribed to, though that could also be your intention. Operator subscriptions are generally fine. I can't see the code for your ChangedAsObservable like functions. If they don't include a Subscribe or an event subscription, they're probably fine as well.
Keep in mind,
I'm observing events from watcher, so there's some shared lifecycle
there.
Since FileWatcher implements IDisposable, you should probably use Observable.Using around it so you can combine the lifecycles.
Is it okay to take an observable and wire them into an event on
my own class (Changed in the example above), or is the idea to stay
out of the native .net event system and leak my IObservable?
I would prefer to stay in Rx. The problem with event subscriptions is that they generally live forever. You lose the ability to control subscription lifecycle. They're also feel so much more primitive. But again, that's a bit subjective.

Entity Framework Inheritance and Logic

I've been creating a prototype for a modern MUD engine. A MUD is a simple form of simulation and provide a good method in which to test a concept I'm working on. This has led me to a couple of places in my code where things, are a bit unclear, and the design is coming into question (probably due to its being flawed). I'm using model first (I may need to change this) and I've designed a top down architecture of game objects. I may be doing this completely wrong.
What I've done is create a MUDObject entity. This entity is effectively a base for all of my other logical constructs, such as characters, their items, race, etc. I've also created a set of three meta classes which are used for logical purposes as well Attributes, Events, and Flags. They are fairly straightforward, and are all inherited from MUDObject.
The MUDObject class is designed to provide default data behavior for all of the objects, this includes deletion of dead objects. The automatically clearing of floors. etc. This is also designed to facilitate this logic virtually if needed. For example, checking a room to see if an effect has ended and deleting the the effect (remove the flag).
public partial class MUDObject
{
public virtual void Update()
{
if (this.LifeTime.Value.CompareTo(DateTime.Now) > 0)
{
using (var context = new ReduxDataContext())
{
context.MUDObjects.DeleteObject(this);
}
}
}
public virtual void Pause()
{
}
public virtual void Resume()
{
}
public virtual void Stop()
{
}
}
I've also got a class World, it is derived from MUDObject and contains the areas and room (which in turn contain the games objects) and handles the timer for the operation to run the updates. (probably going to be moved, put here as if it works would limit it to only the objects in-world at the time.)
public partial class World
{
private Timer ticker;
public void Start()
{
this.ticker = new Timer(3000.0);
this.ticker.Elapsed += ticker_Elapsed;
this.ticker.Start();
}
private void ticker_Elapsed(object sender, ElapsedEventArgs e)
{
this.Update();
}
public override void Update()
{
this.CurrentTime += 3;
// update contents
base.Update();
}
public override void Pause()
{
this.ticker.Enabled = false;
// update contents
base.Pause();
}
public override void Resume()
{
this.ticker.Enabled = true;
// update contents
this.Resume();
}
public override void Stop()
{
this.ticker.Stop();
// update contents
base.Stop();
}
}
I'm curious of two things.
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject?
i.e. context.MUDObjects.Flags or context.Flags
If not how can I query a child type specifically?
Does the Update/Pause/Resume/Stop architecture I'm using work
properly when placed into the EF entities directly? given than it's for
data purposes only?
Will locking be an issue?
Does the partial class automatically commit changes when they are made?
Would I be better off using a flat repository and doing this in the game engine directly?
1) Is there a way to recode the context so that it has separate ObjectSets for each type derived from MUDObject?
Yes, there is. If you decide that you want to define a base class for all your entities it is common to have an abstract base class that is not part of the entity framework model. The model only contains the derived types and the context contains DbSets of derived types (if it is a DbContext) like
public DbSet<Flag> Flags { get; set; }
If appropriate you can implement inheritance between classes, but that would be to express polymorphism, not to implement common persistence-related behaviour.
2) Does the Update/Pause/Resume/Stop architecture I'm using work properly when placed into the EF entities directly?
No. Entities are not supposed to know anything about persistence. The context is responsible for creating them, tracking their changes and updating/deleting them. I think that also answers your question about automatically committing changes: no.
Elaboration:
I think here it's good to bring up the single responsibility principle. A general pattern would be to
let a context populate objects from a store
let the object act according to their responsibilities (the simulation)
let a context store their state whenever necessary
I think Pause/Resume/Stop could be responsibilities of MUD objects. Update is an altogether different kind of action and responsibility.
Now I have to speculate, but take your World class. You should be able to express its responsibility in a short phrase, maybe something like "harbour other objects" or "define boundaries". I don't think it should do the timing. I think the timing should be the responsibility of some core utility which signals that a time interval has elapsed. Other objects know how to respond to that (e.g. do some state change, or, the context or repository, save changes).
Well, this is only an example of how to think about it, probably far from correct.
One other thing is that I think saving changes should be done not nearly as often as state changes of the objects that carry out the simulation. It would probably slow down the process dramatically. Maybe it should be done in longer intervals or by a user action.
First thing to say, if you are using EF 4.1 (as it is tagged) you should really consider going to version 5.0 (you will need to make a .NET 4.5 project for this)
With several improvements on performance, you can benefit from other features also. The code i will show you will work for 5.0 (i dont know if it will work for 4.1 version)
Now, let's go to you several questions:
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject? If not how can I
query a child type specifically?
i.e. context.MUDObjects.Flags or context.Flags
Yes, you can. But to call is a little different, you will not have Context.Worlds you will only have the base class to be called this way, if you want to get the set of Worlds (that inherit from MUDObject, you will call:
var worlds = context.MUDObjects.OfType<World>();
Or you can do in direct way by using generics:
var worlds = context.Set<World>();
If you define you inheritance the right way, you should have an abstract class called MUDObjects and all others should iherit from that class. EF can work perfectly with this, you just need to make it right.
Does the Update/Pause/Resume/Stop architecture I'm using work properly
when placed into the EF entities directly? given than it's for data
purposes only?
In this case i think you should consider using a Design Pattern called Strategy Pattern, do some research, it will fit your objects.
Will locking be an issue?
Depends on how you develop the system....
Does the partial class automatically commit changes when they are
made?
Did not understand that question.... Partial classes are just like regular classes, thay are just in different files, but when compiled (or event at Design-Time, because of the vshost.exe) they are in fact just one.
Would I be better off using a flat repository and doing this in the
game engine directly?
Hard to answer, it all depends on the requirements of the game, deploy strategy....

Should a ViewModel be initialized via constructor, properties, or method call

I'm fighting a few different design concepts within the context of MVVM that mainly stem from the question of when to initialize a ViewModel. To be more specific in terms of "initializing" I'm referring to loading values such as selection values, security context, and other things that could in some cases cause a few second delay.
Possible strategies:
Pass arguments to ViewModel constructor and do loading in the constructor.
Only support a parameterless constructor on the ViewModel and instead support initialize methods that take parameters and do the loading.
A combination of option 1 and 2 where arguments are passed to the ViewModel constructor but loading is deferred until the an Initialize method is called.
A variation on option 3 where instead of parameters being passed to the ViewModel constructor they are set directly on properties.
Affect on ViewModel property getters and setters
In cases where initialization is deferred there is a need to know whether the ViewModel is in a state that is considered available for which the IsBusy property generally serves just as it does for other async and time consuming operations. What this also means though is that since most properties on the ViewModel expose values retrieved from a model object that we constantly have to write the following type of plumbing to make sure the model is available.
public string Name
{
get
{
if (_customerModel == null) // Check model availability
{
return string.Empty;
}
_customerModel.Name;
}
}
Although the check is simple it just adds to the plumbing of INPC and others types of necessities that make the ViewModel become somewhat cumbersome to write and maintain. In some cases it becomes even more problematic since there may not always be a reasonable default to return from the property getter such might be the case with a boolean property IsCommercialAccount where if there is no model available it doesn't make sense to return true or false bringing into question a whole slew of other design questions such as nullability. In the case of option 1 from above where we passed everything into the constructor and loaded it then we only need to concern ourselves with a NULL ViewModel from the View and when the ViewModel is not null it is guaranteed to be initialized.
Support for deferred initialization
With option 4 it is also possible to rely on ISupportInitialize which could be implemented in the base class of the ViewModel to provide a consistent way of signaling whether the ViewModel is initialized or not and also to kick off the initialization via a standard method BeginInit. This could also be used in the case of option 2 and 3 but makes less sense if all initialization parameters are set all in one atomic transaction. At least in this way, the condition shown above could turn into something like
How the design affects IoC
In terms of IoC I understand that options 1 and 3 can be done using constructor injection which is generally preferred, and that options 2 and 4 can be accomplished using method and property injection respectively. My concern however is not with IoC or how to pass in these parameters but rather the overall design and how it affects the ViewModel implementation and it's public interface although I'd like to be a good citizen to make IoC a bit easier if necessary in the future.
Testability
All three options seem to support the concept of testability equally which doesn't help much in deciding between these options although it's arguable that option 4 could require a more broad set of tests to ensure proper behavior of properties where that behavior depends on the initialization state.
Command-ability
Options 2, 3, and 4 all have the side effect of requiring code behind in the View to call initialization methods on the ViewModel however these could be exposed as commands if necessary. In most cases one would probably be loading calling these methods directly after construction anyways like below.
var viewModel = new MyViewModel();
this.DataContext = viewModel;
// Wrap in an async call if necessary
Task.Factory.StartNew(() => viewModel.InitializeWithAccountNumber(accountNumber));
Some other thoughts
I've tried variations on these strategies as I've been working with the MVVM design pattern but haven't concluded on a best practice yet. I would love to hear what the community thinks and attempt to find a reasonable consensus on the best way forward for initializing ViewModels or otherwise dealing with their properties when they are in an unavailable state.
An ideal case may be to use the State pattern where the ViewModel itself is swapped out with different ViewModel objects that represent the different states. As such we could have a general BusyViewModel implementation that represents the busy state which removes one of the needs for the IsBusy property on the ViewModel and then when the next ViewModel is ready it is swapped out on the View allowing that ViewModel to follow the stategy outlined in option 1 where it is fully initialized during construction. This leaves open some questions about who is responsible for managing the state transitions, it could for example be the responsibility of BusyViewModel to abstract something similar to a BackgroundWorker or a Task that is doing the initialization itself and will present the internal ViewModel when ready. Swapping the DataContext on the view on the other hand may require either handling an event in the View or giving limited access to the DataContext property of the View to BusyViewModel so it can be set in the traditional state pattern sense. If there is something similar that people are doing along these lines I would definitely like to know because my google searching hasn't turned up much yet.
My general approach to object oriented design, whether I am creating a view model, or an other type of class is that; Everything that can be passed to the constructor, should be passed to the constructor. This reduces the need to have some sort of IsInitialized state and makes your objects less complex. Sometimes certain frameworks make it hard to follow this approach, IoC containers for example (although they should allow constructor injection), but I still adhere to it as a general rule.