Laravel એપ્લિકેશન્સ બનાવતા ડેવલપર્સને તેમના કંટ્રોલર્સમાં new કીવર્ડનો ઉપયોગ કરવાનું છોડીને Factory Method પેટર્ન અપનાવવા માટે સૂચવવામાં આવી રહ્યું છે. ઓબ્જેક્ટ ક્રિએશનને ડેડિકેટેડ ફેક્ટરીઝમાં ખસેડવાથી, કોડને એક્સટેન્ડ, ટેસ્ટ અને મેન્ટેન (જાળવણી) કરવો સરળ બને છે—જે પ્રોજેક્ટ્સ જ્યારે થોડા એન્ડપોઈન્ટ્સથી વધીને મોટા થાય ત્યારે ખૂબ જ મહત્વપૂર્ણ છે.

new કીવર્ડ એક છુપી જવાબદારી (liability) કેમ છે

જ્યારે કંટ્રોલરમાં આ પ્રકારની લાઇન હોય:

$processor = new StripePaymentProcessor($config);

ત્યારે કંટ્રોલર હવે StripePaymentProcessor ક્લાસ સાથે ટાઈટલી કપલ્ડ (tightly coupled) બની જાય છે. જ્યાં પણ પેમેન્ટ પ્રોસેસરની જરૂર હોય ત્યાં આ લાઇન વારંવાર લખવી પડે છે, જેનાથી કન્સ્ટ્રક્શન લોજિક આખા કોડબેઝમાં વિખરાઈ જાય છે. જો પ્રોસેસરને પાછળથી લોગર (logger), કેશ મેનેજર અથવા અલગ કન્ફિગરેશન ફોર્મેટની જરૂર પડે, તો તે દરેક જગ્યાએ અપડેટ કરવું પડે છે. પરિણામે, કોડ નાજુક (fragile) બને છે જે ફેરફારોનો વિરોધ કરે છે અને યુનિટ ટેસ્ટમાં મોક (mock) કરવો મુશ્કેલ બને છે.

Factory Method પેટર્નનો ઉપયોગ

Factory Method પેટર્ન ડાયરેક્ટ ઇન્સ્ટન્શિએશનને બદલે એક મેથડનો ઉપયોગ કરે છે જે આપેલ ઇન્ટરફેસનું ઇન્સ્ટન્સ રિટર્ન કરે છે. કંટ્રોલર ઇન્ટરફેસ પર આધાર રાખે છે, જ્યારે ફેક્ટરી ક્લાસ જાણે છે કે કયો કોંક્રિટ ક્લાસ (concrete class) બનાવવો અને તેની ડિપેન્ડન્સીઝ કેવી રીતે જોડવી. બધું જ ક્રિએશન લોજિક એક જ જગ્યાએ હોય છે, તેથી નવી ડિપેન્ડન્સી ઉમેરવી અથવા ઇમ્પ્લીમેન્ટેશન બદલવું હોય તો માત્ર ફેક્ટરીમાં જ ફેરફાર કરવો પડે છે.

મુખ્ય ફાયદાઓ

  • Loose coupling – કંટ્રોલર્સ એબ્સ્ટ્રેક્શન (abstractions) પર કામ કરે છે, કોંક્રિટ ક્લાસ પર નહીં.
  • Centralized construction – બિલ્ડ પ્રોસેસ બદલવા માટે માત્ર એક જ ફાઇલ એડિટ કરવાની જરૂર પડે છે.
  • Testability – ફેક્ટરીઝને સ્ટેબ (stub) કરી શકાય છે અથવા મોક્સ (mocks) સાથે બદલી શકાય છે, જેનાથી કંટ્રોલરના અલગ (isolated) ટેસ્ટ કરી શકાય છે.
  • Open/Closed Principle – હાલના કંટ્રોલર કોડને અડક્યા વગર નવી સુવિધાઓ (દા.ત. નવું પેમેન્ટ ગેટવે) ઉમેરી શકાય છે.

કોફી શોનું ઉદાહરણ (analogy)

એક બરિસ્ટાની કલ્પના કરો જેને દરેક ઓર્ડર માટે if-else સ્ટેટમેન્ટ્સની લાંબી શ્રેણીનો ઉપયોગ કરીને જાતે જ બીન્સ પીસવા, દૂધ ગરમ કરવું અને પાણી રેડવું પડે છે. જો લેટે (latte) રેસીપી બદલાય, તો દરેક બરિસ્ટાએ સ્ટેપ્સ ફરીથી શીખવા પડે. જ્યારે એક કોફી મશીન જે ઓર્ડરનો પ્રકાર મેળવે છે અને આંતરિક રીતે તૈયારી સંભાળે છે, ત્યારે સમસ્યા હલ થઈ જાય છે: બરિસ્ટા ફક્ત મશીનને જણાવે છે કે શું જોઈએ છે, અને મશીન તમામ સ્ટેપ્સને એન્કેપ્સ્યુલેટ (encapsulate) કરે છે. હવે રેસીપી અપડેટ કરવાનો અર્થ મશીનમાં ફેરફાર કરવો છે, દરેક બરિસ્ટામાં નહીં.

Laravel પહેલેથી જ ફેક્ટરીઝનો ઉપયોગ કરે છે

