Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
So let's say I am using this code. Your typical constructor has the same parameters as the fields within the square brackets, but this one doesn't --something more common than I expected btw.
public class PetOwner
{
private readonly string OwnerName;
private readonly List<PetAnimal> Pets;
public PetOwner(string name)
{
OwnerName = name;
Pets = new List<PetAnimal>();
}
}
Why shouldn't I create the constructor with both fields as the parameter which is the most typical thing and not only the owner's name?
Same here:
public class PetOwner
{
private readonly string OwnerName;
public static int ownersCounter;
public PetOwner(string name)
{
OwnerName = name;
ownersCounter++;
}
}
Why and when to use?
Example One
In your first example the OwnerName is taken in as a argument, while Pets is intialized with a instance. This is required to actually use the field in any meaningfull way. And as a readonly, it has to happen here.
It would be entirely possible to also hand in the Pet collection with the constructor call. The designer choose not to, but setting/initalizing it from a existing collection or with a array initializer is not difficulty after creation.
My best guess why Collections are generally not assigned values in the Constructors, is the danger of Exceptions. The operation of filling or expanding Collections is very prone to OOM Exceptions. While the danger also exists with any new operation, it is orders of magnitude more likely with any actuall array write opereation.
Example two
In your second example the OwnerName is taken in as a argument, while a static variable ownersCounter is increased.
Sharing data via a static field is the most common beginners mistake with statics you can do. Outside of learning examples, you should avoid it like the plague. If the field was constant or readonly, the static nature would not mater. But this one is writeable.
What if you later need a programm with 2 different owner counts? (say vertebrates and invertebrates). Your class can not do that. It does not scale.
If somebody wants to have that kind of counting, it is generally his job to track it. This is a thing only code using your class can reliably do. It is the same reason that among all the Concurrent Collections, we do not have a Concurrent List. The index is by nature prone to race condition and the List class can do nothing to prevent it.
The user propably will also have a collection of PetOwner instances, so it would really only be a single call to .Lenght or .Count to get that number. Something that is so easily solved is not worth the hassle of tracking it internally.
I am answering because I like questions like this. Because I like BS about code and laugh when people make stupid things in code
Here is what it is. Keyword here is "motivation". And I can see it here
public PetOwner(string name)
{
OwnerName = name;
Pets = new List<PetAnimal>();
}
The designer obviously wanted to make sure that pets list will be always there (!= null) and you can only add/remove them, and you can't have PetOwner without the name, hence, you must fully initialize it in constructor. That explains this particular design.
And, NO, this is not a "typical constructor" that "has the same parameters as the fields". Imagine class with 20 fields.. What you add to constructor is whatever needed to fully initialize your object. And if fields are many, just create a wrapper object and pass that to constructor.
Bottom line - your design. If you create classes for others (people) to consume, you basically think about how they are going to use it and you are trying to close all the holes that prevent them from doing something stupid. For example, here I would add
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException();
to close a hole of no-name owner.
So, there we go, my motivation is to simplify usage by other devs and their life easy, while also support good practice and design. Sometimes you leave objects open, that is - add parameter-less constructor. In this case it has potency of not being fully initialized but some frameworks like dependency injection may require such constructor, etc.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am using C#, but I think this applies to most programming languages.
Philosophical question here. When I write windows form applications, I try very hard to keep UI and data structures separate. But I wonder if I am doing it the best way, OO-wise.
For instance, if I have MyClass, and my application requires many of them, perhaps stored in a List, should I make that List a member of the Form1 (with Form1 being the "main" form)? If not, where should I instantiate the List? Any opinion on public vs. private declaration, or is it just a matter of whatever is needed?
public partial class Form1 : Form
{
private List<MyClass> myClassList; // good idea? Bad idea?
public Form1 ()
{
InitializeComponent();
}
}
It depends. If your list stores things related to the UI, like form controls, then yes, that could probably be the best place for it.
Otherwise, it would depend on the context - which we can't see whole here.
Edit: at some point, your form will have to hold a reference to an instance of one of your non UI classes. I think (though again, without more context, can't be 100% sure) that one of these objects should be the one keeping the list.
Try to keep your logic as independent of the form as possible - i.e.: manipulate that list as little as you can from the form, and as much as you can from the non UI classes. You may end up seeing that in the end you don't need the form to hold that reference to the list at all.
Edit again: if I have a system for a pet shop, I might have a Kennel class and a generic list holding items of the Pup class. The kennel instance would hold the list of puppies, not the UI. I hope this small example illustrates my point more clearly.
It's all about choosing the scope of the data and what kinds of operations you are going to be performing on them on the regular basis. For example, you may want other parts of the program to know about that list, but they might not have to know that Form1 even exists. Things can also get messy when you start performing operations on that list in a way that doesn't actually concern the Form1 class.
Whenever you make a new variable, ask yourself some questions. Do other classes need to know about this variable? Do I need to perform operations on this variable that are independent of the form? Does this variable truly belong to the form?
Asking yourself these types of questions can save you time in the future and make your program more readable and easier to maintain.
An internal representation of a list of objects isn't bad (though you should have a good reason to waste the extra memory if you only need it to draw a form), but the list (if it is required to meaningfully render the form) should be an argument in the constructor.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm developing software in C# and I remember that I read an article with the following statement:
Design the methods of a class like this:
use a void method with argument(s) in order to change state of the class instance. method will do some changes on the data of the class
use return value with a method without any arguments in order to retrieve data from the class
I can't find the article anymore and I'm wondering about the benefits and drawbacks of such a convention in order to improve the quality and maintainability of the code I'm writing.
My question is: do you know any references/articles for this question? Does it make sense to follow these statements?
C# has properties which I think makes these suggestions less practical. The big point to take away is that data inside a class should be encapsulated (the outside world cannot access it directly) and abstracted (the details are hidden). This is one of the primary purposes of a class. For this reason I think this advice would make more sense for a language like C++ that doesn't have properties.
One of the problems though is that people would write a class with private fields then have to write a getter method and a setter method for each private field and this results in redundant boiler plate code. Properties help streamline this strategy while still maintaining encapsulation and abstraction. For example,
UserInfo user = new UserInfo();
user.Username = "foo";
Console.WriteLine(user.Password);
In the above example I have set the username to foo and retreived the password for the user. Exactly HOW I set and retreived the information is hidden. It may be saved in an .xml file right now but later I decide to change to saving it in a database or directly in memory. The outside world that uses this classes is never the wiser. This is one of the many beauties of OOP.
The two bullets in your question can respond to a getter and a setter of a property. If I want to retrieve data from my class without any arguments it makes more sense to have a property. Likewise if I want to change the state of my object I can use a setter property. I can perform validation on the input, make it thread-safe, add logging, everything I could do with a method that takes a single argument.
I suppose the bullet points are referring to Command Query Responsibility Separation. In practice you could still need to pass some argument to a return method in order to filter the results for instance. Using voids to change the state is sensible, and also making your return methods so that they don't change the state is good too, but really the number of arguments you pass in is not decided by whether you have a getter or setter method. It is really a factor of what a method needs to know to get it's job done.
The amount of arguments that you pass in should be kept to a minimum however. If you have more than one argument you should really consider if your method is doing more than one thing. I suppose the message is, "Have your methods do one thing and do it well". You can get loads of information about this from Uncle Bob, Bob Martin's Clean Coders series is a great source of information on this subject.
Having a get method that returns a value and doesn't take any parameters makes it very clear what your method is doing.
GetFirstName() is clearer about what it's doing than GetName(bool first) or GetFirstName(User user).
Clarity is key. The method signature may seem like it's fairly clear, but when you read GetName(false) in the code somewhere then it's going to cause some confusion.
These types of getter methods are also not really my standard in C# where I am more likely to use a property for a getter of that nature.
When it comes to void methods with arguments, then this mainly comes into play for setters where you are setting the state of something in the object. Again, easily handled with properties in C#.
Most of the time these guidelines are there to help keep your code testable.
Methods that have fewer parameters are more easily tested -- assuming you are injecting dependencies into the method signature and not creating new objects in the method itself, which can be difficult to mock and test.
Think of how many test cases you may need to cover if you have a method that accepts 5 parameters.
In the end, these are general guidelines that are good for testability and clarity of your code, but there are certainly times when you will find that it doesn't make sense to follow these guidelines.
As with any coding, just be aware of what you are doing and why you are doing it.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have a Class that retrieves some data and images does some stuff to them and them uploads them to a third party app using web services.
The object needs to perform some specific steps in order.
My question is should I be explicitly exposing each method publicly like so.
myObject obj = new myObject();
obj.RetrieveImages();
obj.RetrieveAssociatedData();
obj.LogIntoThirdPartyWebService();
obj.UploadStuffToWebService();
or should all of these methods be private and encapsulated in a single public method like so.
public class myObject()
{
private void RetrieveImages(){};
private void RetrieveAssociatedData(){};
private void LogIntoThirdPartyWebService(){};
private void UploadStuffToWebService(){};
public void DoStuff()
{
this.RetrieveImages();
this.RetrieveAssociatedData();
this.LogIntoThirdPartyWebService();
this.UploadStuffToWebService();
}
}
which is called like so.
myObject obj = new myObject();
obj.DoStuff();
It depends on who knows that the methods should be called that way.
Consumer knows: For example, if the object is a Stream, usually the consumer of the Stream decides when to Open, Read, and Close the stream. Obviously, these methods need to be public or else the object can't be used properly. (*)
Object knows: If the object knows the order of the methods (e.g. it's a TaxForm and has to make calculations in a specific order), then those methods should be private and exposed through a single higher-level step (e.g. ComputeFederalTax will invoke CalculateDeductions, AdjustGrossIncome, and DeductStateIncome).
If the number of steps is more than a handful, you will want to consider a Strategy instead of having the steps coupled directly into the object. Then you can change things around without mucking too much with the object or its interface.
In your specific case, it does not appear that a consumer of your object cares about anything other than a processing operation taking place. Since it doesn't need to know about the order in which those steps happen, there should be just a single public method called Process (or something to that effect).
(*) However, usually the object knows at least the order in which the methods can be called to prevent an invalid state, even if it doesn't know when to actually do the steps. That is, the object should know enough to prevent itself from getting into a nonsensical state; throwing some sort of exception if you try to call Close before Open is a good example of this.
If method B() truly cannot be called unless A() is called first, then proper design dictates that A should return some object that B requires as a parameter.
Whether this is always practical is another matter, but that's how it should be done.
Yes private, otherwise you are leaving the door open for users to do things wrong, which will only be a cause for pain for everyone.
Do you ever need to call any of these methods on its own? ie does any of them do anything which is useful and might be needed stand alone? if so then you might want to keep those public, but even if you keep them all public, you should have the method which calls them in the correct order (preferably with a useful name) to make things easier for your users.
It all depends on whether the operation is essentially atomic. In this case it looks like a single operation to us outsiders, but is it really? If LogIntoThirdPartyWebService fails, does the UI need to present a dialog box to ask the user if they want to retry? In the case where you have a single operation, retrying the LogIntoThirdPartyWebService operation also requires redoing potentially expensive operations like RetrieveImages, while making them separate enables more granular logic.
What I would do in this case is something like this:
Images images = RetrieveImages();
ImagesAndData data = RetrieveAssociatedData(images);
WebService webservice = LogIntoThirdPartyWebService();
UploadStuffToWebService(data, webservice);
or maybe more ideally something like this:
UploadStuffToWebService(RetrieveImages().RetrieveAssociatedData(),
LogIntoThirdPartyWebService());
Now you have granularity while enforcing the proper order of operations.
It sounds to me like from the consumer of your object's point of view, the object does one thing: it moves images from one place to another. As the consumer of the object, all of the individual steps you need to take to accomplish that are irrelevant to me; after all that's why I have you to do it for me.
So you should have a single DoStuff() method that takes all the necessary params, and make all the implementation details private.
Private -- and take the parameters in the constructor and execute the order there.
Do not assume the caller will, or knows how to, call them in order.
So, rather than the example you have listed, I would do it this way:
MyObject myObject = new MyObject(); // make a constructor to take any parameters that are required to "setup" the object per your requirements.
myObject.UploadToWebService();
It really depends on whether you estimate that anyone would want to invoke only one of these methods and whether they make sense individually or can be implemented independently. If not, then it is better to avoid exposing anything but the high level op.
Expose as little as possible, as much as necessary. If a call to FuncA() is always followed by a call to FuncB(), make one public and have it call the other, or else have public FuncC() call them in sequence.
Yes, it should definitely be private, especially as all the methods seem to be parameterless and you're just concerned with the order.
The only time I would consider calling each method explicitly is if they each took several, non-overlapping parameters, and you wouldn't want to pass such a long string of parameters to one method and would want to modularize. And then you should make sure to document it clearly. But remember that comments are not executable... You'll still have to trust your user a bit more than you really should.
One of the biggest factors of information hiding and OOP... only give the user what is absolutely necessary. Allow as little room for mess-up as possible.
The question of public or private depends entirely on the contract you wish to expose for your object. Do you want users of your object to call the methods individually, or do you want them to call a single "DoStuff" method and be done with it?
It all depends on the intended usage of the class.
In the example you've given, I'd say DoStuff should be public and the rest private.
Which do you think would be easier for the consumers of your class?
Absolutely write one public method that performs the correct steps in the correct order. Otherwise, the caller is not going to do it right; they're going to forget a step or skip something.
Neither. I think you have at least 3 objects otherwise you are breaking the Single-Responsibility Principal. You need an object that "Gets and holds images", one that "manipulates images", and one that "manages external vendor communication".
One reason they would be public is if you intend the user to be able to insert logic between steps. In this case, you should impose that the functions are called in the correct order internally by keeping a really tiny state machine. If the state machine transitions in the wrong order, you have options besides just doing something wrong, such as throwing an exception.
However, an alternative design that allows them all to be remain private if the case of needing to act beween steps does exist. Instead of making the methods public, provide a public callback interface that lets the users attach handlers that you call at each step of the process. In your now private doItAll() method, you can do something as granular as:
if(preRetrieveHandlerExists){
preRetrieveHandler()
}
obj.RetrieveImages();
if(postRetrieveHandlerExists){
postRetrieveHandler()
}
//so on and so forth
My software engineering rule of thumb is to always give the user/consumer/caller as little chance to screw things up as possible. Therefore, keep the methods private to ensure working order.
Fowler uses the term "Feature Envy" to describe a situation where one object calls a handful of methods (especially repeatedly) on another.
I don't know where he got it from. You don't see it much in the literature, and a lot of people over the years have had no idea what I was talking about (I dunno why, I thought the name was perfectly obvious once I heard it. Which is why I repeat it)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 months ago.
Improve this question
Background
In a C# command-line app I'm writing, several of the parameters have "yes" and "no" as the possible values.
I am storing their input using the Enum type shown below.
enum YesNo
{
Yes,
No
}
Which is fine - the code works. No problem there.
NOTE: Yes, I could store these as bool (that's how it used to work). My design choice is to be explicit about the Yes/No choice made by the user because they will see this printed in other contexts and I'd like it to be more obvious what the choice was.
My Question
It just seems odd to have an enum called "YesNo" - what are some suggestions for better names for an enum for "yes" and "no" values.
So Finally
I asked this question relatively early in StackOverflow's life. It wasn't fake question - I really did have this situation. I just thought it would be nice to use it see what the community would do. Because it is, I admit a somewhat odd question.
First, thanks to all who spent the time replying. I'm trying to pay that back with a thoughtful conclusion.
Comments on the answers
switching to bool. I understand your motivation, but I feel I need to point out that having a binary choice (and by that I mean a choice between any two values - alive/dead, married/unmarried, etc.) is not the same as boolean choice between true and false. We find as programmers switching between yes/no and true/false easy - fair enough. Had my choice in this case been for example "Democrat" or "Replication"" (contrived example, I know) then you can see possibilities for confusion or at least awkwardness. I do think the bool option is valid in this case, but less so in other binary choices.
localization - great point. In my specific case it didn't matter - this was not and is never going to be localized, but for other situations it is something to consider.
more than three options - In fact, later on I had to add a third value called to represent the valid (in my application) condition of a user specifically not making the choice.
There were a lot of good comments, thank you all!
You say you don't want to use bool because it will be printed out for the user to see amongst other contents. That suggests the problem isn't in storage but in display. By all means present true/false as Yes/No, but there's no need to create a whole new type for it IMO.
EDIT: In addition to suggesting you don't use an enum in the first place, I'd strongly recommend that if you do use an enum, you change the order or use explicit values. Having Yes=0, No=1 will be really confusing if you ever end up seeing the values as integers.
I'd suggest you use a name that indicates the Value which is set to Yes or No.
E.G.
public enum Married
{
YES,
NO
}
I would be confused to see an enum used for a boolean. You say that:
NOTE: Yes, I could store these as bool (that's how it used to work). My design choice
is to be explicit about the Yes/No choice made by the user because they will see this
printed in other contents and I'd like it to be more obvious what the choice was.
I fail to see how a "Yes" or "No" is any more "explicit" than a true or false.
ResponseEnum or EResponse or UserResponse depending on your conventions.
I wouldn't limit yourself to only Yes or No as in the future you may want to add functionality that required an Unsure response also.
I'd want to call it:
enum Boolean
{
Yes,
No
}
No, wait, there is already a built in boolean type you can use.
If your only reason for using an enum here is because there is a convenient conversion to/from a string that you want to show the user, then you are going to get bitten very badly down the track as you do more sophisticated things. A separation of model from view will server you well. Read up on MVC and/or MVVM patterns.
I might also suggest that a simple boolean with some custom attributes that define the display strings to use in place of "true" and "false" might suffice here. You can then write your own to/from string methods that look for your custom attributes.
YesNo
Choice
BinaryChoice
Or just use a boolean.
I would not use a enum at all, just roll your own typeconverter and use booleans.
I think YesNo is just fine. Consider things like "MB_OK" and "MB_YESNO" ... I know it's not a type but anything that's self-explanatory should be fine.
Is there any possibility for having option other than yes/no.For just 2 option stick with boolean.Try to modify the display area alone
(Humour - please don't take this seriously...)
I'm surprised no-one's suggested this yet:
public enum UserWtf
{
No,
Yes,
FileNotFound
}
I guess there is a problem with displaying bool values.
It is better to create simple wrapper that stores boolean allowing you to display them as Yes/No or True/False.
I read your updated explanation, but I still feel this is a poor choice. Booleans exist exactly for this purpose. It is your responsibility to ensure that when "they will see this printed in other contents" appropriate text is outputted. This could be as simple as:
Console.WriteLine(_("Using Foo: ") + (useFoo ? _("Yes") : _("No")));
while still having full support for localization. useFoo is of course a parameter telling the function whether it is using foo. :)
The _ is short for the gettext function (http://www.gnu.org/software/gettext/), which is available for C# (http://www.gnu.org/software/automake/manual/gettext/C_0023.html).
EUserAction ?
You described it as some user action. You could also be more specific, though. The name allows for some additional choices in the future. (The name should be what the choice is for, not what the choices are)
However, for your other, subtle question:
because they will see this printed in other contexts and I'd like it to be more obvious what the choice was.
it shouldn't really matter what the user sees. The data model can be very different from what you present to the user. A bool would have sufficed. Is there a possibility for additional actions in the future?
When I have need something like this, I use the word Flag, as in Flag.Yes, MarriedFlag.No, etc.
Example of when this is useful: you know there are only Yes and No values today but you suspect there might be additional values (like Maybe) in the future.
I don't see the point of this enum unless there were some other values besides Yes and No. That's just a bool. And making an enum just so you don't have to type out yes or no seems kind of silly.
Use a bool, combined with bool.TrueString and bool.FalseString for display purposes.
I use OptionalBinaryFilter for:
Yes, No, All
But if you have only Yes and No, seem more suitable use of Boolean in a member.
enum Confirmation {
Yes = 'yes',
No = 'no'
}
or
enum Confirmation {
Yes = '401efbce-ad94-41cf-94cf-2313611e94c2',
No = '8f836daa-40fb-46ec-9708-28a40bc6fead'
}