Zgłębiam wiedzę na temat wzorców projektowych, ale mam lekki problem co do dwóch tytułowych wzorców.
Doszedłem do wniosku, że stosujemy Abstract Factory wtedy kiedy w produkcie fabryki chcemy mieć właściwości różnego rodzaju?

Bo wzorując się na tym kodzie

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Factory
{
    public interface FabrykaSkladnikowPizzy
    {
        Ciasto utworzCiastio();
        Sos utworzSos();
    }

    public class WloskaFabrykaSkladnikowPizzy : FabrykaSkladnikowPizzy
    {
        public Ciasto utworzCiastio()
        {
            return new CienkieCiasto();
        }
        public Sos utworzSos()
        {
            return new SosOstry();
        }
    }

    public class AmerykanskaFabrykaSkladnikowPizzy : FabrykaSkladnikowPizzy
    {
        public Ciasto utworzCiastio()
        {
            return new GrubeCiasto();
        }
        public Sos utworzSos()
        {
            return new SosLagodny();
        }
    }
    public interface Ciasto
    {
        string toString();
    }

    public class GrubeCiasto : Ciasto
    {
        public string toString()
        {
            return "Grube ciasto";
        }
    }

    public class CienkieCiasto : Ciasto
    {
        public string toString()
        {
            return "Cienkie ciasto";
        }
    }

    public interface Sos
    {
        string toString();
    }

    public class SosLagodny : Sos
    {
        public string toString()
        {
            return "Sos łagodny";
        }
    }

    public class SosOstry : Sos
    {
        public string toString()
        {
            return "Sos ostry";
        }
    }
    public abstract class Pizza              // Pizza jest PRODUKTEM fabryki
    {
        public string nazwa;
        public Ciasto ciasto;
        public Sos sos;

        public abstract void przygotowanie();

        public void pieczenie()
        {
            Console.WriteLine("Pieczenie: 25 minut w temperaturze 350 stopni Celsjusza");
        }

        public virtual void krojenie()
        {
            Console.WriteLine("Krojenie pizzy na 8 kawałków");
        }

        public void pakowanie ()
        {
            Console.WriteLine("Pakowanie pizzy do pudełka");
        }
    }      

    public class WloskaSerowaPizza : Pizza      // PRODUKT RZECZYWISTY
    {
        FabrykaSkladnikowPizzy fabrykaSkladnikow;
        public WloskaSerowaPizza(FabrykaSkladnikowPizzy _fabrykaSkladnikow)
        {
            fabrykaSkladnikow = _fabrykaSkladnikow;  
        }

        public override void przygotowanie()
        {
            ciasto = fabrykaSkladnikow.utworzCiastio();
            sos = fabrykaSkladnikow.utworzSos();
        }
    }    

    public class AmerykanskaSerowaPizza : Pizza  // PRODUKT RZECZYWISTY
    {
        FabrykaSkladnikowPizzy fabrykaSkladnikow;
        public AmerykanskaSerowaPizza(FabrykaSkladnikowPizzy _fabrykaSkladnikow)
        {
            fabrykaSkladnikow = _fabrykaSkladnikow;
        }
        public override void krojenie()
        {
            Console.WriteLine("Krojenie pizzy na kwadratowe kawałki");
        }

        public override void przygotowanie()
        {
            ciasto = fabrykaSkladnikow.utworzCiastio();
            sos = fabrykaSkladnikow.utworzSos();
        }
    }  
    
    public abstract class Pizzeria          // klasa reprezentująca METODĘ FABRYKUJĄCĄ
    {
        public abstract Pizza utworzPizza(string Type);
        public Pizza zamowPizza(string Type)
        {
            Pizza pizza;
            pizza = utworzPizza(Type);
            pizza.przygotowanie();
            pizza.pieczenie();
            pizza.krojenie();
            pizza.pakowanie();
            return pizza;
        }
    }

    public class WloskaPizzeria : Pizzeria          // METODA FABRYKUJĄCA RZECZYWISTA
    {
        FabrykaSkladnikowPizzy fabrykaSkladnikow = new WloskaFabrykaSkladnikowPizzy();
        public override Pizza utworzPizza(string Type)
        {
            if (Type.Equals("serowa"))
                return new WloskaSerowaPizza(fabrykaSkladnikow);
            else
                return null;
        }
    }

    public class AmerykanksaPizzeria : Pizzeria     //METODA FABRYKUJĄCA RZECZYWISTA
    {
        FabrykaSkladnikowPizzy fabrykaSkladnikow = new AmerykanskaFabrykaSkladnikowPizzy();
        public override Pizza utworzPizza(string Type)
        {
            if (Type.Equals("serowa"))
                return new AmerykanskaSerowaPizza(fabrykaSkladnikow);
            else
                return null;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            AmerykanksaPizzeria pizzeria = new AmerykanksaPizzeria();
            pizzeria.zamowPizza("serowa");
            WloskaPizzeria pizzeria1 = new WloskaPizzeria();
            pizzeria1.zamowPizza("serowa");
            Console.ReadKey();
        }
    }
}

Abstract Factory został zastosowany, dlatego aby móc "serwować" różne rodzaje ciasta i różne rodzaje sosów?

Może ma ktoś jakiś jeszcze przykład zastosowania najpierw wzorca Factory Method, a później ten przykład rozubodwany o Abstarct Factory? Zależy mi, żeby to było na jednym programie. Chyba, że źle do tego podchodzę?

poprawienie znacznika <code class="csharp"> - furious programming