I have a class with one private field:
class Person {
string name;
public void setName(string name);
}
Then, using some object which is responsible for interacting with user (in this example by command line), I want to change the value of this field:
Person somePerson;
CommandLineView view;
somePerson.setName(view.askUserForName());
It works. But I don't like using set function as it exposes class members.
Therefore I started looking how to avoid it.
New implementation looks like this:
class Person
{
string name;
public void changeName(view) { name = view.askUserForName(); }
}
and:
Person somePerson;
CommandLineView view;
somePerson.changeName(view);
Now Person does not expose its member. Moreover this class is responsible for logic related to changing name (for example function changeName could also update database, notify interested parties etc.
The question is: Is such kind of refactoring a good practice? Or maybe implementation with setter was better, even if it break encapsulation?
I think there should be no method to set the name at all, it should be a constructor parameter:
Person somePerson(view.askUserForName());
Problem with your approach is that you first create the object which is not fully initialized, so is dangerous to use: Person somePerson. What if you forget to setName? Will your code still work with this "empty" person?
And then you allow to directly modify the internal state with setName method, which is also not good.
Using the constructor parameter you avoid both of these problems.
As for the original question - I don't think there is big difference between the two methods.
The result is exactly the same - you call the method and the internal object state changed. You can name it setName or changeName, result is the same.
The second method with changeName(view) actually is worse because you also introduce the dependency of the Person on the View object.
Now, if you want to change the name, you always need to create the View object first.
Related
I've read a lot of articles about "public vs getter/setter", but I still wonder if there is any good part about public variable.
Or the question is:
If you're going to make a new awesome programming languange, are you still going to support public variable and why??
I agree with almost everything that's been said by everyone else, but wanted to add this:
Public isn't automatically bad. Public is bad if you're writing an Object Class. Data Classes are just fine. There's nothing wrong with this class:
public class CommentRecord
{
public int id;
public string comment;
}
... why? Because the class isn't using the variables for anything. It's just a data object - it's meant to be just a simple data repository.
But there's absolutely something wrong with this class:
public class CommentRecord
{
public int id;
public string comment;
public void UpdateInSQL()
{
// code to update the SQL table for the row with commentID = this.id
// and set its UserComment column to this.comment
}
}
... why is this bad? Because it's not a data class. It's a class that actually does stuff with its variables - and because of that, making them public forces the person using the class to know the internals of the class. The person using it needs to know "If I want to update the comment, I have to change the public variable, but not change the id, then call the UpdateInSQL() method." Worse, if they screw up, they use the class in a way it wasn't intended and in a way that'll cause unforseen consequences down the line!
If you want to get some more info on this, take a look at Clean Code by Robert Martin, Chapter 6, on "Data/Object Anti-Symmetry"
A public variable essentially means you have a global accessible/changeable variable within the scope of an object. Is there really a use case for this?
Take this example: you have a class DatabaseQueryHandler which has a variable databaseAccessor. Under what circumstances would you want this variable to be:
Publicly accessible (i.e. gettable)
Publicly settable
Option #1 I can think of a few - you may want to get the last insert ID after an insert operation, you may want to check any errors the last query generated, commit or rollback transactions, etc., and it might make more logical sense to have these methods written in the class DatabaseAccessor than DatabaseQueryHandler.
Option #2 is less desirable, especially if you are doing OOP and abiding by SOLID principles, in particular regards to the ISP and DIP principles. In that case, when would you want to set the variable databaseAccessor in DatabaseQueryHandler? Probably on construction only, and never at any time after that. You probably also want it type-hinted at the interface level as well, so that you can code to interfaces. Also, why would you need an arbitrary object to be able to alter the database accessor? What happens if Foo changes the variable DatabaseQueryHandler->databaseAccessor to be NULL and then Bar tries to call DatabaseQueryHandler->databaseAccessor->beginTransaction()?
I'm just giving one example here, and it is by no means bullet proof. I program in PHP (dodges the hurled rotten fruit) and take OOP and SOLID very seriously given the looseness of the language. I'm sure there will be arguments on both sides of the fence, but I would say that if you're considering using a public class variable, instead consider what actually needs to access it, and how that variable is to be used. In most cases the functionality can be exposed via public methods without allowing unexpected alteration of the variable type.
Simple answer is: yes, they are bad. There are many reasons to that like coupling and unmaintanable code. In practice you should not use them. In OOP the public variable alternative is Singleton, which is considered a bad pracitce. Check out here.
It has a lot to do with encapsulation. You don't want your variable to be accessed anyhow. Other languages like iOS (objective-c) use properties:
#property (nonatomic, strong) NSArray* array;
then the compiler will generate the instance variable with it's getter and setter implicitly. In this case there is no need to use a variable (though other developers still prefer to use variables). You can then make this property public by declaring it in the .h file or private by declaring it in the .m file.
In the active record pattern and in the builder pattern one may encounter so called "fluid" methods with non-verb names such as
public function carRadio(...);
public function driver(...);
The ellipsis (...) indicates zero or more arguments.
The purpose of the above is brevity. Sometimes exposing a public property is enough, but sometimes you want to do more stuff than simply assign an object.
e.g.
$kid = Kindergarden::find(33);
$kid->food($carrot);
assert($carrot == $kid->food());
Roughly, this means give some food to the child, but in the food method you may want to check for allergies or some such.
A bulilder-pattern example could look like:
$threeThousandWatts = Generator::create();
$threeThousandWatts->wires($w)->fuel($gas)->schedule($timeSlot);
...you get the idea.
The question is, what do you (literature you have read) call a mutator that is also a an accessor?
PS. This is not a for a public API. It's just a generic question.
I am new to OOP. I am still in a learning phase.
Why do we need constructors, When we can initialize the values of the properties (variables) by writing a "Initialize function"?
Basically why do we write a constructor when we can achieve the same results even by writing a function for initializing the variables?
The constructor IS the "Initialize function"
Rather than calling two functions
object = new Class;
object.initialize();
You just call
object = new Class();
The logic inside the constructor can be identical to the logic inside the initialize function, but it's much tidier and avoids you naming your function initialize(), me naming mine initialize_variables(), and someone else naming theirs init_vars()... consistency is useful.
If your constructor is very large, you may still wish to split variable initialisation into a separate function and calling that function from your constructor, but that's a specific exception to the scenario.
So answer is simple
Why do we write Constructor?
Because in C you can write,
int i;
if write like this In above case data type and variable defines if you define like this memory allocated for i variable.So simple here we define class name and variable name(object name) we can create memory allocated for class name.
Example
myClass objectName;
But in C++ new keyword is used for dynamic memory allocation, so this dynamic memory which we can allocate to our class but here my example myClass is our class and we want to allocate to dynamic memory allocated.
So
myClass objectName = new myClass();
and simply constructor is memory allocation for class variable is called the constructor.`
the role of the constructor is to initialize the variables/values.it is the "initialization function".The only reason i find on why we use a constructor instead of a normal function to initialize the variables is to stop different people from using different function names and avoid ambiguity and it is much more easier to use a constructor which is instantiated automatically as soon as the class is run,instead of having to write a separate code for instantiation.this may seem small and like something that doesn't require much work,but only for a very small program,for larger ones the struggle is real.
It is usual to put mandatory things into the constructor and optional ones into the Initialise function.
For example, consider an amplifier that requires a power source so that would be supplied to its constructor. Logically, you may want to turn it on and set its power level but one could argue that you might not want to do that until later. In pseudo-code:
class Amplifier
{
public Amplifier(PowerSource powerSource)
{
// create amplifier...
}
public int PowerLevel;
public void Initialise()
{
// turn on...
}
}
The example, above, is rather puerile but it illustrates the concepts at play. It is always an issue of design, however, and opinions do vary.
Some classes of object, however, will have to perform obvious set-up operations during their construction phase. In these cases, the requirement to have a constructor is very easy to understand. For example, if your object might require a variable amount of memory, the constructor would be a logical place to allocate it and the destructor or finaliser would be a logical place to free it up again.
Even if you don't use constructor it will call implicitly by your language translator whenever you create object.Why?
The reason is that it is used for object initialization means the variable(instance) which we declare inside our class get initialized to their default value.
class Person {
//Class have two parts
//1.Data(instance variable)
//2.Methods(Sub-routine)
String name;
int age;
}
public class Stack{
public static void main(String[] args){
Person person1 = new Person();
System.out.println("Name: "+person1.name);
System.out.println("Age: " + person1.age);
}
}
Output- Name: null
Age: 0
"null" and "0" are default values which are impicitly set by default constructor.
When we initialize a class by creating an instance or object the constructor is called automatically. This is very helpful when we need a huge amount of code to be executed every time we create an object.
The best use of constructor can be seen when we create a " graphical user interface". While building a GUI for an application we need to separate the code for designing the GUI and the business logic of the application. In such a case we can write the code for designing GUI, in a constructor and business logic in respective methods. This make the code tidy and neat too.
Also when an object is created the global variables can be initialized to their default values using constructor. If we don't initialize the global variables, then the compiler will do it implicitly by using the default constructor.
So constructor is a very wise concept which appears to be an idiosyncrasy at first but as you code further and more and more you will realize it's importance.
Because constructors are exactly for that: to avoid using an "initialize function"
Plus you can have have as many constructors as you want: you juste feed them some parameters, depending how you want to inialize your object.
Constructor is a special member function which has same name as class name and called whenever object of that class is created. They are used to initialize data field in object.
Constructor has following properties:
It has same name as class name.
It is called whenever object of a class is created.
It does not have return type not even void.
It can have parameters.
Constructor can be overloaded.
Default constructor is automatically created when compiler does not find any constructor in a class.
Parameterized constructor can call default constructor using this() method.
A constructor can be static for static data field initialization.
It is not implicitly inherited.
For More Info
https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
I am designing a process that should be run daily at work, and I've written a class to do the work. It looks something like this:
class LeadReport {
public $posts = array();
public $fields = array();
protected _getPost() {
// get posts of a certain type
// set them to the property $this->posts
}
protected _getFields() {
// use $this->posts to get fields
// set $this->fields
}
protected _writeCsv() {
// use the properties to write a csv
}
protected _sendMail() {
// attach a csv and send it
}
public function main() {
$this->out('Lead Report');
$this->out("Getting Yesterday's Posts...");
$this->_getPosts();
$this->out("Done.");
$this->out("Next, Parsing the Fields...");
$this->_getFields();
$this->out("Done.");
$this->out("Next, Writing the CSVs...");
$this->_writeCsv();
$this->out("Done.");
$this->out("Finally, Sending Mail");
$this->_sendMail();
$this->out('Bye!');
}
}
After showing this code to one of my colleagues, he commented that the _get() methods should have return values, and that the _write() and _sendMail() methods should use those values as parameters.
So, two questions:
1) Which is "correct" in this case (properties or return values)?
2) Is there a general rule or principle that governs when to use properties over when to use return values in object oriented programming?
I think maybe the source of your question comes from the fact that you are not entirely convinced that using properties is better than having public fields. For example here, common practice says that should not have posts and fields as public. You should use the getField method or a Field protected property to regulate access to those fields. Having a protected getField and a public fields doesn't really make sense.
In this case your colleague may be pointing at two things. The fact that you need to use Properties and not public fields and also the fact that it is probably better to pass the post into the method and not have the method access a property if you can. That way you don't have to set a property before calling the method. Think of it as a way of documenting what the method needs for it to operate. In this way another developer doesn't need to know which properties need to be set for the method to work. Everything the method needs should be passed in.
Regarding why we need properties in the first place? why shouldn't you use public fields. Isn't it more convenient? It sure is. The reason we use properties and not public fields is that just like most other concepts in OOP, you want your object to hide its details from the outside world and just project well defined interfaces of its state. Why? Ultimately to hide implementation details and keep internal change to ripple out(Encapsulation). Also, accessing properties has the added benefit of debugging. You can simply set a breakpoint in a property to see when a variable is changed or simply do a check if the variable is of certain value. Instead of littering your code with said check all over the place. There are many more goodies that come with this, returning readonly values, access control, etc.
To sum up, fields are though of as internal state. Properties(actual get/set methods) are though of as methods that interact with internal state. Having an outside object interact with interfaces is smiley face. Having outside class interact with internal state directly is frowny face.
I am learning from Stanford's CS193P course. In the class, Paul has a demo project, "Calculator", where he uses id as the type of a property. He intends to not use a specific class, because he does not want to create a new class and then he does not need to write documentation, and even when it is updated, he does not need to redesign the class. id can solve all these problems.
Is this a really a good way? id is the return type of the property, and used as the parameter type of another method. How does the caller know what id is, and how to provide the correct object? By reading code comments?
In general, is there any good reason to use id as a return type or parameter type in public API? (Except init and factory method, though even for those, instancetype is recommended.)
If your method returns a class that is a member of a class cluster, you should return id.
If you're returning an object whose class is opaque, isn't declared in a public header, you should return id. (Cocoa occasionally uses such objects as tokens or context data.)
Container classes should always accept and return their constituents as ids.