Maybe it's just me, but after diving into the new Vue3 composition API, I don't really see the benifit of it, compared to just creating a new class that exports some helper functions (functions to prevent duplicated code). Can someone please clarify this for me?
official doc actually has a pretty good detailed explanation with examples, you can check step by step starting from here: https://v3.vuejs.org/guide/composition-api-introduction.html#why-composition-api
The most important is:
Such fragmentation is what makes it difficult to understand and maintain a complex component. The separation of options obscures the underlying logical concerns. In addition, when working on a single logical concern, we have to constantly "jump" around option blocks for the relevant code.
Any helper classes can minimize logical concerns fragmentation. So everything is almost next to each other, but still you'll have to separate and put them to different Options api sections (data, watchers, computed, etc)
It can't eliminate mentioned "jumps" around option blocks.
It would be much nicer if we could collocate code related to the same logical concern. And this is exactly what the Composition API enables us to do.
Related
I'm exploring both Go and Entity-Component-Systems. I understand how ECS works, and I'm trying to replicate what seems to be the go-to document of ECS, namely http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
For performance, the document recommends to use static arrays of every component type. That is, not arrays of component interfaces (arrays of pointers). The problem with this in Go is circular imports.
I have one package, ecs, which contains the definitions for Entity, Component and System types/interfaces as well as an EntityManager. Another package, ecs/components, contains the various components. Obviously, the ecs/components package depends on ecs. But, to declare arrays of specific components in EntityManager, ecs would depend on ecs/components, therefore creating a circular import.
Is there any way of avoiding this? I am aware that normally a high level system should not depend on lower systems. I'm also want to point out that using an array of pointers is probably fast enough for my purposes, but I'm interested in possible workarounds (for future reference)
Thank you for your help!
For performance, the document recommends to use static arrays of every
component type.
I'm just going to start off saying that I may be blind, but I ctrl+f'd and read that document multiple times and didn't see anything close to that. (Certainly some optimizations could be made this way with regards to things like avoiding cache misses, but I'm dubious it in any way outweighs the clerical overhead).
There's the easy answer to the exact question you asked first, the . import. Any package with an import statement like import . "some/other/package" will treat that package's contents as its own, ignoring circular dependencies. Don't do this.
Unfortunately, without merging the packages, you won't be able to do this (without using interfaces, I mean). Don't fear, though. The article you posted explicitly says this under "implementation details".
Giving each component a common interface means deriving from a base
class with virtual functions. This introduces some additional
overhead. Do not let this turn you against the idea, as the additional
overhead is small, compared to the savings due to simplification of
objects.
It's outright telling you to use interfaces (okay, C++ virtual inheritance, but close enough). It's okay, it's necessary. Especially if you want two slightly different AI components or something, it's a godsend then.
I'm looking for non-trivial resources on concepts of asychronous programming, preferably books but also substantial articles or papers. This is not about the simple examples like passing a callback to an event listener in GUI programming, or having producer-consumer decoupled over a queue, or writing an onload handler for your HTML (although all those are valid). It's about the kind of problems the lighttpd developers might be concerned with, or someone doing substantial business logic in JavaScript that runs in a browser or on node.js. It's about situations where you need to pass a callback to a callback to a callback ... about complex asynchronous control-flows, and staying sane at the same time. I'm looking for concepts that allow you to do this systematically, to reason about this kind of control-flows, to seriously manage a significant amount of logic distributed in deeply nested callbacks, with all its ensuing issues of timing, synchronization, binding of values, passing of contexts, etc.
I wouldn't shrink away from some abstract explorations like continuation-passing-style, linear logic or temporal reasoning. Posts like this seem to go into the right direction, but discuss specific issues rather than a complete theory (E.g. the post mentions the "reactor" pattern, which seems relevant, without describing it).
Thanks.
EDIT:
To give more details about the aspects I'm interested in. I'm interested in a disciplined approach to asynchronous programming, a theory if you will, maybe just a set of specific patterns that I can pass to fellow programmers and say "This is the way we do asynchronous programming" in non-trivial scenarios. I need a theory to disentangle layers of callbacks that randomly fail to work, or produce spurious results. I want an approach which allows me to say "If we do it this way, we can be sure that ...". - Does this make things clearer?
EDIT 2:
As feedback indicates a dependency on the programming language: This will be JavaScript, but maybe it's enough to assume a language that allows higher-order functions.
EDIT 3:
Changed the title to be more specific (although I think design patterns are only one way to look at it; but at least it gives a better direction).
When doing layered callbacks currying is a useful technique.
For more on this you can look at http://en.wikibooks.org/wiki/Haskell/Higher-order_functions_and_Currying and for javascript you can look at http://www.svendtofte.com/code/curried_javascript/.
Basically, if you have multiple layers of callbacks, rather than having one massive parameter list, you can build it up incrementally, so that when you are in a loop calling your function, the various callback functions have already been defined, and passed.
This isn't meant as a complete answer to the question, but I was asked to put this part into an answer, so I did.
After a quick search here is a blog where he shows using currying with callbacks:
http://bjouhier.wordpress.com/2011/04/04/currying-the-callback-or-the-essence-of-futures/
UPDATE:
After reading the edit to the original question, to see design patterns for asynchronous programming, this may be a good diagram:
http://www1.cse.wustl.edu/~schmidt/patterns-ace.html, but there is much more to good asynchronous design, as first-order functions will enable this to be simplified, but, if you are using the MPI library and Fortran then you will have different implementations.
How you approach the design is affected heavily by the language and the technologies involved, that any answer will fall short of being complete.
If we had a defined hierarchy in an application. For ex a 3 - tier architecture, how do we restrict subsequent developers from violating the norms?
For ex, in case of MVP (not asp.net MVC) architecture, the presenter should always bind the model and view. This helps in writing proper unit test programs. However, we had instances where people directly imported the model in view and called the functions violating the norms and hence the test cases couldn't be written properly.
Is there a way we can restrict which classes are allowed to inherit from a set of classes? I am looking at various possibilities, including adopting a different design pattern, however a new approach should be worth the code change involved.
I'm afraid this is not possible. We tried to achieve this with the help of attributes and we didn't succeed. You may want to refer to my past post on SO.
The best you can do is keep checking your assemblies with NDepend. NDepend shows you dependancy diagram of assemblies in your project and you can immediately track the violations and take actions reactively.
(source: ndepend.com)
It's been almost 3 years since I posted this question. I must say that I have tried exploring this despite the brilliant answers here. Some of the lessons I've learnt so far -
More code smell come out by looking at the consumers (Unit tests are best place to look, if you have them).
Number of parameters in a constructor are a direct indication of number of dependencies. Too many dependencies => Class is doing too much.
Number of (public) methods in a class
Setup of unit tests will almost always give this away
Code deteriorates over time, unless there is a focused effort to clear technical debt, and refactoring. This is true irrespective of the language.
Tools can help only to an extent. But a combination of tools and tests often give enough hints on various smells. It takes a bit of experience to catch them in a timely fashion, particularly to understand each smell's significance and impact.
You are wanting to solve a people problem with software? Prepare for a world of pain!
The way to solve the problem is to make sure that you have ways of working with people that you don't end up with those kinds of problems.... Pair Programming / Review. Induction of people when they first come onto the project, etc.
Having said that, you can write tools that analyse the software and look for common problems. But people are pretty creative and can find all sorts of bizarre ways of doing things.
Just as soon as everything gets locked down according to your satisfaction, new requirements will arrive and you'll have to break through the side of it.
Enforcing such stringency at the programming level with .NET is almost impossible considering a programmer can access all private members through reflection.
Do yourself and favour and schedule regular code reviews, provide education and implement proper training. And, as you said, it will become quickly evident when you can't write unit tests against it.
What about NetArchTest, which is inspired by ArchUnit?
Example:
// Classes in the presentation should not directly reference repositories
var result = Types.InCurrentDomain()
.That()
.ResideInNamespace("NetArchTest.SampleLibrary.Presentation")
.ShouldNot()
.HaveDependencyOn("NetArchTest.SampleLibrary.Data")
.GetResult()
.IsSuccessful;
// Classes in the "data" namespace should implement IRepository
result = Types.InCurrentDomain()
.That().HaveDependencyOn("System.Data")
.And().ResideInNamespace(("ArchTest"))
.Should().ResideInNamespace(("NetArchTest.SampleLibrary.Data"))
.GetResult()
.IsSuccessful;
"This project allows you create tests that enforce conventions for class design, naming and dependency in .Net code bases. These can be used with any unit test framework and incorporated into a build pipeline. "
The other day i stumbled onto a rather old usenet post by Linus Torwalds. It is the infamous "You are full of bull****" post when he defends his choice of using plain C for Git over something more modern.
In particular this post made me think about the enormous amount of abstraction layers that accumulate one over the other where I work. Mine is a Windows .Net environment. I must say that I like C# and the .Net environment, it really makes most things easy.
Now, I come from a very different background made of Unix technologies like C and a plethora or scripting languages; to me, also, OOP is just one, and not always the best, programming paradigm.. I often struggle (in a working kind of way, of course!) with my colleagues (one in particular), because they appear to be of the "any problem can be solved with an additional level of abstraction" church, while I'm more of the "keeping it simple" school. I think that there is a very different mental approach to the problems that maybe comes from the exposure to different cultures.
As a very simple example, for the first project I did here I needed some configuration for an application. I made a 10 rows class to load and parse a txt file to be located in the program's root dir containing colon separated key / value pairs, one per row. It worked.
In the end, to standardize the approach to the configuration problem, we now have a library to be located on every machine running each configured program that calls a service that, at startup, loads up an xml that contains the references to other xmls, one per application, that contain the configurations themselves.
Now, it is extensible and made up of fancy reusable abstractions, providers and all, but I still think that, if we one day really happen to reuse part of it, with the time taken to make it up, we can make the needed code from start or copy / past the old code and modify it.
What are your thoughts about it? Can you point out some interesting reference dealing with the problem?
Thanks
Abstraction makes it easier to construct software and understand how it is put together, but it complicates fully understanding certain issues around performance and security, because the abstraction layers introduce certain kinds of complexity.
Torvalds' position is not absurd, but he is an extremist.
Simple answer: programming languages provide data structures and ways to combine them. Use these directly at first, do not abstract. If you find you have representation invariants to maintain that are at a high risk of being broken due to a large number of usage sites possibly outside your control, then consider abstraction.
To implement this, first provide functions and convert the call sites to use them without hiding the representation. Hide the data representation only when you're satisfied your functional representation is sufficient. Make sure at this time to document the invariant being protected.
An "extreme programming" version of this: do not abstract until you have test cases that break your program. If you think the invariant can be breached, write the case that breaks it first.
Here's a similar question: https://stackoverflow.com/questions/1992279/abstraction-in-todays-languages-excited-or-sad.
I agree with #Steve Emmerson - 'Coders at Work' would give you some excellent perspective on this issue.
I have a large codebase that targetted Flash 7, with a lot of AS2 classes. I'm hoping that I'll be able to use Flex for any new projects, but a lot of new stuff in our roadmap is additions to the old code.
The syntax for AS2 and AS3 is generally the same, so I'm starting to wonder how hard it would be to port the current codebase to Flex/AS3. I know all the UI-related stuff would be iffy (currently the UI is generated at runtime with a lot of createEmptyMovieClip() and attachMovie() stuff), but the UI and controller/model stuff is mostly separated.
Has anyone tried porting a large codebase of AS2 code to AS3? How difficult is it? What kinds of pitfalls did you run into? Any recommendations for approaches to doing this kind of project?
Some notable problems I saw when attempting to convert a large number of AS2 classes to AS3:
Package naming
class your.package.YourClass
{
}
becomes
package your.package
{
class YourClass
{
}
}
Imports are required
You must explicitly import any outside classes used -- referring to them by their fully qualified name is no longer enough.
Interface methods can't be labelled 'public'
This makes total sense, but AS2 will let you do it so if you have any they'll need to be removed.
Explicit 'override' keyword
Any functions that override a parent class function must be declared with the override keyword, much like C#. Along the same lines, if you have interfaces that extend other interfaces and redeclare functions, those overrides must be removed (again, as with public, this notation didn't make sense anyway but AS2 let you do it).
All the Flash builtin stuff changed
You alluded to this above, but it's now flash.display.MovieClip instead of just MovieClip, for example. There are a lot of specifics in this category, and I didn't get far enough to find them all, but there's going to be a lot of annoyance here.
Conclusion
I didn't get to work on this conversion to the point of success, but I was able in a matter of hours to write a quick C# tool that handled every aspect of this except the override keyword. Automating the imports can be tricky -- in my case the packages we use all start with a few root-level packages so they're easy to detect.
First off, I hope you're not using eval() in your projects, since there is no equivalent in AS3.
One of the things I would do is go through Adobe's migration guide (which is basically just an itemized list of what has changed) item by item and try to figure out if each item can be changed via a simple search and replace operation (possibly using a regex) or whether it's easier to just manually edit the occurrences to correspond to AS3. Probably in a lot of cases (especially if, as you said, the amount of code to be migrated is quite high) you'll be best off scripting the changes (i.e. using regex search & replace) and manually fixing any border cases where the automated changes have failed.
Be prepared to set some time aside for a bit of debugging and running through some test cases as well.
Also, as others have already mentioned, trying to combine AS2 SWFs with AS3 SWFs is not a good idea and doesn't really even work, so you'll definitely have to migrate all of the code in one project at once.
Here are some additional references for moving from AS2 to AS3:
Grant Skinners Introductory AS3 Workshop slidedeck
http://gskinner.com/talks/as3workshop/
Lee Brimelow : 6 Reasons to learn ActionScript 3
http://www.adobe.com/devnet/actionscript/articles/six_reasons_as3.html
Colin Moock : Essential ActionScript 3 (considered the "bible" for ActionScript developers):
http://www.amazon.com/Essential-ActionScript-3-0/dp/0596526946
mike chambers
mesh#adobe.com
My experience has been that the best way to migrate to AS3 is in two phases - first structurally, and second syntactically.
First, do rounds of refactoring where you stay in AS2, but get as close to AS3 architecture as you can. Naturally this includes moving all your frame scripts and #include scripts into packages and classes, but you can do more subtle things like changing all your event listeners and dispatchers to follow the AS3 flow (using static class properties for event types, and registering by method rather than by object). You'll also want to get rid of all your "built-in" events (such as onEnterFrame), and you'll want to take a close look at nontrivial mouse interaction (such as dragging) and keyboard interaction (such as detecting whether a key is pressed). This phase can be done incrementally.
The second phase is to convert from AS2 to AS3 - changing "_x" to "x", and all the APIs, and so on. This can't be done incrementally, you have to just do as much as you can in one fell swoop and then start fixing all the compile errors. For this reason, the more you can do in the first phase, the more pain you avoid in the second phase.
This process has worked for me on a reasonably large project, but I should note that the first phase requires a solid understanding of how AS3 is structured. If you're new to AS3, then you'll probably need to try building some of the functionality you'll need to be porting. For example, if your legacy code uses dragging and drop targets, you'll want to try implementing that in AS3 to understand how your code will have to change structurally. If you then refactor your AS2 with that in mind, the final syntax changes should go smoothly.
The biggest pitfalls for me were the parts that involved a lot of attaching, duplicating and moving MovieClips, changing their depths, and so on. All that stuff can't really be rearchitected to look like AS3; you have to just mash it all into the newer way of thinking and then start fixing the bugs.
One final note - I really wouldn't worry about stuff like import and override statements, at least not to the point of automating it. If you miss any, it will be caught by the compiler. But if you miss structural problems, you'll have a lot more pain.
Migrating a bigger project like this from as2 will be more than a simple search and replace. The new syntax is fairly similar and simple to adapt (as lilserf mentioned) but if nothing else the fact that as3 is more strict and the new event model will mostly likely cause a lot of problems. You'll probably be better off by more or less rewriting almost everything from scratch, possibly using the old code as a guide.
Migrating from as2 -> as3 in terms of knowledge is fairly simple though. If you know object oriented as2, moving on to as3 won't be a problem at all.
You still don't have to use mxml for your UI unless you specifically want to. Mxml just provides a quick way to build the UI (etc) but if you want to do it yourself with actionscript there's nothing stopping you (this would also probably be easier if you already have that UI in as2 code). Flex (Builder) is just a quick way to do stuff you may not want to do yourself, such as building the UI and binding data but essentially it's just creating a part of the .swf for you -- there's no magic to it ;)