Class member organization - language-agnostic

What is the best way to sort class members?
I'm in conflict with a team member about this. He suggests that we should sort the members alphabetically. I think it's better to organize in a semantic manner: important attributes first, related methods together, etc.
What do you think?

I like semantic. Alphabetical doesn't seem to make a lot of sense to me, cause when you're looking for a member, you rarely know exactly what it's called. Also, if you're using any sort of naming convention (eg: Hungarian), alphabetical is going to lead to grouping by type, which may not be what you want.

Group related class members together. I think this will help other programmers understand your interface more easily when they see it for the first time.
Some also find it helpful to organize accessors and modifiers together in separate sections.

I've studied this exact issue as part of my master's thesis.
An alphabetical organization or organization based on public/private is better for being able to find specific things. However, in some IDEs you can set the outline tool to sort alphabetically and to use special indicators for public/private.
My approach was to group methods based on what members they use: there is often a conceptual connection between methods that use the same fields.
I actually created a visualization from that, which helped to quickly navigate and understand the structure of huge classes.

I never look for a member by going through the code. When I want to jump to a member definition, I either select it from the navigation bar / document outline / class view, or I right-click and select "Jump to definition". You don't need to sort the members if you have a decent IDE. This works very good in Visual Studio and the other IDE I use if needed, KDevelop, supports at least the basics of this.
Anyway, I tend to group members by functionality, i.e. all fields / properties / methods that are part of some specific functionality are together. And since classes shouldn't be too long, this is enough.

This is just my opinion, which I am sure will be unpopular, but the problem with semantic sorting is its subjective. Each person will have a different opinion of what methods should be close together.
Alphabetical has the advantage that it is entirely objective. It also reduces large diffs for small changes, which is common when one coder chooses a different semantic ordering.
Most IDEs have outlines, or hyperlinks to make navigation easier.
EDIT: A clarification- I still sort by public first to private, but alphabetical within the same access level. In fact, I don't do any sorting - I let my IDE resort the file for me when saving.

Are you writing a phone book?
With a semantic approach you can easily show what are the most important methods.
I generally go with Constructor, Destructor first, then important methods followed by getters and setters and eventually misc. methods. Finally, I take a similar approach for internal parts (private methods, attributes...).
Alphabetical order does not convey any useful information about your class. If you really want to see methods sorted alphabetically, you should rely on a function of your IDE.

You can go from semantic to alphabetic by sorting the "methods display" in your IDE.
You can't go (automatically) from alphabetic to semantic.
Hence: semantic.

