Head First Design Patterns: A Brain-Friendly Guide

Category: Programming
Author: Eric Freeman, Elisabeth Freeman, Kathy Sierra, Bert Bates
4.5
All Stack Overflow 99
This Year Stack Overflow 4
This Month Reddit 3

Comments

by topkai22   2022-03-20
This made me think of “Head First Design Patterns”, a book whose content has aged fairly well, but whose cover and typesetting have not.

https://www.amazon.com/Head-First-Design-Patterns-Brain-Frie...

by CodeTamarin   2021-12-10

A book called Headfirst with Design Patterns and this video series alongside the book.

...and yes the Gang Of Four is still relevant.

by both-shoes-off   2021-12-10

Google "c# github projects for beginners". Theres a whole bunch of interesting stuff out there. You could also download/fork a github repo and try to extend a project, or build on top of it.

I think this repo has been posted here before, but learning design patterns is really useful prior to designing something from ground up. https://github.com/Finickyflame/DesignPatterns

Here's a good beginner's book on design patterns. https://www.amazon.com/dp/0596007124/ref=cm_sw_r_cp_apa_i_FmHsDbGWQ0NTJ

by auctorel   2021-12-10

An alternative to the gang of 4 book which is easier to digest is the head first guide

Head First Design Patterns https://www.amazon.co.uk/dp/0596007124/ref=cm_sw_r_cp_apa_i_jGIzDb57C3ACR

by macando   2020-07-24
Why's (Poignant) Guide to Ruby

https://www.amazon.com/Head-First-Design-Patterns-Brain-Frie...

by invictus08   2019-07-21

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:

  1. 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.

  2. 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

  3. 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).

  4. 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.

  5. 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.

  6. 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:

    • Head First Design Patterns
    • Clean Code - focused more on java, but you'll get the ideas are pretty much language agnostic
    • Fluent Python
  7. 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.

by xunlyn85   2019-07-21

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

by anonymous   2019-07-21

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:

yUML class diagram

Here is a sample LinqPad C# program:

void Main()
{
    IOperation step = new StepC();
    step = new StepB(step);
    step = new StepA(step);
    step.Next();
}

public interface IOperation 
{
    bool Next();
}

public class StepA : IOperation
{
    private IOperation _chain;
    public StepA(IOperation chain=null)
    {
        _chain = chain;
    }

    public bool Next() 
    {
        bool localResult = false;
        //do work
        //...
        // set localResult to success of this work
        // just for this example, hard coding to true
        localResult = true;
        Console.WriteLine("Step A success={0}", localResult);

        //then call next in chain and return
        return (localResult && _chain != null) 
            ? _chain.Next() 
            : true;
    }
}

public class StepB : IOperation
{
    private IOperation _chain;
    public StepB(IOperation chain=null)
    {
        _chain = chain;
    }

    public bool Next() 
    {   
        bool localResult = false;

        //do work
        //...
        // set localResult to success of this work
        // just for this example, hard coding to false, 
            // to show breaking out of the chain
        localResult = false;
        Console.WriteLine("Step B success={0}", localResult);

        //then call next in chain and return
        return (localResult && _chain != null) 
            ? _chain.Next() 
            : true;
    }
}

public class StepC : IOperation
{
    private IOperation _chain;
    public StepC(IOperation chain=null)
    {
        _chain = chain;
    }

    public bool Next() 
    {
        bool localResult = false;
        //do work
        //...
        // set localResult to success of this work
        // just for this example, hard coding to true
        localResult = true;
        Console.WriteLine("Step C success={0}", localResult);
        //then call next in chain and return
        return (localResult && _chain != null) 
            ? _chain.Next() 
            : true;
    }
}

The best book to read on design patterns, IMHO, is Head First Design Patterns.

by anonymous   2019-07-21

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 :

import java.lang.reflect.Constructor;

public class SimpleItemFactory {
    public <T extends Item> T createItem(Class<? extends Item> itemClass) {
        try {
            // construct your dependencies here
            // and inject them in the getConstructor
            Constructor<? extends Item> constructor = itemClass.getConstructor();
            return (T)constructor.newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException();
        }
    }
}

and use it like this :

class Client {
    public static void main(String[] args) {
        SimpleItemFactory factory = new SimpleItemFactory();
        IceCream iceCream = factory.createItem(IceCream.class);
        System.out.println(iceCream);
        Cake cake = factory.createItem(Cake.class);
        System.out.println(cake);
        Chocolate chocolate = factory.createItem(Chocolate.class);
        System.out.println(chocolate);
    }
}

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.

