1

What are the thoughts about calling a class function that doesn't return anything but instead sets internal property values that you then read.

var myClass = new MyClass();
myClass.DoFunction(specialDate, "A");

// after calling DoFunction() the Name and Type property are now set
var name = myClass.Name;
var type = myClass.Type;

Off the top of my head this seems like an awkward way of doing things vs having DoFunction() return an object that has Name and Type properties in it. Thoughts?

  • Without any arguments, what would DoFunction() actually do? – Phil N DeBlanc Jan 5 '18 at 18:53
  • Sorry, it was just an example. You're correct, DoFunction() would have arguments. It's more just the general structure of this approach vs DoFunction() returning an object that has Name and Type vs setting it's own internal data. – user441521 Jan 5 '18 at 19:09
  • I don't understand why you would use the extra step of calling a method to do what a parameterized constructor can do. – Phil N DeBlanc Jan 5 '18 at 19:12
  • Why would you return an object with those properties when you already have this as the above mentioned object? – slybloty Jan 5 '18 at 19:44
  • @PhilNDeBlanc I would do it this way if you need to modify the value later on. Like a setter would. – yarwest Jan 5 '18 at 20:11
3

This is reasonable. Since you already have a Name and Type field, let's pretend this is some type of "Person" class. You might have a method

person.updateFromRecentMarriageRecords(MarriageRecords)

that could change the name (e.g., from maiden name to spouse's name) and type (from 'single' to 'married').

4

One obvious example of this pattern that I can think of is a stream: if I call the Read or Write methods of some .net stream, the Position property is updated/advanced by the number of bytes read/written. Another might be dataset.ReadXml - the method takes a file path and deserialises xml, populating the dataset with tables and rows representing the xml. It doesn't return the xml: if you want to look at it you need to inspect the dataset after you call read, and a vast number of properties become set to various different values as a result

As such, while I don't personally think it's a commendable pattern in a lot of cases it's certainly contextual and makes sense in some. The case you posted seems a poor example as I don't see how setting a date and a string would reasonably alter a name and a type but perhaps this is because your question's example is a Foo/Bar style contrivance. I thought for a while to find a fit for the example you posted, and came up with the following:

If you had calenderEntry.setDateAndLocation then the Name and Type properties could become set to some relevant contextual thing:

calendarEntry.setDateAndLocation(Date.Parse("4 Jul 2018"), "USA")
calenderEntry.Name //now "Independence Day"
calendarEntry.Type //now PublicHoliday

So, yes.. it could work- not saying it's a universally wise pattern but if you post a more accurate rendition of where you were thinking of using it, what names and processes are involved in the context, then we could perhaps be a bit more on target than "it depends".

3

Such questions are mostly nonsensical by using arbitrary terms like "Foo" or "Bar", or in this case DoFunction and MyClass, instead of using proper terms which reflect the real function or class names. Here is an example which could make sense:

var myPoint = new Point2D(); // lets assume for some reason `Point2D` is mutable
// ... and though there is a constructor taking x and y, you also want to be able
// ... to change those values later.

// Now, ..
myPoint.SetXY(123,456); 
// as a shorter form of myPoint.X=123, myPoint.Y=456
// can be useful as syntactic sugar, when X and Y are very often changed together

// still X and Y can be retrieved individually
var x = myPoint.X;
var y = myPoint.Y;

But I can easily imagine a different example where this makes no sense (and I am sure you can do, too). So don't look for braindead, general rules where you can decide if some code is good or bad just because of some formal structure, instead look if the abstraction the methods and classes create are useful and make sense.

2

As far as I understand, that kind of function is called a setter. They allow for validation rules to be checked before the class variable is made to the input. More about getters & setters: http://www.hydrick.net/?p=292

  • 2
    As I understand OP, he is setting more than one value, and using fancy logic to do so. myClass.DoFunction(specialDate, "A"); has nothing specific to Name and Type. That is not the traditional usage of "setter". – user949300 Jan 5 '18 at 20:26
  • Ah, I see. I suppose it would really be something I would put in a constructor then. Now I understand it. – KeizerHarm Jan 5 '18 at 21:03
2

A class is a mechanism for creating abstraction.

An abstraction is a bundling of capabilities (methods & state) offering the consuming client (a programmer, often ourselves) something useful in a single concept, while hiding certain details that are irrelevant (sometimes b/c real-world some details are irrelevant, and often b/c the internal implementation of the offering is a detail that the consuming client doesn't/shouldn't need to know about to use it)

It is best to have coherent abstractions. One way to judge the coherence of an abstraction is to look the lifetimes of state. The lifetime of all the fields of an object, ideally, is one and the same (as the object itself).

When the object is created, and its fields are initialized together, and such an object is a more-or-less coherent abstraction. Fields may be updated during the operation of the object, though it always remains in a usable state.

When we find that some object's fields are not necessarily initialized at the same time, it suggests a conflation of two different abstractions.

Thus, given what I can see in your questions, I consider that approach to have room for improvement. You could change it as follows:

  • remove the DoFunction() method, and pass the parameters in the constructor so that is the whole purpose of the object

  • return a different object as the return value, an new class that bundles the various fields of interest together.

1

You don't always need or want to return something after setting variables.

If possible, feed the values through the constructor and have them set at initialization.
But if you don't have values at that time, you can use a set function to assign them afterwards. There is no need for a return here.
Also, if you need to change some of those values in the future, again, you can use the set function to do so. No return needed.
If your variables are not visible outside your class' scope, you will need set and get methods to address such situation.

Here are some examples of such usage:

myClass(n='', t='')
    setName(n)
    setType(t)

    setName(n)
        name = n
    setType(t)
        type = t

    doSomethingToName()
        setName('some other name')

    doSomethingToType()
        setType('some other type')


myC = myClass() //Initialization with no values

myC.setName('name')
myC.setType('type')

print myC.name //Prints 'name'

myC.doSomethingToName()
print myC.name //Prints 'some other name'
print myC.type //Prints 'type'

myC1 = myClass('myName', 'myType') //Initialization with values
print myC1.name //Prints 'myName'
print myC1.type //Prints 'myType'
  • Same comment as for @KeizerHarm: As I understand OP, he is setting more than one value, and using fancy logic to do so. myClass.DoFunction(specialDate, "A"); has nothing specific to Name and Type. That is not the traditional usage of "setter". – user949300 Jan 5 '18 at 20:27
  • Yeah, this wouldn't be a setter. The DoFunction() is using the import to run complex logic and the result of this logic are 2 values. – user441521 Jan 6 '18 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.