Assuming you are using a modern IDE, finding the method you want is rarely more than two mouse clicks away, so I am not sure what having a particular way of organizing your methods would get you. I do use stylecop (http://code.msdn.microsoft.com/sourceanalysis) which has me ordering by public / private / method / properties - I have found that to be anal enough.
The only time I ever truely thought this was important is when I wrote a very large jscript program and the editor at the time didn't offer any help in finding functions. Alphabetic organization was very helpful. When alphabatized, it isn't hard to figure out which way in the file you need to go to find a method. Semantic organization would have been completely unhelpful.

At a higher level, I would organize my class this way:
Constructor
Destructor
Private Fields
Properties
Methods/Functions
Then for methods/functions I would break it down again by functionality. e.g. I would put methods that implement an interface into one region, I would put event handlers methods into one region, etc...
RWendi

I guess I'm one of the oddball cases who favors alphabetical listings.
First and foremost, it's been my experience that grouping methods together "semantically" tends to be a time-sink. Now, if we're talking about grouping them by scope/visibility, that's another thing. But then, if the member changes it's scope, you have to sink time into moving the member to keep the code current. I don't want to have to waste time shuffling code around to observe a guideline like that.
I am also not a big fan of regions. When properties and methods are grouped by scope, they tend to shout out for enclosure in a region. But enclosing code in collapsing regions tends to hide badly written code. As long as you don't have to look at it, you won't be bothered to think about refactoring it to make it maintainable.
So, I favor alphabetical organization. It's simple, direct, and to the point. I'm not tempted to enclose groups into regions. And since the IDE makes it easy to leap to a function or property definition anyway, the physical layout of the code is moot. It used to be that you wanted folks to focus on your public members first. Modern IDEs make that largely a pointless argument in favor of scope-based layouts.
But the biggest advantage of alphabetical layouts is this: printed code samples during code reviews. And I use them alot. It makes finding a function or a property a snap. If you've ever had to wade through a lot of code to find a function or a property when things weren't just alphabetically listed, you'll know what I'm talking about.
But, as they say, those are my subjective views on the subject. Your mileage may vary.

Related

Has the word Abstraction other interpretations in computing?

I am quite new in programming and what haunts me about it is not really the coding (well at least not until the present moment!) itself, but some words/concepts that are really important to understand. My doubt is with the word "ABSTRACTION". I have already searched dictionaries and saw some videos of people giving very clear explanations of the word. So, I know that abstraction is when you take into consideration only the things that are important and leave out everything else (putting in very simple and direct language), like for instance, if you are going to change a light bulb, you do not need to know the manufacturer of the light bulb or the light socket. You also do not need to know the materials used to manufacture the light bulb. However, the problem is when you read some texts or listen to people using the word and it does not seem to fit the meaning and then you start to wonder if they misused the word (which I think is very unlikely) or it is because there is another obscure meaning that I have not found yet or maybe it is just because I am too dumb to understand it. Below I put excerpts from articles I was reading and bolded and capitalized the part where the word appears so you guys have a context and understand where my problem is. Thank you.
"A paradigm programming provides and determines the view that the programmer has on the structuring and execution of the programme. For example, in object-oriented programming, programmers MAY ABSTRACT A PROGRAMME AS A COLLECTION OF OBJECTS that interact with each other, while in functional programming, programmers ABSTRACT THE PROGRAMME as a sequence of functions executed in a stacked fashion."
"A tuple space has the function of creating a SHARED MEMORY ABSTRACTION over a distributed system, where everyone can read and write to it."
It's easy to understand if you replace abstract/abstraction with one of its synonyms conceptualize/conceptualization. In your first two examples "abstract a programme" means "think of a programme as"... or "conceptualize a programme as"... When we make an abstraction we forget about some details, and think about that thing in other terms.
Side advice from a fellow beginner:
As someone who started learning computer science independently less than a year ago, I can tell you right now there will be lots of tricky terms like this. Try not to get too caught up in them. Often times if you just keep learning, you'll experience first hand what these terms mean without even realizing it. Bits and pieces will add up. The takeaway from this being, don't let what you don't know slow you down. Sometimes it's ok to keep going and just not know for a while.
These seem to fit the definition you put up earlier. For object oriented programming, the mindset is to consider "objects" as the essential (important) aspect of a program and abstract all other considerations away. Same thing for functional programming where "functions" are the defining aspect abstracting other considerations as secondary.
The tuple space may be a little trickier but if you consider that variations in memory storage models are abstracted away in favour of a higher level concept focusing on a collection of values, then you see what the abstraction relates to.
Abstract
adjective
existing in thought or as an idea but not having a physical or concrete existence.
relating to or denoting art that does not attempt to represent external reality, but rather seeks to achieve its effect using shapes, colours, and textures.
verb
consider something theoretically or separately from (something else).
extract or remove (something).
noun
a summary of the contents of a book, article, or speech.
an abstract work of art.
There you have your answer. Ask 100 people what an abstract painting is, you will get at least 100 answers. Why should programmers behave differently?
Lets see what Oracle has to say about abstract classes:
Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.
Consider using abstract classes if any of these statements apply to your situation:
You want to share code among several closely related classes.
You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
Compare that with the definition of abstract in the above section. I think you get a pretty good idea of abstractness in computer programming.

When to make class and function?

I am a beginner to programming when I start to code I just start writing and solve the problem.
I write whole program in a single main function.
I don't know when to make class, and functions.
What are good books which I read to learn these concepts?
A very general question, so just a few rules of thumb:
code reuse: when you have the same or very similar piece of code in two places, it should be moved to a function
readibility: if a function spans more than a single page on screen, you may want to break it apart into several functions
focus: every class or function should do only one specific task. Everything that is not core to this purpose should be delegated to other classes/functions.
I think the canonical answer here is that you should organize your code so that it's readable and maintainable. With that said, it's also important to consider the cost of organizing your code, and how long you expect your code to live.
More directly in response to your question: functions should be used to replace repetitive or otherwise well contained pieces of code. If you apply the same 10 operations over and over again on the same kinds of elements/data you might want to think about collecting all that information into a more concise and clear function. In general, a function needs well defined inputs and outputs.
Classes, in essence, collect functions and data together. Much like you should use a function to collect operations into concise, well defined collections of operations, classes should organize functions and data relevant to be stored together. That is, if you have a bunch of functions that operate on some things like a steering wheel, brakes, accelerators, etc. you should think about having a Vehicle class to organize these relevant functions and data/objects.
Beyond acting as an organizational element, classes should be used to enable easy reuse and creation of multiple "things" - suppose you wanted a collection of those Vehicles. Classes allow you to tie meaning or at least some semantics to your program.
The point of all this, though, is to make your life and the lives of others easier hen it comes to authoring and maintaining your program. So, by all means, when you need a solution to a problem in less than ten minutes and you think it's a one-time use program, ignore all this if you think it'll let you accomplish what you need to faster. Bear in mind, all this organization, semantics and ease of repetitve operation exists to make it easier to accomplish your objectives.
This is a stylistic and preference question and depending on how formal a place you work at it could be a matter of standards. I follow a couple of rules.
Classes
Sets of related data belong in classes together
Functions to operate on that data should be in the classes together
The classic Example is the Car class functions would be things like Drive and AddGass
Functions
If you are going to use it more then once it should be in a function
Most functions should be no more then one screen of code
Functions Should do one thing well not a bunch of things poorly
there Are a ton of opinions, but over time you must develop your own style.
It's actually very simple nicky!
The purpose of splitting code into methods is simply to allow its reuse. When you create a method you allow your program to invoke it at any time from several places instead of repeating the code again and again.
So every time you write lines and think... 'hey, I might need this functionality again somewhere in my program', then you need to put it in a method.
As for classes, you will try to group similar functionalities together. And try to keep classes short and simple. If you need several classes, you'll also group them in packages and so on.
When I write code, I usually have a pretty good idea what I'll be using again. But often I will start to write a few lines of code and realize that I wrote something quite similar in the past. So I'll find it and put it in a method then the two or more locations can now just invoke it. That is reuse at its best!
You can often use analyzers to find various metrics which will "put a grade" on your reuse and code duplication.
Happy learning!
Have a look at
Procedure, subroutine or function?, Object-oriented programming
An object is actually a discrete
bundle of functions and procedures,
all relating to a particular
real-world concept such as a bank
account holder or hockey player in a
computer game. Other pieces of
software can access the object only by
calling its functions and procedures
that have been allowed to be called by
outsiders.
Basically, you use a function/procedure/method to encapsulate a specific section of code that does a specific job, or for reusibility.
Classes are used to encapsulate/represent an object with possibly its own data, and specific function/procedure/method that makes sense to use with this object.
In some languages classes can be made static, with static function/procedure/method which can then be used as helper function/procedure/method
Just FYI, it'll become more evident when and why functions are useful as you progress to larger projects. I was a bit confused by their use when I first started too, when your entire program is only 20-50 lines of code which follows a very linear path, they don't make much sense. But when you start re-using tidbits of code, it makes sense to throw it in functions. Also makes it easier to read and follow the logic of your program if you only have to read descriptive function names, rather than deciphering what the next 5 lines of code are supposed to do.
I found myself asking this same question, and it led me to this post.
I think that one of the most confusing things about how OOP is explained to beginners is the idea that classes represent exactly what they sound like: classes of things, like Computer, Dog, Car, etc.
This is fine as far as it goes, but it's not strictly true, and the reality is much more abstract. Sometimes, classes don't really represent anything that could be considered a clearly defined abstraction of a group of things. Sometimes, they just organize stuff.
For this reason, I think "class" is really a misnomer, or at least misleading. A more relatable way to think about what a class is might be to simply think of it as a "group" or a "logical grouping."

How to partition a problem into smaller understandable portions?

I'm not sure if it's possible to give general advice on this topic, but please try. It's hard to explain my case because it's too complex to explain. And that's exactly the problem.
I seem to constantly stumble on a situation where I try to design some part of my project, but it has so many things to take into consideration that I'm unable to get a grasp of it.
Are there any general tips or advice on how to look at my system in smaller pieces at a time? How to find smaller portions that could be designed separately on their own?
Create a glossary.
In other words, identify the terms that are meaningful to the project domain — not from the programmer's point of view, but from a user's, who is familiar with the subject matter.
Then define the terms as precisely and discretely as you can. A good definition in this form can serve as a kind of pseudocode.
Since you have not identified even the domain of your problem, I'll choose a random example. In a civilian personnel system, you might have terms like:
billet: a term of service (from start date to end date) at a particular grade and step
employee: a series of billets associated with a particular SSN
grade and step: row and column in the federal general schedule
And so on. This isn't to identify functional units, as it sounds like you are trying to do, but it's a good preparatory step before doing so, so that you can express your functional steps in well-defined terms.
Your key goals are:
High cohesion: Code (methods, fields, classes) within one piece/module/partition should interact intensively; it should make sense for these elements to know about each other. If you find that some of them don't interact much with the rest, they probably belong somwhere else or should form their own partition. If you find code outside interacting intensively with the partition and knowing too much about its inner workings, it probably belongs inside. The typical example is found in OO code written in procedural style, with "dumb" data objects and "manager" code that operates on them but should really be part of the data objects.
Loose coupling: Interaction between pieces/modules/partitions should only happen through narrow, well-defined, well-documented APIs. Try to identify such APIs and see what code is needed to implement them and what code will use them.
It's useful to approach problem decomposition both top-down and bottom-up.
If you're having trouble splitting a big problem into two or more smaller problems, try to think of the smallest possible problems that will need to be solved. Once those are handled, you may start to see ways to combine them into larger problems as you approach your original large problem.
When I find myself copying and pasting chunks of code with minimal adjustments I realize that's a "partition" and then create a class, method, function, or whatever.
Actually, the whole object oriented approach is what it's all about. Try thinking of your application as tangible things that do stuff. Write pseudo code describing what the things are and what they do, I find lots of "partitions" this way.
Here's a try, kind of wild guess.
People usually underestimate how long it will take them to do the work. If your project is large, then most likely you'll need several people to work on it, so you can try planning with that in mind. Now a person can be expected to hold just one area in the head, so you'll need to explain to him exactly what kind of task he's supposed to do.
So I'd say you should try to write a job description that should encompass as much as possible for one person to seriously concentrate on. Repeat, until you have broken your project into parts you wanted to. As a benefit, you're ready to assemble your team. But if you find out the parts are small, maybe you'll still be able to do it yourself.

Creative Terminology

I seem to use bland words such as node, property, children (etc) too often, and I fear that someone else would have difficulty understanding my code simply because the parts' names are vague, common words.
How do you find creative names for classes and components to make them more memorable?
I am particularly having trouble with generic tools which have no real description except their rather generic functional purpose. I would like to know if others have found creative ways to name things rather than simply naming them by their utility, such as AnonymousFunctionWrapperCallerExecutorFactory.
It's hard to answer. I find them just because they seem to 'fit'.
What I do know, however, is that I find it basically impossible to move on writing code unless something is named correctly, and it 'feels' good. If it isn't named right, I find it hard to use, and the code is generally confusing.
I'm not too concerned about something being 'memorable', only 'accurate'.
I have been known to sit around thinking out loud about what to name something. Take your time, and make sure you are really happy with the name. don't be afraid of using common/simple words.
I don't really have an answer, but three things for you to think about.
The late Phil Karlton famously said: "There are only two hard problems in computer science. Cache Invalidation and Naming Things." So, the fact that you are having trouble coming up with good names is entirely normal and even expected.
OTOH, having trouble naming things can also be a sign of bad design. (And yes, I am perfectly aware, that #1 and #2 contradict each other. Or maybe one should think of it more like balancing each other.) E.g., if a thing has too many responsibilities, it is pretty much impossible to come up with a good name. (Witness all the "Service", "Util", "Model" and "Manager" classes in bad OO designs. Here's an example Google Code Search for "ManagerFactoryFactory".)
Also, your names should map to the domain jargon used by subject matter experts. If you can't find a subject matter expert, that's a sign that you are currently worrying about code that you're not supposed to worry about. (Basically, code that implements your core business domain should be implemented and designed well, code in ancillary domains should be implemented and designed so-so, and all other code should not be implemented or designed at all, but bought from a vendor, where what you are buying is their core business domain. [Please interpret "buy" and "vendor" liberally. Community-developed Free Software is just fine.])
Regarding #3 above, you mentioned in another comment that you are currently working on implementing a tree data structure. Unless your company is in the business of selling tree data structures, that is not a part of your core domain. And the reason that you have trouble finding good names could be that you are working outside your core domain. Now, "selling tree data structures" may sound stupid, but there are actually companies that do that. For example, the BCL team inside Microsoft's developer division: they actually sell (well, for certain definitions of "sell", anyway) the .NET framework's Base Class Libraries, which include, among others, tree data structures. But note that for example Microsoft's C++ compiler team actually (literally) buys their STL from a third-party vendor – they figure that their core domain is writing compilers, and they leave the writing of libraries to a company who considers writing STLs their core domain. (And indeed, AFAIK, that company does nothing but write and sell STL implementations. That's their sole product.)
If, however, selling tree data structures is your core domain, then the names you listed are just fine. They are the names that subject matter experts (programmers, in this case) use when talking about the domain of tree data structures.
Using 'metaphors' is a common theme in agile (and pattern) literature.
'Children' (in your question) is an example of a metaphor that is extensively used and for good reasons.
So, I'd encourage the use of metaphors, provided they are applicable and not a stretch of the imagination.
Metaphors are everywhere in computing. From files to bugs to pointers to streams... you can't avoid them.
I believe that for the purpose of standardization and communication, it's good to use a common vocab, like in the same case for design patterns. I have a problem with a programmer who keeps 'inventing' his own terms and I have trouble understanding him. (He kept using the term 'events orchestrating' instead of 'scripting' or 'FCFS process'. Kudos for creativity though!)
Those common vocab describe stuff we are used to. A node is a point, somewhere in a graph, in a tree, or what-not. One way is to be specific to the domain. If we are doing a mapping problem, instead of 'node', we can use 'location'. That helps in a sense, at least for me. So I find there is a need to balance being able to communicate with other programmers, and at the same time keeping the descriptor specific enough to help me remember what it does.
I think node, children, and property are great names. I can already guess the following about your classes, just by their "bland" names:
Node - this class is part of a graph of objects
children - this variable holds a list of nodes belonging to the containing node.
I don't think "node" is either vague or common, and if you're coding a generic data structure, it's probably ok to have generic names! (With that being said, if you are coding up a tree, you could use something like TreeNode to emphasize that the node is part of a tree.) One way you can make the life of developers who will use your API easier is to follow the naming conventions of your platform's built in libraries. If everyone calls a node a node, and an iterator an iterator, it makes life easy.
Names that reflect the purpose of the class, method or property are more memorable than creative ones. Modern IDEs make it easier to use longer names so feel fee to be descriptive. Getting creative won't help as much as getting accurate.
I recommend to pick nouns from a specific application domain. E.g. if you are putting cars in a tree, call the node class Car - the fact that it is also a node should be apparent from the API. Also, don't try to be too generic in your implementation - don't put all attributes of the car into a hashtable named properties, but create separate attributes for make, color, etc.
A lot of languages and coding styles like to use all sorts of descriptive prefixes. In PHP there are no clear types, so this may help greatly. Instead of doing
$isAvailable = true;
try
$bool_isAvailable = true;
It is admittedly a pain, but usually well worth the time.
I also like to use long names to describe things. It may seem strange, but is usually easier to remember, especially when I go back to refactor my code
$leftNode->properties < $leftTreeNode->arrayOfNodeProperties;
And if all else fails. Why not fall back on a solid star wars themed program.
$luke->lightsaber($darth[$ewoks]);
And lastly, in college I named my classes after my professor, and then my class methods all the things I wanted to do to that jerk.
$Kube->canEat($myShorts, $withKetchup);

Can a Sequence Diagram realistically capture your logic in the same depth as code?

I use UML Sequence Diagrams all the time, and am familiar with the UML2 notation.
But I only ever use them to capture the essence of what I intend to do. In other words the diagram always exists at a level of abstraction above the actual code. Every time I use them to try and describe exactly what I intend to do I end up using so much horizontal space and so many alt/loop frames that its not worth the effort.
So it may be possible in theory but has anyone every really used the diagram in this level of detail? If so can you provide an example please?
I have the same problem but when I realize that I am going low-level I re-read this:
You should use sequence diagrams
when you want to look at the behavior
of several objects within a single use
case. Sequence diagrams are good at
showing collaborations among the
objects; they are not so good at
precise definition of the behavior.
If you want to look at the behavior of
a single object across many use cases,
use a state diagram. If you want
to look at behavior across many use
cases or many threads, consider an
activity diagram.
If you want to explore multiple
alternative interactions quickly, you
may be better off with CRC cards,
as that avoids a lot of drawing and
erasing. It’s often handy to have a
CRC card session to explore design
alternatives and then use sequence
diagrams to capture any interactions
that you want to refer to later.
[excerpt from Martin Fowler's UML Distilled book]
It's all relative. The law of diminishing returns always applies when making a diagram. I think it's good to show the interaction between objects (objectA initializes objectB and calls method foo on it). But it's not practical to show the internals of a function. In that regard, a sequence diagram is not practical to capture the logic at the same depth as code. I would argue for intricate logic, you'd want to use a flowchart.
I think there are two issues to consider.
Be concrete
Sequence diagrams are at their best when they are used to convey to a single concrete scenario (of a use case for example).
When you use them to depict more than one scenario, usually to show what happens in every possible path through a use case, they get complicated very quickly.
Since source code is just like a use case in this regard (i.e. a general description instead of a specific one), sequence diagrams aren't a good fit. Imagine expanding x levels of the call graph of some method and showing all that information on a single diagram, including all if & loop conditions..
That's why 'capturing the essence' as you put it, is so important.
Ideally a sequence diagram fits on a single A4/Letter page, anything larger makes the diagram unwieldy. Perhaps as a rule of thumb, limit the number of objects to 6-10 and the number of calls to 10-25.
Focus on communication
Sequence diagrams are meant to highlight communication, not internal processing.
They're very expressive when it comes to specifying the communication that happens (involved parties, asynchronous, synchronous, immediate, delayed, signal, call, etc.) but not when it comes to internal processing (only actions really)
Also, although you can use variables it's far from perfect. The objects at the top are, well, objects. You could consider them as variables (i.e. use their names as variables) but it just isn't very convenient.
For example, try depicting the traversal of a linked list where you need to keep tabs on an element and its predecessor with a sequence diagram. You could use two 'variable' objects called 'current' and 'previous' and add the necessary actions to make current=current.next and previous=current but the result is just awkward.
Personally I have used sequence diagrams only as a description of general interaction between different objects, i.e. as a quick "temporal interaction sketch". When I tried to get more in depth, all quickly started to be confused...
I've found that the best compromise is a "simplified" sequence diagram followed by a clear but in depth description of the logic underneath.
The answer is no - it does capture it better then your source code!
At least in some aspects. Let me elaborate.
You - like the majority of the programmers, including me - think in source code lines. But the software end product - let's call it the System - is much more than that. It only exists in the mind of your team members. In better cases it also exists on paper or in other documented forms.
There are plenty of standard 'views' to describe the System. Like UML Class diagrams, UML activity diagrams etc. Each diagram shows the System from another point of view. You have static views, dynamic views, but in an architectural/software document you don't have to stop there. You can present nonstandard views in your own words, e.g. deployment view, performance view, usability view, company-values view, boss's favourite things view etc.
Each view captures and documents certain properties of the System.
It's very important to realize that the source code is just one view. The most important though because it's needed to generate a computer program. But it doesn't contain every piece of information of your System, nor explicitly nor implicitly. (E.g. the shared data between program modules, what are only connected via offline user activity. No trace in the source). It's just a static view which helps very little to understand your processes, the runtime dynamics of your living-breathing program.
A classic example of the Observer pattern. Especially if it used heavily, you'll hardly understand the System mechanis from the source code. That's why you use Sequence diagrams in that case. It captures the 'dynamic logic' of your system a lot better than your source code.
But if you meant some kind of business logic in great detail, you are better off with plain text/source code/pseudocode etc. You don't have to use UML diagrams just because they are the standard. You can use usecase modeling without drawing usecase diagrams. Always choose the view what's the best for you and for your purpose.
U.M.L. diagrams are guidelines, not strictly rules.
You don't have to make them exactly & detailed as the source code, but, you may try it, if you want it.
Sometimes, its possible to do it, sometimes, its not possible, because of the detail or complexity of systems, or don't have the time or details to do it.
Cheers.
P.D.
Any cheese-burguer or tuna-fish-burguer for the cat ?