by anonymous   2019-07-21

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

by anonymous   2019-07-21

In answer to your question:

What should I do to make many different MovieClips share one behaviour?

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 extending lin.

by zerogvt   2019-01-20
Head first is a much better option IMO https://www.amazon.com/Head-First-Design-Patterns-Brain-Frie...
by IllusionsMichael   2019-01-13

[https://toptalkedbooks.com/amzn/0596007124)

by ZukoBestGirl   2019-01-13

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 over how 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.

by thorin   2018-09-28
I used to like Thinking in Java [1], but not sure how it holds up now, I think I read the first the edition.

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...

by user295190   2018-03-19

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.

Static Factory

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)

Simple Factoryt

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.)

Factory Method

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).

Abstract Factory

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.

Abstract Factory From .NET Framework ​​​

by anonymous   2018-03-19

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:

  1. Single responsibility. A class should have only one responsibility. That means that for example, a Person class should only worry about the domain problem regarding the person itself, and not for example, its persistence in the database. For that, you may want to use a PersonDAO for example. A Person class may want to keep its responsibilities the shortest it can. If a class is using too many external dependencies (that is, other classes), that's a symptom that the class is having too many responsibilities. This problem often comes when developers try to model the real world using objects and take it too far. Loosely coupled applications often are not very easy to navigate and do not exactly model how the real world works.
  2. Open Closed. Classes should be extendible, but not modifiable. That means that adding a new field to a class is fine, but changing existing things are not. Other components on the program may depend on said field.
  3. Liskov substitution. A class that expects an object of type animal should work if a subclass dog and a subclass cat are passed. That means that Animal should NOT have a method called bark for example, since subclasses of type cat won't be able to bark. Classes that use the Animal class, also shouldn't depend on methods that belong to a class Dog. Don't do things like "If this animal is a dog, then (casts animal to dog) bark. If animal is a cat then (casts animal to cat) meow".
  4. Interface segregation principle. Keep your interfaces the smallest you can. A teacher that also is a student should implement both the IStudent and ITeacher interfaces, instead of a single big interface called IStudentAndTeacher.
  5. Dependency inversion principle. Objects should not instantiate their dependencies, but they should be passed to them. For example, a Car that has an Engine object inside should not do engine = new DieselEngine(), but rather said engine should be passed to it on the constructor. This way the car class will not be coupled to the DieselEngine class.
by anonymous   2018-03-19

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.

Brief Summary

  1. You're the user--you interact with the view. The view is your window to the model. When you do something to the view (like click the Play button) then the view tells the controller what you did. It's the controller's job to handle that.

  2. The controller asks the model to change its state. The controller takes your actions and interprets them. If you click on a button, it's the controller's job to figure out what that means and how the model should be manipulated based on that action.

  3. The controller may also ask the view to change. When the controller receives an action from the view, it may need to tell the view to change as a result. For example, the controller could enable or disable certain buttons or menu items in the interface.

  4. The model notifies the view when its state has changed. When something changes in the model, based either on some action you took (like clicking a button) or some other internal change (like the next song in the playlist has started), the model notifies the view that its state has changed.

  5. The view asks the model for state. The view gets the state it displays directly from the model. For instance, when the model notifies the view that a new song has started playing, the view requests the song name from the model and displays it. The view might also ask the model for state as the result of the controller requesting some change in the view.

enter image description here Source (In case you're wondering what a "creamy controller" is, think of an Oreo cookie, with the controller being the creamy center, the view being the top biscuit and the model being the bottom biscuit.)

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.

by anonymous   2017-08-20

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 is JuiceBehavior

package fruitcart;

import java.math.BigDecimal;

public interface JuiceBehavior {
    BigDecimal getJuicePrice();
}

And all fruits for which juice behavior is applicable (yes for Apple, no for Durian) would implement the interface:

package fruitcart;

import java.math.BigDecimal;

public class Apple implements JuiceBehavior {

    @Override
    public BigDecimal getJuicePrice() {
        // FIXME implement this
        return null;
    }

}

And then in your loop, what you check is whether a fruit is instanceof the interface:

if (fruit instanceof JuiceBehavior) {
    System.out.format("can be made into juice "
        + "with price $ %.2f%n", fruit.getJuicePrice());
} else {
    System.out.format("cannot be made into juice %n");

}

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 topic

Design 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 of JuiceBehavior. I won't go into the details here. But you can read up on that on some books about Design Patterns. Such as

  1. Design Patterns: Elements of Reusable Object-Oriented Software
  2. Head First Design Patterns: A Brain-Friendly Guide