Laravel ના પોતાના કોર કમ્પોનન્ટ્સ આ પેટર્નને અમલમાં મૂકે છે:

  • Database – ConnectionFactory નક્કી કરે છે કે MySQL અથવા PostgreSQL કનેક્શન બનાવવું.
  • Queues – QueueManager Redis, SQS અથવા અન્ય બેક-એન્ડ્સ માટે ડ્રાઇવર્સ બનાવે છે.
  • Filesystem – FilesystemManager લોકલ અથવા S3 ડિસ્ક ઇન્સ્ટન્સ બનાવે છે.
  • Mail – MailManager SMTP, Mailgun અથવા અન્ય મેઇલ ડ્રાઇવર્સને રિઝોલ્વ કરે છે.

જો ફ્રેમવર્ક આ મહત્વપૂર્ણ સેવાઓ માટે ફેક્ટરીઝ પર વિશ્વાસ કરે છે, તો કસ્ટમ કોડને પણ તે જ અનુસરવું જોઈએ.

ફેક્ટરીનો ઉપયોગ ક્યારે કરવો

ફેક્ટરીનો ઉપયોગ ત્યારે કરો જ્યારે:

  • ઓબ્જેક્ટ ક્રિએશનમાં મલ્ટિપલ કન્ફિગરેશન સ્ટેપ્સ અથવા એક્સટર્નલ સર્વિસીસ સામેલ હોય.
  • એકથી વધુ બદલી શકાય તેવા ઇમ્પ્લીમેન્ટેશન ઉપલબ્ધ હોય (વિવિધ પેમેન્ટ ગેટવે, સ્ટોરેજ પ્રોવાઇડર્સ, વગેરે).
  • સંભવિત ઇમ્પ્લીમેન્ટેશનની યાદી વધવાની શક્યતા હોય.

ફેક્ટરીનો ઉપયોગ ટાળો જ્યારે:

  • કન્સ્ટ્રક્શન એ કોઈ વધારાના સેટઅપ વગરનું સિંગલ, ઇમ્યુટેબલ (immutable) new કોલ હોય.
  • માત્ર એક જ ઇમ્પ્લીમેન્ટેશનનો ઉપયોગ થશે, જેનાથી વધારાનું એબ્સ્ટ્રેક્શન બિનજરૂરી ઓવરહેડ બની જાય.

ઝડપી સમજૂતી: પેમેન્ટ કંટ્રોલરનું રિફેક્ટરિંગ

  1. ઇન્ટરફેસ વ્યાખ્યાયિત કરો – PaymentProcessorInterface જેમાં process(array $data) મેથડ હોય.
  2. કોંક્રિટ ક્લાસ ઇમ્પ્લીમેન્ટ કરો – StripePaymentProcessor, PayPalPaymentProcessor, જે ઇન્ટરફેસનું પાલન કરે છે.
  3. ફેક્ટરી બનાવો – PaymentProcessorFactory જેમાં make(string $driver): PaymentProcessorInterface મેથડ હોય. તેની અંદર, યોગ્ય ક્લાસ રિટર્ન કરવા માટે switch અથવા મેપનો ઉપયોગ કરો, અને Laravel ના સર્વિસ કન્ટેનરથી જરૂરી સર્વિસીસ ઇન્જેક્ટ કરો.
  4. ફેક્ટરી ઇન્જેક્ટ કરો – કંટ્રોલરના કન્સ્ટ્રક્ટરમાં, PaymentProcessorFactory નો ટાઇપ-હિન્ટ આપો. Laravel તેને આપમેળે રિઝોલ્વ કરશે.
  5. ફેક્ટરીનો ઉપયોગ કરો – $processor = $this->processorFactory->make('stripe'); $processor->process($request->all());

હવે કંટ્રોલરમાં ક્યારેય new અથવા કોઈ કોંક્રિટ પ્રોસેસરનો ઉલ્લેખ નથી. નવું ગેટવે ઉમેરવાનો અર્થ ક્લાસ બનાવવો અને ફેક્ટરીના મેપને એક્સટેન્ડ કરવો છે—કંટ્રોલરમાં કોઈ ફેરફાર કરવાની જરૂર નથી.

સંભવિત ગેરફાયદા અને તેને કેવી રીતે ઘટાડવા

The primary criticism of factories is added indirection, which can feel verbose for trivial objects. Over-engineering a simple service can inflate the codebase without real benefit. The key is to assess the complexity of construction: if an object is a plain data holder with no dependencies, a direct new may be acceptable. Also, factories can become a dumping ground for unrelated logic. Keeping factories focused on object creation and delegating configuration to dedicated service providers preserves clarity.

What to watch for next

  • Service container bindings – Laravel’s container can resolve factories automatically if you bind the interface to the factory class in a service provider.
  • Auto-discovery – Some packages expose their own factories; be aware of naming collisions.
  • Testing strategies – When unit testing controllers, replace the factory with a mock that returns a stubbed processor, ensuring tests stay fast and isolated.

Bottom line

Replacing scattered new calls with a well-placed factory centralizes construction, reduces coupling, and aligns custom code with Laravel’s own design philosophy. For teams that anticipate growth—new payment providers, storage back-ends, or any plug-in-style component—the Factory Method pattern is a low-cost investment that pays off in flexibility and confidence. Your future self, and anyone who inherits the code, will thank you.