I notice a pattern, when i did C++ and backend programming (in C# or any language) all my classes are neat and tidy. Recently i notice all my code are in a class and i literally have >50functions in it. I now realize its because i am doing UI. If i were to separate them by pages or forms/dialogs i would have a LOT MORE files, more lines of code and longer line of code. If i separate them i get the same problem (more files, lines, longer lines). Obviously the less lines the better (less code = less to debug, change or break during maintenance).
This specific project is 5k lines with 2k being from the web or libraries. All my .cs files are <1k lines. Is this acceptable even though i have 50+functions in a single class?
Bonus: I notice most of these functions are called only once. and putting certain code blocks (such as one function make two calls to the db) as their own function makes it harder for me to edit since they are divide between files and this balloon function count. So, i kind of dont know what to do. Do i create more classes to reduce function count (per class, it will increase function calls overall and already most are only called once)? How do i design classes doing frontend/UI?
I often find that my UI stuff grows considerably more complex than pure classes. Think about it - your "pure" classes are (for the most part) essentially machine instructions, and can (or should be able to) assume pure, pre-validated inputs and outputs, and do not have to accomodate the vagaries of human behavior.
A UI, on the other hand, is subject to all of human fallacy - and needs to respond in human-predictable ways, in a manner which humans can understand. THIS is where the complexity comes in.
Consider - in your nice, crisply defined classes, in which each function performs a fixed action against a known type of input, there is not alot of random BS to anticipate or handle.
A UI must be receptive to all manner of improper, inconsistent, or unanticipated input and actions by the user. While we, as designers, can pre-think some of this (and even minimize it with things like Combo-boxes and Command Buttons, a). all of that requires additional back-side code, and b) all of these things can then interact in different ways as well.
In our classes, WE decide how certain methods/functions and the like interact and affect one another. on the UI, we can do our best to point the user in the right direction, but there is still the random element. What if the user pushes the button before selecting an item from the list? There are several different ways to handle that scenario, all of which require another line (or ten, or 100) of code to handle gracefully.
Lastly, the more complex the project, the more complex the UI is likely to be, and the more of this must go on.
Managing the actions of the machine, given inputs and outpus we as programmers explicitly define, is EASY compared to predicting, managing, and handling the random quirks imposed on our stuff by a user. If only they would pay attention, right?
Anyway, I believe all of THAT is why code for a UI becomes greater, and more complex. As for how to break it out in a maintanable manner, the guys above covered it. Abstract the two. I design a form. I define the menas for the user to input data, and/or indicate what they want to happen next. Then I define the manner in which that form can communicate those things with my crisp, clean back end classes. Then I provide validation mechanisms, and the means to help control the user in navigating it all (e.g. the button is not enabled until the user selects an item from the list . . .).
Complex.
Related
Hey i have question with a real word example.
Its related to my two other, but not really answered questions here:
https://softwareengineering.stackexchange.com/questions/423392/no-trivial-god-class-refactoring
and
https://softwareengineering.stackexchange.com/questions/425113/different-composition-techniques-from-the-perspective-of-the-client
Let's say we have a switch with the methods switchOn(), switchOff().
The switch(es) are included in some other structure, for example a switch-bag, from where i can pull out the switches.
This can be seen as a ready system.
Now i want to introduce the possibility of switching these switches on after a certain time automatically: A time switch
The time switch ueses now the "normal" switch.
The normal switch doesn't have to know something about the time switch.
So but now the client can pull out the normal switch from the switch-bag and now he want also to get to the time-switch related to these normal switch, maybe to configure a new time.
And this is my question, how can the client get to the time-switch?
There are a few possibilites:
I refactor the normal switch class to a third-class where the
normal-switch and the time switch lives bundled in it. But for this,
i break some other client code which still uses the normal switch, but
get now from the switch bag a "Combinator"-Class/Object out of it.
I don't change anything of the normal switch class. The client if he
wants to get access to the time switch have to ask a Map which time switch is related to it. (I think this approach is classical a
relation-programming style like a sql relationship database and its
not anymore real object-oriented style)
I extend the normal switch: Here i also have different options:
I change it to a big facade, which delegates the calls to the
normal-switch and time switch (its similar to my first solution with
the combinator, but here with an facade don't breaking some existing
client code)
i extend the normal switch letting the existing normal switch code
untouched and introduce a component holder. Into this component
holder i inject the time switch. So i have these methods there:
switchOn(); switchOff(); getComponent("timeSwitch"). But these
approach feels like a entity-component system
(https://medium.com/ingeniouslysimple/entities-components-and-systems-89c31464240d)
but is that still object oriented programming?
i think the last solution is the best one, because its the most flexible.
But what do you think which approach is the best, maybe some approach i didnt mentionend here?
Edit:
One more thing you must to know here: The time switch is one extension of the normal switch. One of many. So i want to add of course different more things XYZ switches/behavior extensions to the normal switch
Update: answer totally re-written (so the first comment won't make sense any more).
To summarize:
SwitchBag provides access to a list/collection of switches.
Switches have methods like on() and off().
You want to extend the behavior of at least some switches can do stuff themselves based on the passing of time, etc.
Clients (e.g. the UI) need access to the switches classes.
You make comments like
and now he want also to get to the time-switch related to these normal
switch
which suggests you have one of each, etc - which is way more complex than it needs to be. Here's some options to consider - some of your ones were heading in the right direction.
Option A: One type of switch
This assumes that the solutions design & functional drivers don't push you to create huge and overly complex switches. For example, let's say some of your switches need to do something after a period of time, others don't. Such a difference is not necessarily reason enough to make a separate class.
E.g. you can implement a time related property like Duration, if Duration > 0 then time logic applies and gets executed; < 0 means no time logic is applied (normal switch behavior).
I'm assuming here that any client can get access to any switch via the SwitchBag.
This is the option I would start with because it's simple and still allows plenty of functional scope.
Option B: Smart SwitchBag, Dumb Swithes
I'm not sure if I like the smell of this option because it tightly-couples the SwitchBag and Switch classes, but it could be useful.
Keep the switch class as dumb as possible.
SwitchBag knows about switches, it controls access to them (and their properties/methods). Use class structure and access modifiers to control this.
SwitchBag can decide to do stuff to switches based on time if it wants to.
In this approach, switches will be mostly properties, and be a little bit like the SwitchBags personal database, only it's fluid based on objects at runtime.
Note - you can still have events on the switches.
Option C: Interfaces
Create a basic switch. Create interfaces that are designed to be applied to switch class(es), that extend them as necessary. E.g.:
interface ITimeBehaviour{
double InitialDuration
double TimeUntilChange
}
At runtime you can see if a given switch instance implements the interface and respond accordingly. But whilst you can do this I'm not sure why you would, based on what I understand of your problem.
Other Thoughts
Your comments suggest you've thought a lot about OO concepts like inheritance and methods, but I saw no evidence you've considered asynchronous programming techniques - such as using events. If you know nothing about this then do some research and get up to speed, then see if that offers an elegant solution to your problem.
Design Patterns - are you familiar with the idea of design patterns? If you aren't, be sure to research that too. There's heaps of good content online, which describe patterns that might already solve the fundamentals of your problem.
i want to know what is the difference between box and module in programming
i have been asked this question
and somehow i am confuse now
reading on web and document that what is box in programming
and i found below link
https://www.nbs-system.com/en/blog/black-box-grey-box-white-box-testing-what-differences/
if the box is the top link and similar link then the box is the testing of the
program and module is the proram
The "box" is just a common word from an object you know from real world. It servers as an analogy with code put together to form some kind of software component. This is because it's internal parts are so related to each other, on responsabilities and communication, on internal data use, on overall goal, that it makes sense to group them together. We name it module and many times this maps to a source file (but doesn't have to), but the same grouping concept applies to classes, packages (usually modules/classes grouped together), libraries or even complete applications or systems.
What the box term mostly refers to is the fact that there is a frontier between what is inside the box and actors interacting with it from the outside (users or other systems).
The box has to present a public interface to external world, in order to become usable, or useful. This has to be documented, otherwise you don't know how to use it. When you use it based on this info only to achieve your goals, not knowing anything about the internals, we say you are using a "black box".
This has lots of advantages because it can make the box a powerful abstraction that is simple to use, wrapping a possible complex implementation inside. It encapsulates things and hides them from the user.
If by any means, you as an external actor use the box in some way, because you know how something is done inside, you are violating this encapsulation principle. You are probably entering in "grey box" usage mode. This is dangerous because if the box is changed your assumptions (and code) may fail.
When using it as a "white box" you really know entirely how it is made inside so you can make very well informed decisions in your code, but now the box code can't be touched really. So there goes the abstraction.
When coding, you mostly want to code against black boxes, and want also to build your own black boxes, for abstraction, cohesion, and modularity reasons.
Grey and white boxes make most sense when it comes the time (hopefully from the start) to test the code you have written. Here you still want to test your system as a black box, but want also to use white box testing, because you want both observable behaviour and internal detailed behaviour to be correct.
Grey testing in particular applies probably when you are testing code you have written that uses other modules or libraries you have not, and generally do not want to test (code of others was tested already), but still you have some knowledge about its internals and you make additional tests to cover your code, that explore this knowledge.
Edit:
So unless they want you to distinguish the module as the code that's inside, and the box as the wrapping public interface for the module, there's no difference actually.
I have a busy set of routines to validate or download the current client application. It starts with a Windows desktop shortcut that invokes a .WSF file. This calls on several .VBS files, an .INI for settings, and potentially a .BAT file. Some of these script documents have internal functions. The final phase opens a Microsoft Access database, which entails an AutoExec macro, which kicks off some VBA, including a form which has a load routine of its own in VBA.
None of this detail is specifically important (so please don't add a VBA tag, OR criticize my precious complexity). The point is I have a variety of tools and containers and they may be functionally nested.
I need better techniques for parsing that in a flow chart. Currently I rely on any or all of the following:
a distinct color
a big box that encloses a routine
the classic 'transfer of control' symbol
perhaps an explanatory call-out
Shouldn't I increase my flow charting vocabulary? Tutorials explain the square, the diamond, the circle, and just about nothing more. Surely FC can help me deal with these sorts of things:
The plethora of script types lets me answer different needs, and I want to indicate tool/language.
A sub-routine could result in an abort of the overall task, or an error, and I want to show the handling of that by (or consequences for) higher-level "enclosing" routines.
I want to distinguish "internal" sub-routines from ones in a different script file.
Concurrent script processing could become critical, so I want to note that.
The .INI file lets me provide all routines with persistent values. How is that charted?
A function may have an argument(s) and a return value/reference ... I don't know how to effectively cite even that.
Please provide guidance or point me to a extra-helpful resource. If you recommend an analysis tool set (like UML, which I haven't gotten the hang of yet), please also tell me where I can find a good introduction.
I am not interested in software. Please consider this a white board exercise.
Discussion of the question suggests flowcharts are not useful or accurate.
Accuracy depends on how the flow charts are constructed. If they are constructed manually, they are like any other manually built document and will be out of date almost instantly; that makes hand-constructed flowcharts really useless, which is why people tend to like looking at the code.
[The rest of this response violate's the OPs requirement of "not interested in software (to produce flowcharts)" because I think that's the only way to get them in some kind of useful form.]
If the flowcharts are derived from the code by an an appropriate language-accurate analysis tool, they will be accurate. See examples at http://www.semanticdesigns.com/Products/DMS/FlowAnalysis.html These examples are semantically precise although the pages there don't provide the exact semantics, but that's just a documetation detail.
It is hard to find such tools :-} especially if you want flowcharts that span multiple languages, and multiple "execution paradigms" (OP wants his INI files included; they are some kind of implied assignment statements, and I'm pretty sure he'd want to model SQL actions which don't flowchart usefully because they tend to be pure computation over tables).
It is also unclear that such flowcharts are useful. The examples at the page I provided should be semiconvincing; if you take into account all the microscopic details (e.g., the possiblity of an ABORT control flow arc emanating from every subroutine call [because each call may throw an exception]) these diagrams get horrendously big, fast. The fact that the diagrams are space-consuming (boxes, diamonds, lines, lots of whitespace) aggravates this pretty badly. Once they get big, you literally get lost in space following the arcs. Again, a good reason for people to avoid flowcharts for entire systems. (The other reason people like text languages is they can in fact be pretty dense; you can get a lot on a page with a succinct language, and wait'll you see APL :)
They might be of marginal help in individual functions, if the function has complex logic.
I think it unlikely that you are going to get language accurate analyzers that produce flowcharts for all the languages you want, that such anlayzers can compose their flowcharts nicely (you want JavaScript invoking C# running SQL ...?)
What you might hope for is a compromise solution: display the code with various hyper links to the other artifacts referenced. You still need the ability to produce such hyperlinked code (see http://www.semanticdesigns.com/Products/Formatters/JavaBrowser.html for one way this might work), but you also need hyperlinks across the language boundaries.
I know of no tools that presently do that. And I doubt you have the interest or willpower to build such tools on your own.
What can I do to structure my application so the code stays manageable as it gets bigger? I am building an application that will be in a certain state which will change depending on how the user interacts with it, and there will be many different states the application can be in. I've tried looking for tutorials/resources, but what I find only covers an application with a couple of modes, whereas mine will have lots of different behaviors.
For instance, you can click on object type A or B, so there can be a different behavior for each. If you hold the mouse down and try to drag one, they will behave differently too. But if you weren't holding your mouse down, that means it's not a drag. It's knowing what mode to move into when X event happens while you're in Y state that has me confused because I don't want to have a massive switch statement that handles everything.
It's not clear what exactly you mean by 'different modes.'
Lots of people spend a ton of time dreaming up abstract structures, behavioral, and organizational patterns for code. Another term for these concepts is design patterns. Aside from cleanly formatting and documenting your code, these concepts help you keep your code logically and functionally clean and operational.
They are well-known and mainstream because they have been proven to work in many implementations; you won't use all of them on every project, but you will probably start using combinations/variations of them if you want to scale. My advice would be to familiarize yourself with these and then reflect on where a particular pattern would work well in your application/state machine.
EDIT: Response to your edits.
For GUI development, in principle, you want to achieve separation of presentation code, behavior code, and state code. Some patterns lend themselves naturally to this end, for example the Model-View-Controller (MVC) pattern.
I'm working on a project with a contractor we hired to do some VB.Net programming. I used to program for this project, but I have more recently become primarily the project manager so I can work on other issues I have. His method of programming differs greatly from what I was taught in school. The only time he uses classes is basically in the form of a sort of dataset (not an actual dataset, as I learned how to use in school). As an example, there's the cEmployee class, where he creates a class for an Employee, and in that he defines all the fields an employee has.
All functions are put in Modules. So if he has several functions to populate a combo box, they all go in the combo box module. My understanding on this though is that when the program is run, the modules are treated as global functions and included regardless of whether or not they are actually used on a form. To me this sounds like it would increase the resource requirements to run such a program, since the large amount of module code has to be included for every form.
The way I learned was to put functions with specific purposes in namespaces and classes, then import the appropriate namespace and class when needed. Then only the necessary code to run a form is loaded, and the extra code for functions that are not needed isn't loaded until imported on a form. I never used modules myself, but I can see their utility, I just think he is severely mis-using modules in this case. Am I correct?
From your description of the situation, it appears your programmer has VB6 backgrounds and has not completely migrated to VB.NET; he does not use OOP if he can avoid it.
To answer your questions, his code style would make a hell for a pure VB.NET OOP programmer. However, it wouldn't cause much overhead.
A VB module does basically define "global" functions - if this were C# it'd be a static class with static functions. However, this won't make any difference to the resource requirements of your application: all methods are defined once, no matter where they're called from, and being in a module or a class doesn't change that. If you have 20 forms that all use the combobox code, the combobox code still only exists once - it's not duplicated 20 times, either in the application or in memory when you run.
It does sound like your contractor may have some unusual coding styles if he's using a lot of module code, but without more concrete examples it's hard to say for sure.
It's hard to answer without seeing the code. From the information in your question it seemed that your contractor was writing procedural structured code, which is old-fashioned, but not necessarily a huge problem, although many programmers who are used to OO won't enjoy looking at the code.
From your last comment on Dan's answer it sounds like he is writing a module for each functional area, with routines that can act on any object. The routines accept Object or Variant arguments, detect the type of object passed with case/if statements, then branch to the appropriate code for that object. Is that right? That is quite eccentric and hard to maintain. Usually, a better way is to declare interfaces for the functional areas, and have the classes implement the interfaces.
I've seen code like this from self-taught programmers. To be fair to them, they are bright people who were stumbling towards inventing OO programming from scratch! It can be a slow process though, and it's better to learn about other people's conclusions first! I might recommend a course on OO programming, or if he is a reader a book like Head First Design Patterns or even Code Complete 2, which has some good chapters on design. If you can get him hooked on Code Complete, that would be a good thing.
By traditional OOP approach, we learned at school that class methods are bound to their objects and while modules are used to carry global functions, and I guess your project partner wants to use those functions independently, irrelevant of associated objects. If those methods are processing only on Combo boxes, than they must be encapsulated with dedicated class for the purpose.
Well, as you said that loading all the functions at the same time will increase overhead, so here's how things will work; since, execution deals with functions only when they are needed, & not when execution starts, so no matter you include hundreds of functions with your code, compiler will execute them only when you call it, (until then compiler doesn't knows what you've wrote in it) along with allocating variables within the functions. But, this is not the case if variables are shared by all the functions, as when they are shared by all of the functions, they are global for them, and hence, they will sit in memory since from the beginning.