Jump to content

shoneill

Members
  • Posts

    867
  • Joined

  • Last visited

  • Days Won

    26

Everything posted by shoneill

  1. You are still debating it. As far as I can see, everyone else is happy with the answers given.
  2. I'll check them out, especially the LVOOP assistant. Looks promising. Open source is way cool. I am looking to script accessors for a RT framweork I'm working on. We have a fixed-width input pipe and output pipe for registering for changes made within the timed loop of a RT system. These pipes are 64-bit in width so I need to be able to create accessors for each and every scalar in the private cluster (unbundle.unbundle.arrayindex.unbundle.scalar for example). In addition to this I need to create an "index" enum for each class for the actual values so that I can auto-create a polymorphic VI for host-to-RT communications for these parameters. In addition (it's a multi-step process), I need to script the return channel which takes a parameter index as an input and monitors for changes and sends back changed values (handled by a delegate with a U64 interface). All of this work is highly repetitive and extremely boring and error-prone to do manually. Each small modification becomes tedious to the extent that I simply don't want to make changes any more. I'm currently designing a schame to auto-create the entire host-RT-Host pathway for strictly-typed parameter storage on the RT. The actual logic of what each module is supposed to actually DO is implemented manually (if only that could be automated also!! ). At the moment we have a single SGL array as a parameter storage with an associated "God" enum. Obviously this makes encapsulation almost impossible and links each and every module we have to the entirety of all parameters we have in any module we have ever implemented. Not optimal. I am aiming for properly encapsulated objects with standardised in and out to the RT loop (implemented in the parent class). If I ever get to actually implement it, I'll give feedback or maybe even contribute the accessor code if my employer allows it.
  3. Hmm, stuck with LV 2012 SP1 unfortunately..... I wonder if they still work if I save for previous....?
  4. Warning: I'm not a scripting veteran. I know my way around vanilla Vi Server pretty well, but Scripting is still (kind of) new for me. I am looking into the possibility of scripting a different kind of accessor for a "framework" (I use the term loosely) I am working on. What I'm really not sure about is whether I should try to leverage the VIs present in the "\Framework\LVClassLibrary\" directory. Most are password protected and I'm unsure as to whether the work will be easier wrangling the existing code to do what I want or just doing it from scratch.... I don't need IDE integration, just code which can be run when needed.
  5. Hmm, you sound like my wife when she's fed up with a discussion and just can't be bothered any more.
  6. I am and I am. I am referring to both the composite pattern AND composition, both terms being used correctly. The idea of a Frame containing a List class internally and handling this WITHIN the borders of it's encapsulation : not exposed) is composition in the classical sense, one class containing another in order to implement some aspect of the functionality in a sub-class. The fact that this Frame incorporating a List (which accepts Frames as items) is also a Frame object is the Composite Pattern. The item representing multiple instances of a defined object type is transparently exchangeable with an item representing a single instance of the same object type. As to your image. Hmm, I see no evidence of composition here at all. There's only a single object wire, no observable sub-objects. I think you're simply showing inheritance at work here which is most definitely NOT composition (in the generally accepted sense). If you're defining some super-literal definition of composition then you need to make that clear but the standard definition of composition is that a class "car" can have four "wheels". If each "wheel" is itself an object (different inheritance hierarchy than "car") then by giving an object "car" four member classes of type "wheel" allows the actual implementation of "wheel" to vary independently of "car" and also allows run-time substitution, something which Inheritance cannot. It would theoretically be possible to replace four standard "wheels" with jet propulsion units without having to modify "car" at all. Only the Interface for "wheel" needs to be compatibly with the implemented functionality. In your case, "Truck" IS A "Vehicle". This is Inheritance. In my example "car" HAS "wheel"s, this is composition. It's identity versus possession. Two very different approaches to essentially different problems. Good, then let's move on. Well I think a "What if" scenario when the problem has been defined as variable, i.e. not knowing which requirements are going to come next as was expressed in the original post, is an important thing to consider. The aspect of Interface bloat is easy to understand. If I take one of your Frame objects I can call each and every public method of your List class on my Frame. Even if they're not required. Even if they're not on the Menu but they are there and any tool which auto-populates a menu to show accessible functions will be bloated. The methods are there and supported. I'm referring to the actual Class interface, not whatever is shown to (or hidden from) the user. Another topic: So which object type does your List contain? Some generic datatype? So I could feasibly call Frame.Add Item and pass it an Action and similarly call Action.Add Item and pass it a Frame? Or do you have some way of hiding these methods of your List after inheritance? The only thing I can think of is "Community" scope but IIRC this is bugged to hell. The bolded term is simply wrong. Flat out, no discussion. I can call ANY public methods you have defined for your List on any Frame object. It will call the Parent implementation (I think this is what you're getting at) but I can do this, it's legal and there's nothing to stop me doing it. Depending on how you present your VIs to the end-user you may have any subset of the interface listed there, but doing so does NOT remove them from the interface. The methods are there, they can be called and they do something. You even say later that "I will just use the base class VIs.". Exactly. But why have those methods available when they're not always needed? That's interface bloat right there. Parent methods are just as much a part of an object's interface as it's own. This is because the child IS A parent (inheritance). Making a shorter list, looking only at that level of the inheritance hierarchy or just plain pretending the methods do not exist for that object does not mean that the methods are not there. So for Frames which are only a single item and will only ever BE a single item, the List methods are bloat. Taking things further, if (beyond Frame initialisation) you never need to deal directly with the List functionality, having them there is bloat, exposed methods which at best confuse and at worst destroy any encapsulated functionality you might have implemented. What if I choose to Add a new item to a List half way through execution so that the currently executed step is suddenly a different one? Why have methods available which are unneccessary? Here we have things backwards. Inheritance (inheriting from List) fixes us into the fact that each and every Frame is a List for ever and ever, immutable. Using Composition, those Frames which need to be a List can manage their list privately, knowing what to do when told to execute. If one wants to have a Collection, one wants to have a State machine, one wants to have a Client-Server connection, if one wants to pick random items from disk or whatever then each and every Frame is free to implement the grouping methodology it requires and handle it appropriately when told to execute. That fixes you into nothing. It frees you to do whatever you need whenever you need. You can access the EXACT same functionality as with Inheritance but the List methods will NOT be callable on Frame. When a Frame with an internal List is told to execute, it will call the appropriate methods on it's List without the caller needing to know or see any of it. THIS is the composite pattern combined with composition. Allowing you to treat a List of Frames as a Frame as the same type of object is the composite pattern. Using an internal List to give extra functionality and choosing which methods (if any) are exposed is composition. By doing so you also expose "Add" functions which accept ONLY Frames which prevents a cross-communication with other object types, something which the normal "List" methods cannot do. Shane
  7. Junction points like this create all kinds of problems, even for MS programs. I remember trying to back up a drive with a sub-folder pointing back to the root folder. MSBackup did NOT recognise this and tried to back up an infinite amount of data. I don't think it's finished yet.
  8. Is what what? Is the discussion Inheritance versus Composition? Yup. It is.
  9. So this is meant as a continuation of a discussion of relative merits of inheritance versus composition between myself and Shaun R to be found HERE.
  10. I also made no claim whatsoever that you were using any kind of pattern. I was comparing with a pattern. The obvious drawback of your idea is the static linkage to the List class. While the List class is most likely a lovely piece of work, if you want to implement a Frame as a different kind of grouping (don't ask me, I'm just theorizing, perhaps a conditional looping of individual elements until a condition is met) then either you build that into your List class or you implement it separately in your child class. By moving the List functionality into the child class, each child is free to implement whatever method of aggregation they see fit without requiring interface bloat. Each item implements whatever it needs. You could have several different flavours of collections (lists) which do things different based on some corner cases. You also cannot hide the interface to the List aspect of your objects which is something you CAN do when the child implements it (in fact it almost requires it). Depending on your taste you might prefer one solution over the other. If I want to do something with a Frame, why does the interface for that object insist on telling me it's a list when that's not something I need or want to be confronted with. It creates noise in the interface which is seldom a good thing. So imagine a "collection" which internally manages a List (your class). When dealing with a collection (strictly typed child of Frame), you have the exposed methods for the list, when working with Frames (when you don't need to know whether it's a list or not) you have a much cleaner interface. By moving your same List class up two levels of the hierarchy you gain a lot of flexibility and remove static linkage to the functionality of your list. What are the downsides you see with this approach? The only downside I see is the creation of some proxy VIs which, depending on your taste might be enough to sway you. I don't want to weigh this relatively focussed topic down with previous discussions which may or may not be applicable and to which I was not a party. I also don't mean to be nasty but your usage of both has no relevance to the discussion. That's fine by me if you think it requires it.
  11. Almost. There's one major difference you're missing out on here Shaun. When designing the "list" according to the Composite Pattern the List itself is an instance of the objects it contains. You cannot do that with your List class. If I make a List of "Frame", the List is a List, not a Frame. In the Composite pattern, the List is also a Frame, allowing it to be placed in another List and so on recursively. It's the interchangeability of the List and the object it contains which is the essential part of the Composite pattern. In BobDobbs code shown above the user can program with a Frame Collection or Frame interchangeably. In your case, all of the objects are inheriting from the List class so you're going about things the opposite way. By making EVERYTHING a List you also have a single interface but the downside is that when you DO want to have a single object rather than a collection or list, you still have a list (and associated now non-functioning interface elements). This is a variant of the problem where the "single interface" is the sum of all possible implementable interfaces within the problem space. Why, if the user program doesn't need to know, is it presented with a List Interface for the objects being processed?
  12. The composite pattern is not really what you need here since you admit yourself that the different levels of the hierarchy require different interfaces. What you need is simple object composition (a grouping of objects to increase functionality) which is NOT the same as the Composite Pattern. I think your different object hierarchies are relatively clear. Your confusion arises perhaps from the false expectation that all levels of your object composition need to share interfaces. So a Group is a single step for ALL DUTs, right? Group 0 is Initialise essentially, Group 1 is Step 1, Group 2 is Step 2? This sounds like it may actually be a candidate for the Composite Pattern. Why not implement a Group as a Composite of Step with the same interface? This will allow you to treat groups and steps transparently. I don't know if that functionality would actually aid your development, I'm too far away to be able to judge that but it would allow you to have "Virtual DUTs" which are actually comprised of several individual DUTs. Your functions are a completely different beast, as are your Actions. Again you could theoretically define Functions and Actions so that the Composite Pattern could apply. Again this would allow the generation of an Action which actually contains several other actions. Part 1: Base Class : Step Child Class : Group (contains 1..N Steps) A Step is an object which represents a stage of your testing procedure for a single DUT. A group represents the same thing but for 1..N DUTs. A group may contain other groups. A group and a Step can be used interchangeably within the program. The interface you would code to is that of the Step (Parent class). Part 2: Base Class : Action Child Class : Function (contains 1..N Actions) An Action is a single action (Set Voltage, Raise Alarm, whatever). A Function is also an action but contains 1..N other Actions. A Function can also contain other Functions (Hierarchical definition of test procedures). So I could imagine (without in-depth knowledge of EXACTLY what you're trying to do) that you could use a combination of Object Composition (Action&Function or Step&Group) and the Composite Pattern (Step contains 1..N Actions) to achieve what you want.
  13. This post will not directly address your specific problem but rather concentrates on clearing up some confusion which cost me personally many headaches and which I have not seen addressed before (I never actually looked that hard). I have had lots of trouble finding the link between theoretical discussions on the Composite Pattern and actual implementations (Composition) in LabVIEW for years. A short time ago, the penny dropped (figuratively). The Composite Pattern refers to a single hierarchy tree where you have a number of child classes. You define one class of this hierarchy Y (for example a single step above the base class X) to actually contain an array of the base class. It is simply an object which allows a group of objects of base Type X to be operated on as if the object containing them all was also a simple Object X. You can therefore easily picture a hierarchy of objects by simply having an array of Objects X where some of them are actually Object Y containing other objects, some of which again may be X and some Y and so on. By abstracting the "many X" into Y (which due to inheritance is also X) you have implemented the Composite Pattern. The Composite Pattern (as the GoF describe) is certainly not what NI propagates as Composition (a solution where many objects of DIFFERENT hierarchies are collated into a single object in order to implement different functionalities). The key sentences in the links you provide regarding the Composite Pattern are: Implementing the composite pattern lets clients treat individual objects and compositions uniformly (Y containing two or more X is itself an object of Type X) and There are times when a program needs to manipulate a tree data structure and it is necessary to treat both Branches as well as Leaf Nodes uniformly (Whatever operations you can perform on X must also be doable with Y - they have the SAME interface) Composite Pattern != Composition Composition is a general term and can be used for defining a class A which contains classes B,C and D all of which have different interfaces and hierarchy trees. This is a grouping, a Composite object. The word Composite here does NOT infer application of the Composite Pattern. The Composite Pattern is a small sub-set of possible object groupings or Compositions because it has much different requirements and is much more restrictive. WAY back in college, I had a really hard time understanding inheritance in OOP. I couldn't figure out how the mapping from child to parent could possibly be implemented in a way that was stable and robust. It was only after LVOOP came to LabVIEW that the proverbial penny dropped (I'm not wealthy, the time it takes for pennys to drop for me means I'm actually really really poor). Inheritance is an EDIT-TIME declaration, not a RUN-TIME declaration. To anyone who understands OOP this is a no-brainer. But my brain interpreted it differently and because nobody cared to make this distinction when teaching it to us at college I lost out on nearly 20 years of understanding OOP.
  14. You can do this better with the blending bin and blending mode. Your solution is always running after the 3D control to patch things up whereas a solution with the correct blending bin and blending mode will be automatic. I recommend you re-visit the other methods posted as it's a far more robust solution.
  15. Blackadder references always welcome. I need to start my next suggestion on improving our code with "I have a plan....."
  16. Create the background image you require (with pattern) and write it to Plot Image.Back (or middle, depending on the effects you require. Then set the graph to fill to infinity with a white fill colour (or whatever colour your non-filled space should be).
  17. I meant managing in the sense of "how does your program know when to use which class?". Given the absence of a factory pattern, you will NEED to have this array maintained statically. These are essentially the two options available. One is static, the other is dynamic.
  18. Did you use Billboarding to solve the problem? What was the solution exactly?
  19. Well if you don't have a plug-in architecture working yet (which would be one way to solve his problem) you need to have your classes included statically somewhere in your code. Why not make an array of your implemented classes and simply call an "ID" method on them returning their IDs which may or may not be different from their names on disk. How are you managing all of your different classes at the moment within your program?
  20. Why exactly does your class need to know about existing ancestors at run-time? It sounds like a design problem, not a code problem.
  21. I think we're talking about edit-time information, not run-time, right? Parents knowing about their children at run-time sounds wrong.
  22. The only way I can think of is to add a (public) boolean element to the Child to signal whether it should execute it's version of the overridden function as opposed to simply passing it on to the "parent". It's dirty and feels wrong but might be a way out of your predicament. I mean, which is MORE wrong, this construct or simply duplicating code?
  23. Oh good lord I hope you're wrong. I could always start training to be a carpenter. I always wanted to be a carpenter.
  24. Seriously? Wow. We were seeing some weird network slowdowns recently. Maybe this is the reason. We have Kaspersky, but maybe it's a similar crap slowing out network.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.