The problem with my code is that I have two errors at the moment. "Syntax Error: Unexpected Token "." even though the "." is part of the code and should be working fine. Then another when I get rid of the "." is "Reference Error: fairyEmbed is not defined" Here's the code in question:
const Discord = require("discord.js");
module.exports = fairyEmbed;
.setColor('#dd525d')
.setTitle('Fairy')
.setURL('https://youtu.be/0K6qBmnRizU')
.setDescription('Fairy types are too cutesy for my preference. They’re weak to Poison and Steel type and Fire, Steel and Poison types resist their attacks. But they do a lot of damage to Dark, Fighting and Dragon types. Dragon type attacks don’t effect them at all, so they’re good in that department.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.pinterest.com%2Fpin%2F627055948095995745%2F&psig=AOvVaw1Vu5xwOk0k9tBEJ9Yclz2F&ust=1609622152653000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCICQ3vXT--0CFQAAAAAdAAAAABAD')
module.exports = fightingEmbed;
.setColor('#61dde6')
.setTitle('Fighting')
.setURL('https://youtu.be/FJgRlbjzsrs')
.setDescription('Fighting types are very resilient. Their attacks are super effective against Rock, Steel, Dark, Normal and Ice types and they resist Dark, Rock and Bug type attacks. Fighting type attacks won’t do well against Flying, Psychic, Fairy, Poison or Bug types and they won’t do anything to Ghost types and they’re very weak to Fairy, Psychic and Flying type attacks.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fpokemon.fandom.com%2Fwiki%2FZamazenta_(anime)&psig=AOvVaw1b8V8kCknIyef2c_zxuFjV&ust=1609622421791000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCJCsvPXU--0CFQAAAAAdAAAAABAM')
module.exports = steelEmbed;
.setColor('#ba2838')
.setTitle('Steel')
.setURL('https://youtu.be/I_57ptO3TKc')
.setDescription('Steel types are the prime definition of defense with an amazing resistance to Normal, Grass, Ice, Flying, Psychic, Bug, Rock, Dragon, Steel and Fairy type attacks and are immune to Poison attacks. They’ll do immense damage to Rock, Fairy and Ice types. If they get hit by Fire, Ground or Fighting type attacks, they’ll be greatly damaged and they don’t do much to Water, Fire, Electric or other Steel types.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fpokemongohub.net%2Fpost%2Fguide%2Fdialga-heat-map%2F&psig=AOvVaw3l68mb5ltZZZusGgHSGLTd&ust=1609622768057000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKjLpZ_W--0CFQAAAAAdAAAAABAV')
module.exports = darkEmbed;
.setColor('#3a4c7b')
.setTitle('Dark')
.setURL('https://youtu.be/0K6qBmnRizU')
.setDescription('Dark type Pokémon are masters of the night and dirty, underhanded tactics. They’re very strong against Psychic and Ghost and resist Dark and Ghost type attacks. Psychic type attacks don’t stand a chance due to their immunity. It’s best to avoid putting them against Fighting, Fairy and Bug type attacks because of their weakness and they won’t do as much damage against Dark, Fighting and Fairy type Pokémon. Either way you slice it, Dark type Pokémon are very strong. Spikemuth’s gym is a prime example of that.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fbulbapedia.bulbagarden.net%2Fwiki%2FYveltal_(Pok%25C3%25A9mon)&psig=AOvVaw01HxoY93uTikkUD-yDrdJU&ust=1609623455517000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCIDG2OLY--0CFQAAAAAdAAAAABAD')
module.exports = dragonEmbed;
.setColor('#352822')
.setTitle('Dragon')
.setURL('https://youtu.be/8lrMjcNJGfE')
.setDescription('Dragon types are very rare and thought to be a mystical type. If you want to stop them in their tracks, use Fairy, Ice or Dragon type moves against them. Dragon types resist Fire, Water, Grass and Electric type attacks and Dragon Type attacks are only strong against themselves but have a wide variety of attacks. Dragons type moves don’t do much to Steel types and Fairy types are completely immune to their attacks. My bro said Raihan was infamous for completely demolishing trainers with his overwhelming dragons, so I’d watch your choices around them.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fbleedingcool.com%2Fgames%2Frayquaza-raid-guide-how-to-catch-a-shiny-rayquaza-in-pokemon-go%2F&psig=AOvVaw02L1u59NkP3kqQSp5xAJKB&ust=1609623775222000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCIiX9PvZ--0CFQAAAAAdAAAAABAD')
My goal for this code is to send an embed with a different file. That's the embed file which isn't working. I've tried removing the "." and googling ways to define embeds and so on but nothing helpful comes up. All that shows is an embed documentation which doesn't answer how to fix my errors directly or what I should've done. So here I am.
You have to define the Embeds like:
const Discord = require("discord.js");
let fairyEmbed = new Discord.MessageEmbed()
.setColor('#dd525d')
.setTitle('Fairy')
.setURL('https://youtu.be/0K6qBmnRizU')
.setDescription('Fairy types are too cutesy for my preference. They’re weak to Poison and Steel type and Fire, Steel and Poison types resist their attacks. But they do a lot of damage to Dark, Fighting and Dragon types. Dragon type attacks don’t effect them at all, so they’re good in that department.')
.setThumbnail('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.zedge.net%2Fwallpaper%2F23b8d5ed-9f57-39e7-b27c-ffd2df026702&psig=AOvVaw3xIwv-YzXf8AuUEaTGfBp4&ust=1609622014464000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCKDrk7TT--0CFQAAAAAdAAAAABAJ')
.setImage('https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.pinterest.com%2Fpin%2F627055948095995745%2F&psig=AOvVaw1Vu5xwOk0k9tBEJ9Yclz2F&ust=1609622152653000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCICQ3vXT--0CFQAAAAAdAAAAABAD')
you have to do this for every single embed. The solution that you have cannot work, because from where should your program know that fairyEmbed for example is a MessageEmbed? Defining means storing values in variables. In this case our values are MessageEmbeds. If you defined it, your program is able to know that you are working with embeds. And then you can do:
module.exports = fairyEmbed;
This is how you would do what you are attempting to do :)
const { MessageEmbed } = require('discord.js');
module.exports.fairyEmbed = new MessageEmbed()
.setTitle('Title!')
.setDescription('Hello World!');
Related
How does the SOLID "Interface Segregation Principle" differ from "Single Responsibility Principle"?
The Wikipedia entry for SOLID says that
ISP splits interfaces which are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them
However, to me that sounds like just applying the SRP to interfaces as well as classes. After all, if an interface is only responsible for just one conceptual thing, than you wouldn't be able to break it down further.
Am I missing something, or is ISP sort of redundant with SRP? If not, then what does ISP imply that SRP does not?
SRP tells us that you should only have a single responsibility in a module.
ISP tells us that you should not be forced to be confronted with more than you actually need. If you want to use a print() method from interface I, you shouldn't have to instantiate a SwimmingPool or a DriveThru class for that.
More concretely, and going straight to the point, they are different views on the same idea -- SRP is more focused on the designer-side point-of-view, while ISP is more focused on the client-side point-of-view. So you're basically right.
It all came from
The ISP was first used and formulated by Robert C. Martin when doing
some consulting for Xerox. Xerox had created a new printer system that
could perform a variety of tasks like stapling a set of printed papers
and faxing. The software for this system was created from the ground
up and performed its tasks successfully. As the software grew, making
modification became more and more difficult so that even the smallest
change would take a redeployment cycle to an hour. This was making it
near impossible to continue development. The design problem was that
one main Job class was used by almost all of the tasks. Anytime a
print job or a stapling job had to be done, a call was made to some
method in the Job class. This resulted in a huge or 'fat' class with
multitudes of methods specific to a variety of different clients.
Because of this design, a staple job would know about all the methods
of the print job, even though there was no use for them.
so
The solution suggested by Martin is what is called the Interface
Segregation Principle today. Applied to the Xerox software, a layer of
interfaces between the Job class and all of its clients was added
using the Dependency Inversion Principle. Instead of having one large
Job class, a Staple Job interface or a Print Job interface was created
that would be used by the Staple or Print classes, respectively,
calling methods of the Job class. Therefore, one interface was created
for each job, which were all implemented by the Job class.
# http://en.wikipedia.org/wiki/Interface_segregation_principle#Origin
SRP is concerned with what a module does, and how it is done, disallowing any mix of abstraction levels. Basically, as long as a component can be extensively defined with a single sentence, it will not break SRP.
On the other hand ISP is concerned with how a module should be consumed, whether it makes sense to consume just part of the module, while ignoring some aspect.
As an example of a code that keeps the spirit or SRP, but can break ISP is the Facade pattern. It has a single responsibility, "providing simplified access to a larger subsystem", but if the underlying subsystem needs to expose wildly different thinks, it does break ISP.
That said, usually when a piece of code breaks a SOLID principle, it often breaks the whole lot. Concrete examples that break a specific principle, while preserving the rest are rare in the wild.
Robert Martin tweeted the following on May 16, 2018.
ISP can be seen as similar to SRP for interfaces; but it is more than that. ISP generalizes into: “Don’t depend on more than you need.” SRP generalizes to “Gather together things that change for the same reasons and at the same times.”
Imagine a stack class with both push and pop. Imagine a client that only pushes. If that client depends upon the stack interface, it depends upon pop, which it does not need. SRP would not separate push from pop; ISP would.
SRP and ISP ultimately boils down to the same things. Implementing, either of them, needs a split of classes or interfaces.
However there are differences on other fronts.
Violation of SRP can have a far reaching effects on the entire design structure, giving rise to poor maintainability, reuse and of course low cohesion and coupling.
SRP has an impact on both the behavioral and structural components of an object structure.
Re designing on SRP violation needs a much deeper analysis, require looking at the different components of design in a holistic way.
Violation of ISP is mostly about poor readability ( and to some degree, low cohesion ). But the impact on maintenance and code re-use is far less sinister than SRP.
Moreover, refactoring code to ISP conformation, seems to be just a structural change.
See also my blog for SRP and ISP
From the point of my understanding, both principles are complementary, i.e. they need to be combined.
The ultimate consequence of violating ISP is becoming fragile, "shotgun surgury" or a "butterfly effect". A lot of code can break or require code updates because they depend onto some interface or objects which provide more than they needed. Changes become excessive.
The consequence of violating SRP is mainly decreased readability and maintentance. The lack of clear code structure may require people to search across the code base (a single responsibility is too distributed) or within a single large unit (multiple responsibilities scrammed together) to make a coherent change. In General, it is increased overhead to fully understand the concern (purpose) of some code snippet. Changes are prevented.
In that way, both principles act like a lower and upper bound for sane change management.
Examples for satisfying RSP without ISP – as provided by the other answers – express that there can be code which truly would belong together (like the stack example quote from Robert C. Martin). But it may do too much, is overengineered, etc. Maybe in very small examples, the effect is not visible, but if it grows large, it may be more comfortable to have a depending class still compile correctly after some unrelated part in the (indirect) dependency was changed. Rather than not compile anymore because unrelated things were changed.
While I understand the value of implementation/interface distinction, I fail to see why most OO systems issue errors on access to private members.
I indeed wouldn't want to access private members in my main program.
But I would like to have that access for tests and debugging.
Is there any good reason whatsoever to issue errors and not warnings? The way I see it, I am forced to either write code I can test, but that doesn't utilize language support for interfaces, or use the language support, but have difficulty in testing.
EDIT
For those who suggested using public interfaces. You can, but it's less convinent.
On a conceptual level I find privacy that doesn't care about who or when quite crude.
Friend classes seem like a reasonable solutution. Another might be an 'all public' compiler switch.
The way I see it, I am forced to either write code I can test, but that doesn't utilize language support for interfaces, or use the language support, but have difficulty in testing.
Why do you need to access private variables and functions? Either they are called (however indirectly) by public functions at some point, or they are just inaccessible pieces of code that shouldn't be there at all because there is no way to invoke them. Think about it, if the private method is completely impossible to invoke from outside the class in any way at all, is it ever going to be run?
If you really want to test a private method anyway, you can pull it into its own class. Plus, if its so complex that it really needs to best tested individually, there's a chance that it deserves to have its a chance in the first place. The other option is to just make it public whenever you need/want to test it, but not actually change the 'real' code (leaving it private). As others have said, some languages also have features that help you test these methods by exposing them slightly more, such as friend in C++, internal in C#, and package-private in Java. Occasionally the IDE's themselves even help out.
Is there any good reason whatsoever to issue errors and not warnings?
One big reason is not so you can't call them, its so other people can't call them. Picture this, you're writing a library that's going to be used by a substantial number of clients. You've marked everything they shouldn't need to call private, and all the functionality they do need is public. Programmers go ahead and start using your library, write a bunch of code with it, and produce happy customers both out of themselves and their own clients.
A few months later, you decide to spice up your massively successful library, and find that you need to do a bit of refactoring. Hence, you [rename, add/remove a parameter from, delete] some of your private methods, but are careful to keep all of your public method's interfaces exactly the same to make upgrading a seamless process. BUT in this universe, compilers only issue warnings and not errors when you access a private variable, and several of your client programmers wrote code that calls those private methods. Now, when they try to upgrade to your new version of your library, they get a bunch of real errors because they can't call those private methods anymore. Now they either have to spend time finding out what went wrong with the code and rewrite potentially large parts of it that they don't remember anything about (did I mention that this is two years in the future?). Hence, they have to completely relearn how to use your library and rewrite their client code, which is far from fun for anybody. Now they're rather displeased that you were so inconsiderate as to literally break all of their code with your upgrade and make their lives far more difficult.
Guess what, when they were fixing the code, they researched and called your new private methods, so if you ever decide to change their interface when you issue an upgrade, the whole cycle starts over again. What was slightly more convenient for you just got you a bunch of unhappy customers.
Wait, weren't they idiots for calling my private methods? Why didn't they look at the warnings? This is their fault, not mine!
Well, yes, it is their fault and they could have prevented the problem by taking care to note those warnings. But not everybody is a code-quality fanatic who wants to fix and understand warnings, and a substantial amount of people just ignore them. The thing is, you could have prevented the whole thing yourself if compilers issued errors for trying to access private variables and methods instead of warnings, because otherwise the private keyword might as well not exist at all. You may have lost a little time because those methods are harder to test, but you have gained the power to keep less intelligent people from misusing your code and blaming you for any problems it causes them down the road.
One of my favorite tenets of software development (and product design in general) is that things should be easy to use correctly and hard or impossible to use incorrectly. True private members are the embodiment of this advice because they literally make your code impossible to use correctly.
[hypothetical retort:] Well, the people using my code should be smart enough to figure it out. All I'm asking them to due is just spend a little extra time to use the code correctly.
So you are consciously refusing to spend the time necessary to improve the quality of your code and make it easier to use? Then I don't want anything to do with what your code. Obviously your time is more important than that of your clients, so I'll take the 2.5 seconds it requires to close the web page for your project and click on the next Google result. There are a lot more private members of the libraries you use than you might think, and the glorious thing is that you don't have to spend even a millisecond of your time worrying about them because they're totally hidden from you and would only distract from the easier and better way of doing things that is provided in the public interface. If everything was public or wimpy-warning-issuing private, you'd have to sift through a greater amount of functions before you actually found what you wanted.
Whenever you type private before a member function, you have just given yourself the power to change it in any way you want at any point in the future because nobody can touch it but you. The second someone else tries to access it they will get a show-stopping error because the compiler has your back and won't let them do anything stupid with your code when you've already provided perfectly everything they need in a much more usable form in your public interface.
Yes, it will make it slightly harder to test in the now, but it has also ensured that you won't have to worry about it in the future when you refactor and made your code a lot easier for other people to use. Go ahead and make it public temporarily (I kind of like your 'all-public compiler switch idea :), but don't forget to switch it back when you're done you and your clients can all have the joy working with simpler and more adaptable code. :D
The obvious reason would be that all too many people seem to ignore many (all?) warnings. In some languages (e.g., Python) it's pretty much as you've said -- something being "private" is basically advice against outside code using it directly, but the compiler doesn't enforce that.
As for how much sense that makes, I suspect it varies between languages -- in something like C++, the attitude toward them ("protect against Murphy, not Machiavelli") could be seen as justification for its being a warning instead of an error.
I think it's safe to say that in Ada, that would receive a much cooler reception, to say the least (and that's not to say that I think it would be received warmly by C++ programmers either, just that they might not hate the idea quite as much as most Ada programmers would).
On the other hand, I have to wonder about the design of a class that can't be tested (at least reasonably well) via its external interface. On the rare (should be rare, anyway) occasion that you can't, I think making the test class a friend (in C++ parlance, though many others have similar concepts) would be fairly easy to justify.
There are several advantages to having complete encapsulation:
Security. Strongly-typed OOP languages with strong encapsulation can have certain guarantees about the security of the data in the program. The Java language was designed with safety and security in mind, so certain library classes (for example, String or SecurityManager) cannot have their fields accessed. This prevents malicious code from doing Bad Things to these objects, and allows code to assume the objects are safe.
Maintainability. One of the major reasons to keep private fields and methods private is to allow the implementation to change seamlessly; as long as no updates are made to the public interface, code using the updated class can work with no changes. If you allow access to private fields and then change the implementation, you risk breaking an unbounded amount of code.
Stability/Verifiability/Testability. Classes typically impose invariants on their fields - for example, an implementation of a dynamic array might require that a field tracking how much space is used actually correspond to the total number of elements. Allowing people to arbitrarily access private fields, even with a warning, makes it possible to break these invariants. Without the ability to count on the invariants, it becomes difficult or impossible to reason about the correctness of the code. Additionally, if you do break an invariant somewhere in the code, you would conceivably have to look at every piece of code in the program that has access to the object, since any of them might be accessing the private field. With strong encapsulation, these invariants can't break, and with semiencapsulation through friends or package-private mechanisms, the amount of code to look at is bounded.
As for your question about testing - many languages allow encapsulation to be broken in certain cases; C++ has friend, Java has package-private, etc., so that the class can say "normally you can't touch these, but exceptions can be made." You can then make your testing code a friend or in the same package as the main class in order to test it more thoroughly.
Hope this helps!
The way that I see it is that you need to forget about accessing anything in an object unless you have a way of doing that in that object's interface. I think a correct OO system ought to issue errors (and not warnings) if you are attempting to directly access implementation specific private members. I attended a good talk by Kevlin Henney on this subject recently and I found it very useful, a copy may be viewed here: http://www.infoq.com/presentations/It-Is-Possible-to-Do-OOP-in-Java (note that it is mainly about java but also includes comparisons to other OO systems)
For testing most time I find that most of the code under test is covered by public interface calls. It is only on rare occasions that I need to employ something like runtime reflection to get absolutely 100% coverage.
I was about to post, "Strong enforcement of encapsulation keeps your boss from stepping on your private members." until I realized how that might sound wrong, but on second thought It's
probably just about right.
The mantra "Keep high cohesion and low coupling" (or some variant) is frequently tossed around. However, I find that it frequently conflicts with "Don't repeat yourself."
For example, I think we can all agree that it's a bad thing to re-implement std::string or use C-strings, but doesn't including std::string create another dependency and therefore increase coupling?
For another example, take std::stringstream. It inherits from iostream, which inherits from istream and ostream, which inherit from ios, which inherits from ios_base. Over all these derivations, it inherits a lot of functionality - enough to make re-implementing by hand a very bad idea. It also pulls the <ios> and <istream> headers even though only <sstream> was included, thereby increasing coupling.
How can one keep coupling low without reinventing the wheel for each module?
EDIT: If the two concepts cannot coexist, which one should be favored?
Please go through http://www.artima.com/intv/dry.html on DRY,
particularly "Most people take DRY to mean you shouldn't duplicate code. That's not its intention. The idea behind DRY is far grander than that".
Adding to this, in the example you discussed , std::string and your system are not tightly coupled as you are not relying/using any internal info of std::string. Any (internal) changes to std::string will not effect your system.
I'm going to use this opportunity to put down a number of related but different thoughts on object-oriented philosophy, as a sort of request for comments. If the admins see fit to close, I may make it a blog post instead. But I am asking questions, so I think it's a suitable community wiki.
Suppose I have an abstract class Bird. Supposing that we're taking a fairly typical OO philosophy here, Bird is an object that is capable of maintaining and changing state. The obvious example of a state for this simple model is whether or not our Bird is flying or not.
So, Bird has a method fly().
Or does it? I've seen this very simple example given in introductory books, and in my opinion, it's subtly misleading. If you're maintaining state, you don't need to tell an object to continue to be in a given state; it just is. That's what an object does. So really, you want Bird to have a method takeoff().
Suppose at some point we created our Bird object from another class, Egg. At some point, we might call a method Egg.hatch() which has the return type Bird. Assuming we're coding to an interface, Egg knows what type of bird it's an egg from, and the returned instance from hatch() knows what type of bird it is also. But we can't really say that there's anything in common between an Egg and a Bird that hatches from it. are we really saying that we want specific implementations of these classes to have a reference to an instance of some sort of BirdArchetype that represents the characteristics of all instances of that species, so that both Egg and Bird know their own kind, independently but consistently? Is there any well-known pattern for this kind of relationship?
Whose responsibility is it to ensure that the Egg changes state so that it's no longer capable of hatching again, or doing most of the other things that eggs normally do?
Philosophically, do we want to introduce the concept of a breakable object? Perhaps Egg should be coded so that it throws an exception if you try to do any of the things that change its state more than once. It's up to the calling code to keep track of the client object's lifecycle.
What else can we do with an egg? Perhaps we could cook it. If it were me, I'd code this so that calling cook() on an egg 'breaks' the Egg instance and returns an instance of a new object, FriedEgg. How is this different to telling a Bird to takeoff()? It's absurd to suggest that taking off makes it a fundamentally different bird. Yet the reasoning is the same; a bird that's flying (usually) can't do most of the other things that birds do, because it's busy. Arguably then, Bird is breakable as while it's in the flying state, calling some of its other methods won't work.
I suppose the only real distinction here is that the Bird can become un-broken. Is the concept of thermodynamic reversibility really that crucial to programming very simple models like this?
This is why I don't particularly care for modeling the real world and using that to explain/define OO philosophy.
Unless you're building a simulator (in which the answers to these questions become immediately obvious when one looks at the simulator context) it's far too easy to go off into the weeds and confuse yourself.
Perhaps having mutating state in an object is all wrong ;-)
Shouldn't Bird.takeoff() return a FlyingBird which can land()? (It clearly doesn't make sense for a bird which is not flying to land.)
Similarly, for an egg:
egg = Egg()
incubatedEgg = egg.incubate()
bird = incubatedEgg.hatch()
However, the return type of an operation might not always be limited to one value. For instance, during incubating the embryo could die.
egg = Egg()
egg.incubate() ->
if "still alive" (aliveEgg) ->
aliveEgg.hatch()
else "died in incubation" (deadEgg) ->
deadEgg.discard()
Happy philosophizing :-)
"Fly" reasonably means "begin flying!" (I would say it's used more often that way in natural speech). You don't have to interpret it to mean "sustain flight!" That's why we reasonably use "fly" and "land" (in natural english) as antonyms. (Evidence for the skeptical)
You're assuming the egg is created ex nihilo in your model. That's not really a reasonable assumption. The bird came from an egg, but the egg came from a bird. Assuming a reasonable purpose for modelling an egg, it's to model the time-delay procreation of bird species. That means the baby bird is formed by the sexual reproduction of two other birds. The vehicle of generation of the baby bird is the egg. The egg doesn't need to know what kind of bird is in it; that bird was created by the parents and wrapped in a generic egg (that perhaps has variable properties based on the mother.
In other words, your model isn't really well-formed with regard to this question.
It's the egg's responsibility to see that it doesn't hatch again (a check in the hatch function). See the discussion of "imperatives" below.
The concept of "breakable" is probably superfluous to your model. Are you concerned with the egg's breakability, or it's hatchability? If the breaking is a significant part of the data you are trying to model (for example, if anything in your model essentially depends upon the brokenness of the egg, then model it. Either way, hatching doesn't happen when the egg breaks, it happens when the egg hatches. One of the consequences of hatching is breaking, not the other way around.
The reason egg.cook() seems wrong is because it is. Verb methods should take the object as the subject. Your statement "egg.cook()" is telling the egg to cook, which is rarely how we intend to use the verb "cook" in commands with respect to eggs. You probably really want a chef.cook(food) -- where the "food" arg is anything that derives from food (or better yet, has a Role (a la Moose) "isCookable".
Remember, programming languages are imperative languages; interrogation, exhortation, and other "natural language" functions are inherently misplaced in programming languages, even if we achieve some version of it through commands (we emulate interrogation through commands; "TELL ME YOUR STATE!" is the imperative interpretation of the interrogative "What's your state?")
A good program removes as much information as possible from it's models while meeting all functional specifications. That is, you have a specification (preferably in the form of a test suite). Meaningless information is information that isn't necessary to pass any of the tests. So, you implement one feature at a time, introducing the cookability of eggs when you have a test that quantifies that property via specification (again, read: tests). If you implement breakability of objects and realize that you can accomplish the same tests without it, you improve the program by removing it. Now, a really clever programmer is able to build his models in such a way as that they are extensible -- that is, that new properties can be added easily as new requirement specifications are produced.
Note also, it is possible to have a bad specification. If you can't tell whether something is superfluous or not, the specs (read: tests) are either incorrect or incomplete with respect to that aspect of the program.
Seems more like an issue of naming. For example, in java you might query the bird's state as "getFly()", where you call it "fly()" as python would. Here, you're telling it to take off like you're changing the state of the bird, which is a little ambiguous to the reader of the code.
In the case of the Egg, I don't see any problem with the species of bird the egg handles as being part of the egg. As for who handles whether the egg is hatched, you could just keep a reference inside the egg to the bird that's hatched. An egg physically hatches, so it's up to me to see if it's hatched, so I don't stick an egg shell in an incubator for months expecting a chicken to pop out. In my opinion, it's up to the calling code to know who has hatched. If an egg hatches a bird, it's okay to keep a reference to that bird inside the egg if that helps keep your program organized. I would think it would be a convenience to anyone who uses that class.
There's no reason why you can't make an egg also be in a fried state, where any attempts to hatch it fail.
As to the absurdity of a different object for a bird in flight being a different bird than a grounded one, that's hard to justify. We may reason in our minds that it's the same bird, but in respect to object-oriented programming, we could certainly make them different objects if that meets the needs of the program. Is a bird more like an egg or a plane?
As to your Bird being breakable while it's in flight, is that the bird's fault? If my dog were in it's kennel, would it be broken if I told it to go fetch a ball?
Whose responsibility is it to ensure that the Egg changes state so that it's no longer capable of hatching again, or doing most of the other things that eggs normally do?
This depends on whether you want to keep around the egg remains in your model or consider the egg gone.
If the former, the hatch() method sets a private hatched flag to true and any of the egg's methods which depend on it being un-hatched (including hatch() itself) check that flag and fail (whether the failure is via return code or a raised exception, depends). The latter, might be doable with certain designs but don't really see any need to.
Or does it? I've seen this very simple example given in introductory books, and in my opinion, it's subtly misleading. If you're maintaining state, you don't need to tell an object to continue to be in a given state; it just is. That's what an object does. So really, you want Bird to have a method takeoff().
I think that your problem here is with imprecise word usage, not with software development. The authors of the fly() solution are usng "fly" verb in a sense of "start flight", e.g. as a synonym of "takeoff". Whether that's a 100% valid English usage or not is above my pay grade as ESL developer, but I certainly agree that "takeoff" is a significantly less ambiguous method name.
... so that both Egg and Bird know their own kind, independently but consistently? Is there any well-known pattern for this kind of relationship?
I'm not sure if there's an official "pattern", but having an egg constructor (or factory if you go with factory) implemented in a generic "Bird" class pass the bird type to a new "Egg" object and vice versa having "Egg" object pass its bird type to the constructor (or factory) of "Bird" is very widely used.
What else can we do with an egg? Perhaps we could cook it. If it were me, I'd code this so that calling cook() on an egg 'breaks' the Egg instance and returns an instance of a new object, FriedEgg. How is this different to telling a Bird to takeoff()
As a commenter already pointed out, the above is an OO design problem - the egg doesn't cook itself. Therefore you can't implement "cook" method on the egg in isolation (though some "set status to cooked" method might be needed for your model, if for no other reason than make it unhatcheable. However, the FriedEgg thing needs to be constructed (if needed) by a Cook object's "cook_egg" method - which also calls "set status to cooked" on an egg.
I don't think this really comes under OO philosophy. In my opinion, you're mixing business logic with design patterns.
To address your concerns in general, if you have a method that changes the state of the object, which can cause another method to throw an exception based on this new (changed) state, it is desirable to have a state-inspection method so that you don't have to explicitly handle the exception each time.
In your case, let's say you did egg.fry() (on another note, an egg cannot fry itself. So maybe you need a Cook class that takes an egg as an argument to a fry method and returns a FriedEgg instance), and after that you did egg.hatch(). The second call must return an exception. Instead of forcing the user of your class to put that call in an explicit try...catch block, you should provide a state-inspection method; something like isFried() or isHatchable(). Then instead of:
try {
egg.hatch();
}
catch(UnhatchableException e) {
...
}
You have:
if(egg.isHatchable()) {
egg.hatch();
}
So it is the responsibility of the calling code to check and see what state the object is in, before it performs an operation that can potentially throw an exception.
Now assuming you had a Cook class and a method called fry and you did Cook.fry(egg) which returns a FriedEgg instance, what would happen if you call hatch() on it? Common sense would tell you that a fried egg cannot hatch anything!
In this case, you should have an Egg interface with LiveEgg (i.e., an egg that can hatch) and FriedEgg both implementing the Egg interface. The difference however, is in the implementation of the hatch() method in FriedEgg; it would have to throw an UnsupportedOperationException because you cannot hatch a fried egg.
The problem with modeling most real-world scenarios (like cars, animals etc.) is that sometimes they don't help in adequately explaining the relationships. This is due to the fact that OO concepts are pretty abstract.
Anyway, hope this helps.
Apart from unambiguous clarity, why should we stick to:
car.getSpeed() and car.setSpeed(55)
when this could be used as well :
car.speed() and car.speed(55)
I know that get() and set() are useful to keep any changes to the data member manageable by keeping everything in one place.
Also, obviously, I understand that car.speed() and car.speed(55) are the same function, which makes this wrong, but then in PHP and also in Zend Framework, the same action is used for GET, POST, postbacks.
In VB and C# there are "properties", and are used by many, much to the disgust of purists I've heard, and there are things in Ruby like 5.times and .each, .to_i etc.
And you have operator overloading, multiple inheritance, virtual functions in C++, certain combinations of which could drive anyone nuts.
I mean to say that there are so many paradigms and ways in which things are done that it seems odd that nobody has tried the particular combination that I mentioned.
As for me, my reason is that it is short and cleaner to read the code.
Am I very wrong, slightly wrong, is this just odd and so not used, or what else?
If I still decide to stay correct, I could use car.speed() and car.setSpeed(55).
Is that wrong in any way (just omitting the "get" )?
Thanks for any explanations.
If I called car.speed(), I might think I am telling the car to speed, in other words to increase speed and break the speed limit. It is not clearly a getter.
Some languages allow you to declare const objects, and then restrict you to only calling functions that do not modify the data of the object. So it is necessary to have seperate functions for modification and read operations. While you could use overloads on paramaters to have two functions, I think it would be confusing.
Also, when you say it is clearer to read, I can argue that I have to do a look ahead to understand how to read it:
car.speed()
I read "car speed..." and then I see there is no number so I revise and think "get car speed".
car.getSpeed()
I read "for this car, get speed"
car.setSpeed(55)
I read "for this car, set speed to 55"
It seems you have basically cited other features of the language as being confusing, and then used that as a defense for making getters/setters more confusing? It almost sounds like are admitting that what you have proposed is more confusing. These features are sometimes confusing because of how general purpose they are. Sometimes abstractions can be more confusing, but in the end they often serve the purpose of being more reusable. I think if you wanted to argue in favor of speed() and speed(55), you'd want to show how that can enable new possibilities for the programmer.
On the other hand, C# does have something like what you describe, since properties behave differently as a getter or setter depending on the context in what they are used:
Console.WriteLine(car.Speed); //getter
car.Speed = 55 //setter
But while it is a single property, there are two seperate sections of code for implementing the getting and setting, and it is clear that this is a getter/setter and not a function speed, because they omit the () for properties. So car.speed() is clearly a function, and car.speed is clearly a property getter.
IMHO the C# style of having properties as syntatic sugar for get and set methods is the most expressive.
I prefer active objects which encapsulate operations rather than getters and setters, so you get a semantically richer objects.
For example, although an ADT rather than a business object, even the vector in C++ has paired functions:
size_type capacity() const // how many elements space is reserved for in the vector
void reserve(size_type n) // ensure space is reserved for at least n elements
and
void push_back ( const T& ) // inserts an element at the end
size_type size () const // the number of elements in the vector
If you drive a car, you can set the accelerator, clutch, brakes and gear selection, but you don't set the speed. You can read the speed off the speedometer. It's relatively rare to want both a setter and a getter on an object with behaviour.
FYI, Objective-C uses car.speed() and car.setSpeed(55) (except in a different syntax, [car speed] and [car setSpeed:55].
It's all about convention.
There is no right answer, it's a matter of style, and ultimately it does not matter. Spend your brain cycles elsewhere.
FWIW I prefer the class.noun() for the getter, and class.verb() for the setter. Sometimes the verb is just setNoun(), but other times not. It depends on the noun. For example:
my_vector.size()
returns the size, and
my_vector.resize(some_size)
changes the size.
The groovy approach to properties is quite excellent IMHO, http://groovy.codehaus.org/Groovy+Beans
The final benchmarks of your code should be this:
Does it work correctly?
Is it easy to fix if it breaks?
Is it easy to add new features in the future?
Is it easy for someone else to come in and fix/enhance it?
If those 4 points are covered, I can't imagine why anybody would have a problem with it. Most of the "Best Practices" are generally geared towards achieving those 4 points.
Use whichever style works for you, just be consistent about it, and you should be fine.
This is just a matter of convention. In Smalltalk, it's done the way you suggest and I don't recall ever hearing anybody complain about it. Getting the car's speed is car speed, and setting the car's speed to 55 is car speed:55.
If I were to venture a guess, I would say the reason this style didn't catch on is because of the two lines down which object-oriented programming have come to us: C++ and Objective-C. In C++ (even more so early in its history), methods are very closely related to C functions, and C functions are conventionally named along the lines of setWhatever() and do not have overloading for different numbers of arguments, so that general style of naming was kept. Objective-C was largely preserved by NeXT (which later became Apple), and NeXT tended to favor verbosity in their APIs and especially to distinguish between different kinds of methods — if you're doing anything but just accessing a property, NeXT wanted a verb to make it clear. So that became the convention in Cocoa, which is the de facto standard library for Objective-C these days.
It's convention Java has a convention of getters and setters C# has properties, python has public fields and JavaScript frameworks tend to use field() to get and field(value) to set
Apart from unambiguous clarity, why should we stick to:
car.getSpeed() and car.setSpeed(55)
when this could be used as well : car.speed() and car.speed(55)
Because in all languages I've encountered, car.speed() and car.speed(55) are the same in terms of syntax. Just looking at them like that, both could return a value, which isn't true for the latter if it was meant to be a setter.
What if you intend to call the setter but forget to put in the argument? The code is valid, so the compiler doesn't complain, and it doesn't throw an immediate runtime error; it's a silent bug.
.() means it's a verb.
no () means it's a noun.
car.Speed = 50;
x = car.Speed
car.Speed.set(30)
car.setProperty("Speed",30)
but
car.Speed()
implies command to exceed speed limit.