-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Dart version update above 3 null safety #6
base: master
Are you sure you want to change the base?
Dart version update above 3 null safety #6
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, @VladimirCores.
I've made a few requests, mainly around the refactoring of some params / vars to use underscores. Since this is a stylistic choice that is not backward compatible I ask that they be returned to their previous states. There are some other minor requests/comments as well.
/** | ||
* This [INotifications]'s [body] | ||
*/ | ||
void set body( dynamic bodyObject ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are the accessors removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we have methods: getBody
, setBody
, the accessors looks excess, they duplicate functionality. And in my practice I always use these methods. What are the reasons for accessors existence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessors are not duplicate functionality, they are alternate functionality. You can say myModel.body
or myModel.getBody()
whichever may be your preference. They exist as part of the original framework and all ports.
It's important to remember that personal stylistic choices should not distort a port. A port should hew as closely to the reference implementation as is practicable. This is why the ActionScript Developers Guide to PureMVC is generally useful do devs using most ports. Because the implementation and idioms are very similar across ports. If developers used to one port of the framework find that the same idioms they are used to are present in another port, they get to joy quicker. If they arrive here and find that things are different owing to stylistic choices, well, it all becomes a bit loosey-goosey. The promise of easy portability breaks down. If this one thing is arbitrarily different, what others might be?
lib/src/core/Controller.dart
Outdated
Controller(String key) { | ||
if (instanceMap.containsKey(key)) throw MultitonErrorControllerExists(); | ||
_multitonKey = key; | ||
instanceMap[_multitonKey] = this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change _multitonKey
back to multitonKey
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setter added for every places near getter.
But why multitonKey
could be mutable? Can't imagine use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this one is my bad. I failed to realize that Dart had promoted the underscore as an alternative to having protected
or private
keyword, as was present in the AS3 reference.
So in this case, we legit have to break from the reference implementation and do something different. This means all the Multiton actors need this underscore for the multitonKey
property. Please do an exhaustive search to make sure all references are replaced, because I recall that in the original PR, one of the classes still had a loose multitonKey
ref without the underscore on it.
lib/src/core/Model.dart
Outdated
proxyMap = new Map<String,IProxy>(); | ||
Model(String key) { | ||
if (instanceMap.containsKey(key)) throw MultitonErrorModelExists(); | ||
_multitonKey = key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change _multitonKey
back to multitonKey
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setter added for every places near getter.
|
||
// Make sure caller and callback were set | ||
expect( observer.getNotifyMethod(), isNotNull ); | ||
expect( observer.notifyMethod, isNotNull ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this test removed?
|
||
// Make sure callback method was set | ||
expect( observer.getNotifyMethod(), isNotNull ); | ||
expect( observer.notifyMethod, isNotNull ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this accessor test removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might guess that accessors are needed to keep original version of the property in case something overrides them.
|
||
// Make sure caller was set | ||
expect( observer.getNotifyContext(), isNotNull ); | ||
expect( observer.getNotifyContext(), same(this) ); | ||
expect( observer.notifyContext, isNotNull ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this test removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed direct access to the value of notifyContext
because I though its excess and creates ambiguity in understanding of their use (as we already have methods). But I reverted the remove, and the test as well.
test/Unit_Tests.dart
Outdated
part 'Test_Facade.dart'; | ||
part 'Test_MacroCommand.dart'; | ||
part 'Test_Mediator.dart'; | ||
part 'Test_Model.dart'; | ||
// PureMVC Unit Tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did this comment get moved to the middle of the list of tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how ... but its corrected, and comment moved to the top of "declaration" of parts.
test/Unit_Tests.dart
Outdated
void write(String message) { | ||
document.querySelector('#status').innerHtml = message; | ||
} | ||
// void onTestResult(TestCase testCase) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are these output messages commented out? If no longer needed, we can just remove them. Are they made redundant by the test runner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are not needed for test run from IDE (Android Studio) and this commented out code removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another small request. Could you please update the VERSION and README files to add notes about the changes, and increment this to 2.0.7?
@cliffhall I read your messages, and will answer (and correct) them I hope soon, have some urgent business. Thanks for your collaboration on this! : ) |
198a5c1
to
d344648
Compare
…not needed for run of the tests.
…tter in View, Model and Controller.
…nd observer.notifyContext.
9d9f4bd
to
357356b
Compare
@cliffhall I will review this PR once again and make changes you requested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were a lot more changes this time. Moving target. Unfortunately, I'm requesting most of them be reverted under three major themes:
-
First is my bad. I didn't realize _ was elevated to language level 'private' and no longer just an idiom here. If that's what it takes to make the property private, then so be it, _ on private vars throughout.
-
For maximum portability, we eschew the local syntactic sugar of a language wherever possible and favor simple, widely supported idioms.
So for instance, in a collection where you're invoking containsKey
, you're relying on a Dart-specific feature. While myMap.containsKey('stuff')
is 100% how you might go about it in your application, in a portable framework myMap['stuff']
is the favored approach.
That's important to do even in ports of the reference implementation, because someone who uses this port might decide to port it to their new favorite language. If they're going from a very Dart-flavored implementation, then they need to seek equivalent affordances in the target language and that amounts to friction for the porting developer and a reduced likelihood that they will complete the port.
With regards to portability, PureMVC took a hint from C, which is so dirt simple it exists for nearly every processor in the world.
- In some places, refactors have been done that, while possibly making more sense or being slightly more efficient, should not have happened. A particularly sensitive one is
notifyObservers
. It took a long time to get that one working properly. Lots of community feedback led to a stable implementation. I'd like to keep all of the method implementations as close to the original as is allowed by the language. By doing so, we leverage years of troubleshooting and improvement to get the expected behaviors we see in the ports today. As a result we usually don't see new issues cropping up after a port. Simple refactors can lead to bugs that lie dormant because a particular weird use-case has not been tried, as was the case withnotifyObservers
.
if (instanceMap.containsKey(key)) throw MultitonErrorControllerExists(); | ||
_multitonKey = key; | ||
instanceMap[_multitonKey] = this; | ||
commandMap = Map<String, Function>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the above comment, commandMap
and several other properties of the Multitons should be underscored as well. check the AS3 Reference for props that were protected or private.
{ | ||
view = View.getInstance( multitonKey ); | ||
void initializeController() { | ||
view = View.getInstance(multitonKey)!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's one where it needs to be underscored but wasn't. It's going to be important to sweep all the classes and make sure all the props intended to be private/protected have underscores everywhere they're referenced.
return instanceMap[ key ]; | ||
static IController? getInstance(String? key) { | ||
if (key == null || key == "") return null; | ||
if (instanceMap.containsKey(key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this logic refactored? It may do the same thing in the end, but please, if possible, stick with the existing logic implementation, which was inherited from the AS3 port, which had years of improvement associated with it to eliminate hard to detect bugs. While one implementation might be as good as another, it's where new bugs can creep in. We'd like to make sure that we lean on the well-tested reference wherever we can, departing from it only when we have no other choice.
Function commandFactory = commandMap[ note.getName() ]; | ||
if ( commandFactory == null ) return; | ||
void executeCommand(INotification note) { | ||
final noteName = note.getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another unnecessary departure from the original.
if ( commandMap[ noteName ] == null ) { | ||
view.registerObserver( noteName, new Observer( executeCommand, this ) ); | ||
void registerCommand(String noteName, Function commandFactory) { | ||
if (!hasCommand(noteName)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stick with the original implementation wherever possible.
|
||
// The [IFacade] Multiton instanceMap. | ||
static Map<String,IFacade> instanceMap; | ||
static Map<String, IFacade> instanceMap = Map<String, IFacade>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this being initialzed?
* | ||
* - Returns [String] - the type of the [INotification]. | ||
*/ | ||
String? getType() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, not sure what the ? is for in this context, can we drop it throughout?
/** | ||
* This [INotifications]'s [name] | ||
*/ | ||
final String _name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you adding final to _name but not _type? I think dropping it from both is what's needed.
/** | ||
* This [INotifications]'s [type] | ||
*/ | ||
String? _type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
questioning the ?. I think. we can drop throughout (in this context)
test/Unit_Tests.dart
Outdated
document.querySelector('#status').innerHtml = message; | ||
} | ||
// void onTestResult(TestCase testCase) { | ||
// write("${testCase.result} ${testCase.currentGroup}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove these comments?
Conform framework to the Dart 3 version.
Make all tests pass.
Example works.
Mr @cliffhall could you take a look?