Head First Design Patterns: A Brain-Friendly Guide
All
Stack Overflow 99
This Year
Stack Overflow 4
This Month
Stack Overflow 25
https://www.amazon.com/Head-First-Design-Patterns-Brain-Frie...
First of all, applause for the great start.
Here are some criticisms/suggestions I would like to offer. Keep in mind, I am not assuming your level/experience as a software developer:
Functions with smaller size. You see, most of the functions that you have written is lengthy because of the sql statements. Here comes my second point.
Separate business logic, application code, data storage related stuff etc. Keep things modular. That separation is important because you want things to be maintainable and reusable. Your code should be open for extension, but close for modification. If that does not make sense to you, that's perfectly fine, just start from this
On that note, since you are using flask, might I suggest using flask-sqlalchemy instead of sqlalchemy? You may like it better. I know you have mentioned
> I force myself to write raw SQL Request to get better with SQL
while that is commendable, it is not really a good idea to write raw sqls in production code if there are ORM library alternatives available. Remember, it's not always you that is going to read/modify the code. While ORM syntax will be fairly universal, your style of writing SQL may vary starkly from other people - which is what creates confusion and lets errors sneak in. Even if you want to do that, maybe keep the raw sql in separate modules (point 2).
Instead of computing everything and then sending the result along with the page, maybe create api endpoints for specific sections; render page with bare minimum info and from the webpage make multiple calls to update the page sections when required. This way, it will be far more responsive, user will not be waiting for you to finish all the computation and if you detect any change in any section of the page, you can just update that particular section with an appropriate api call, thereby avoiding a whole page reload. Design choices.
PEP8. You don't have to blindly follow every rule - just make sure you understand why those rules are there, and that if you are breaking any, you know that it is absolutely necessary for accomplishing what you want. Again, what you want may not always be what you actually need - so be really careful.
This is something I wish I knew earlier - Design Patterns. Without going into much details, I would recommend reading these books to start with and really understand instead of memorizing:
Documentation is also important. Follow the good practices there. A remarkable reference would be Ken Reitz's Requests library.
Finally, remember that all these are just suggestions, and you may already know them. You will decide which ones to take and which ones to leave behind based on your situation.
Again, great job (I also learnt something from this). Just make sure you keep running.
I generally agree, but the problem with patterns is some folks try to shoehorn everything into a pattern sometimes turning something simple into something more complex than it needs to be.
​
I find that following SOLID with YAGNI at the back of your mind tends to be what seems to work best for me
Along the lines of patterns: I'd recommend Head First Design Patterns
As Rommik mentioned, you could apply a design pattern for this, but I would use the Decorator pattern rather than Strategy since you are wanting to chain calls. If the code is simple, then I would go with one of the nicely structured answers to prevent nesting. However, if it is complex or requires dynamic chaining, then the Decorator pattern is a good choice. Here is a yUML class diagram:
Here is a sample LinqPad C# program:
The best book to read on design patterns, IMHO, is Head First Design Patterns.
I think in your example a factory seem useless because your Cake and Chocolate constructors don't need any args.
A factory is useful when you want to construct a complex object with many args to respect the DIP (Dependency Inversion Principle) and avoid embarrassing couplings.
In addition, your example seems to violate the LSP (Liskov Substitution Principle). Cake and Chocolate classes have nothing in common, and as evidence, your abstract super class is named Item which is a very generic name.
For me, with complex uncommon objects, the choice of one factory by class is better, and effectively respect the OCP (Open Closed Principle).
Your first example can be useful to instantiate classes which inherits the same superclass, but using your classes as arg and reflection (using java.lang.reflect) to call the constructor not just using String evaluation. (Your IDE is not able to autocomplete that) and in case of no match don't return null, Throw an IllegalArgumentException, it's more correct.
Like this :
and use it like this :
If you have no dependencies you can implement the createItem() method as static directly in your abstract Item class.
See this book, it's a great resource : Head First Design Patterns
OCP is just Open for extension Close for modification Principle. If you need to open for modification your factory to add a new class (a new case to manage in a switch or a if), no, your factory is not "OCP".
You sould'nt calculate a tax in a constructor, a constructor should just... construct an object.. You could use a pattern like strategy to have many taxesCalculator and inject them into a constructor, with an IOC (Inversion of Control) mechanism like dependencies injection or in a simple way with.....a factory (it's acceptable), but not with a simple static method in your class.
I'm sorry for my bad english, it's difficult for me to answer to a complex question like this.
I wouldn't worry about having SpriteEntity_2D and SpriteEntity_3d as separate classes. I think your overall design is pretty good but it is hard to say without knowing the full extent of the project. If you haven't already, you should read about component based systems for games. There is some good stuff here: https://stackoverflow.com/questions/1901251/component-based-game-engine-design
Also, a good book on design(not specifically related to gaming) is http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124/ref=sr_1_sc_1?s=books&ie=UTF8&qid=1326855704&sr=1-1-spell
In answer to your question:
You should read about OOP patterns. This book is a great introduction.
http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124
In response to your error, I think you are not giving us the whole picture. The error refers to class
lin
being extended, but in the code there are no classes extendinglin
.[https://toptalkedbooks.com/amzn/0596007124)
https://toptalkedbooks.com/amzn/0201633612
https://toptalkedbooks.com/amzn/0596007124
https://toptalkedbooks.com/amzn/0735619670
And you could check stack overflow for question on general programming books. I would always go for a general concept
functional programming
overhow to functional programming in haskell
.But I'll be perfectly honest, I'm a victim of the curse of knowledge so I honestly don't know how one should start. What I do remember is that I had huge problems with syntax (how do I tell language X to do a
for (Employee e in employeeList)
, how do you write a switch and stuff, why would I ever need a ternary operator, and like that.But once you master the basics of how to write x, y and z in your preferred language, you absolutely need to understand design patterns, you absolutely need to understand how code is supposed to be written, you absolutely need to understand data structures, you absolutely need to understand inheritance and polymorphism, you absolutely need to understand lambdas and functional programming.
Then you can get to the more "neat" stuff like the benefits of having immutables, and "job specific stuff" like how to solve race conditions in threading; sockets and web communication, etc.
Sure :)
EDIT: Added links to Amazon just in case anyone wants to see reviews.
[$1 Or More Tier]
Head First Ruby
Head First C
Head First Object-Oriented Analysis and Design
Head First SQL
Head First Statistics
[$8 Or More Tier]
Head First Javascript Programming
Head First PMP
Head First HMTL and CSS
Head First C#
Head First Agile
[$15 Or More Tier]
Head First Design Patterns
Head First Java
Head First Python
Head First Learn to Code
Head First Android Development
I enjoyed reading the headfirst patterns book as a refresher
[1] https://sophia.javeriana.edu.co/~cbustaca/docencia/POO-2016-... [2] https://www.amazon.com/Head-First-Design-Patterns-Brain-Frie...
Hope this helps. It describes the various types of factories. I used Head First Design Patterns as my reference. I used yuml.me to diagram.
Static Factory
Is a class with a Static Method to product various sub types of Product.
Simple Factory
Is a class that can produce various sub types of Product. (It is better than the Static Factory. When new types are added the base Product class does not need to be changed only the Simple Factory Class)
Factory Method
Contains one method to produce one type of product related to its type. (It is better than a Simple Factory because the type is deferred to a sub-class.)
Abstract Factory
Produces a Family of Types that are related. It is noticeably different than a Factory Method as it has more than one method of types it produces. (This is complicated refer to next diagram for better real-life example).
Example From The .NET Framework
DbFactoriesProvider is a Simple Factory as it has no sub-types. The DbFactoryProvider is an abstract factory as it can create various related database objects such as connection and command objects.
I've taken a class in college that spent two weeks around design patters, and read the Gang of Four book to no avail. Understanding what each pattern served for and how to use them to fit my problems was very hard for me, a developer that didn't have much experience in OO programming.
The book that really made it click for me was Head First Design Patterns. It starts by showing a problem, different approaches the developers considered, and then how they ended up using a design pattern in order to fix it. It uses a very simple language and keeps the book very engaging.
Design patterns end up being a way to describe a solution, but you don't have to adapt your classes to the solution. Think of them more as a guide that suggest a good solution to a wide array of problems.
Let's talk about SOLID:
A book I'd highly recommend to you for MVC in swing would be "Head First Design Patterns" by Freeman and Freeman. They have a highly comprehensive explanation of MVC.
Um, in case you're interested, you could download a fairly entertaining song about the MVC pattern from here!
One issue you may face with Swing programming involves amalgamating the SwingWorker and EventDispatch thread with the MVC pattern. Depending on your program, your view or controller might have to extend the SwingWorker and override the
doInBackground()
method where resource intensive logic is placed. This can be easily fused with the typical MVC pattern, and is typical of Swing applications.EDIT #1:
Additionally, it is important to consider MVC as a sort of composite of various patterns. For example, your model could be implemented using the Observer pattern (requiring the View to be registered as an observer to the model) while your controller might use the Strategy pattern.
EDIT #2:
I would additionally like to answer specifically your question. You should display your table buttons, etc in the View, which would obviously implement an ActionListener. In your
actionPerformed()
method, you detect the event and send it to a related method in the controller (remember- the view holds a reference to the controller). So when a button is clicked, the event is detected by the view, sent to the controller's method, the controller might directly ask the view to disable the button or something. Next, the controller will interact with and modify the model (which will mostly have getter and setter methods, and some other ones to register and notify observers and so on). As soon as the model is modified, it will call an update on registered observers (this will be the view in your case). Hence, the view will now update itself.You have to make up your mind whether the so called apple-specific method (in this case
checkPrice()
) is really specific to Apple. Or it is actually generally applicable to all fruits.A method that is generally applicable should be declared in the base class
Assuming the answer is yes (in this case it does seems to be yes), then you should declare the method in the base class. In this case you can iterate through all the different types of fruits, and all of them would accept the method
checkPrice()
, so you don't even need to make a special case for apples.A method that isn't generally applicable can be declared in an interface
What if the answer is no? Let's assume we need another method called
getJuicePrice()
, and we further assume that only some fruits can be made into juice (apple juice, orange juice) but other cannot (pineapple? durian?). In this case, a simple solution is to declare an interface, and only the fruits for which the method is appropriate would implement the interface. So let's say this interface isJuiceBehavior
And all fruits for which juice behavior is applicable (yes for
Apple
, no forDurian
) would implement the interface:And then in your loop, what you check is whether a
fruit
isinstanceof
the interface:This solution would work for simple cases, but in more complicated cases, you may notice that you start to duplicate a lot of implementation code for
getJuicePrice()
for different types of fruits. This leads to the next topicDesign Pattern: Strategy
You may want to start thinking about the Design Pattern called Strategy, which further encapsulates
JuiceBehavior
and make it into a family of classes representing different juice behaviors. It also let you set different types of fruits to take different implementations ofJuiceBehavior
. I won't go into the details here. But you can read up on that on some books about Design Patterns. Such asThe Decorator Pattern is probably the most straight forward one to use and would be a good one to extend concrete objects functionality and/or characteristics.
Here is some light reading: Head First Design Patterns - CH3 pdf
FYI, couple must have's for learning and referencing design patterns regardless your language of choice:
1) Head First Design Patterns
2) Patterns for Enterprise Application Architecture
3) Design Patterns: Elements of Reusable Object-Oriented Software
And sites:
1) DoFactory
2) StackOverflow Design Patterns Newbie
There are a few others, I'll have to dig them up.
To study design patterns I would recommend going first with the book Head First Design Patterns and try to build simple examples yourself. Once you do that you will start recognizing patters everywhere you look :). Once you know what they look like you can pick up any popular open source project and you will find ton of examples there.
Actually you don't even have to look much as there are many examples of design patterns in jdk you are using already: Examples of GoF Design Patterns in Java's core libraries
Should I using other patterns?
No, you should not insist on a single pattern.
No design pattern books will ever advise you to use a single pattern. Just like you cannot chop all ingredients in one single way (are you going to dice the spaghetti?), you cannot organise all logic in one single pattern.
Sure, you can make all your Objects use the initialiser pattern, and don't use constructors at all. This is ok. Been there, done that. I like it.
But these objects can be used with Builder or Abstract Factory (if it make things simpler). As long as the builders/factories themselves have initialiser, and that they properly initialise the created objects, then your use of the initialiser pattern will be consistent. Outside of creational patterns, it is usually good to organise objects with structural and behavioural patterns. They do not conflict with initialiser at all.
For example, look at DOM. All nodes are created by the Document object - elements, text nodes, comments, even events. This is the Factory pattern.
Yet the Document object is also a Facade! From it you access the whole system's status, objects, data, you can even write to it! Every DOM operation starts from the Document, it is the Facade of the DOM system.
DOM nodes also implements multiple patterns. They are organised in Composite, let you listen to events with Observer and Command, and handle events in a Chain of Responsibility. They are certainly parsed by an Interpreter, DocumentFragment is a Proxy, svg elements are implemented as Decorators, and createNodeIterator obviously gives you an Iterator.
The point is, good object-oriented design will yield multiple design patterns as a result, intentional or not.
What are the secrets for good code appearance
I think the best looking code is the one that is easiest to understand to you, and the way you read code changes as you gain more experience.
For example my style is too condensed for most programmers, but to me it strikes a good balance. So do develop your own style - you are not me, and you are not yesterday's you either.
Remember this as we go through the styles.
At the lowest level we have coding style - most importantly indent and bracket.
This one is simple, pick the one you like and stick with it. There are language specific styles, and they are often good starting points. Configure your IDE's formatter so that you can format all your code with hotkey.
Above the code syntax we have comment style and naming convention.
Setting rules on comment is fine, sometimes it is necessary for documenting tools. Avoid too much comment in practice. You may also want to decide your namespace and your stand on naming function expressions.
Above these structures, we have logic conventions.
The same code logic can often be done in many ways, some more 'beautiful' than the others in your eyes. Look at this example.
I picked the second style on first sight: no duplicate, logic is sectioned cleanly, format is not my style but reasonable. But many programmers would prefer the first style: logic is plain as day, a few duplications is worth it. While abstract, this level is quite deep - present your logic the wrong way actually increase the chance an experienced programmer read it wrong.
Finally, we arrives at the level of design pattern, about as far as code beauty goes.
The key to keep your code structure beautiful, is using the right patterns at right level to consistently accomplish loose coupling and code reuse, while avoiding pitfalls and over-design.
There are quite some books about beautiful code, and then there are even more books about designing and implementing beautiful software. (Decide for yourself which are beyond your level.) Knowledge is as important as experience, and you can gain them only by spending your time to study, to write, and to revise/refactor your apps.
Feel free to change your mind as you explore and experiment with your code. Changing your mind is a good sign of learning.
But first, familiarise yourself with design patterns. Just don't forget, they are the generic result of applying object-oriented principals to common tasks. It is still up to you to do the design.
Design Patterns Are Not Silver Bullets.
There are some great OOP books from Head First covering Object-Oriented Analysis and Design and Object-Oriented Design Patterns.