{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Abstract Factory Pattern"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from abc import ABCMeta, abstractmethod, abstractstaticmethod"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class IAuto(metaclass=ABCMeta):\n",
    "    @abstractmethod\n",
    "    def start(self):\n",
    "        pass\n",
    "    \n",
    "    @abstractmethod\n",
    "    def stop(self):\n",
    "        pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ford"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class FordFiesta(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Ford Fiesta running cheaply\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Ford Fiest used less fuel before stop\")\n",
    "        \n",
    "class FordMustang(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Ford Mustang start\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Ford Mustang stopped\")\n",
    "        \n",
    "class FordLincoln(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Ford Lincoln start\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Ford Lincoln stopped\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tesla"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TeslaModel3(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Tesla Model 3 start\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Tesla Model 3 stop\")\n",
    "        \n",
    "class TeslaRoadster(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Tesla Roadster start\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Tesla Roadster stop\")\n",
    "        \n",
    "class TeslaModelS(IAuto):\n",
    "    def start(self):\n",
    "        print(\"Tesla Model S start\")\n",
    "        \n",
    "    def stop(self):\n",
    "        print(\"Tesla Model S stop\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Factories"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class IFactory(metaclass=ABCMeta):\n",
    "    @abstractstaticmethod\n",
    "    def create_economy():\n",
    "        pass\n",
    "    \n",
    "    @abstractstaticmethod\n",
    "    def create_sports():\n",
    "        pass\n",
    "    \n",
    "    @abstractstaticmethod\n",
    "    def create_luxury():\n",
    "        pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Ford(IFactory):\n",
    "    def create_economy():\n",
    "        return FordFiesta()\n",
    "    \n",
    "    def create_sport():\n",
    "        return FordMustang()\n",
    "    \n",
    "    def create_luxury():\n",
    "        return FordLincoln()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Tesla(IFactory):\n",
    "    def create_economy():\n",
    "        return TeslaModel3()\n",
    "    \n",
    "    def create_sport():\n",
    "        return TeslaRoadster()\n",
    "    \n",
    "    def create_luxury():\n",
    "        return TeslaModelS()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Driver Program"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ford Fiesta running cheaply\n",
      "Ford Fiest used less fuel before stop\n",
      "----------------\n",
      "Ford Mustang start\n",
      "Ford Mustang stopped\n",
      "----------------\n",
      "Ford Lincoln start\n",
      "Ford Lincoln stopped\n",
      "----------------\n",
      "Tesla Model 3 start\n",
      "Tesla Model 3 stop\n",
      "----------------\n",
      "Tesla Roadster start\n",
      "Tesla Roadster stop\n",
      "----------------\n",
      "Tesla Model S start\n",
      "Tesla Model S stop\n",
      "----------------\n"
     ]
    }
   ],
   "source": [
    "for factory in Ford, Tesla:\n",
    "    car = factory.create_economy()\n",
    "    car.start()\n",
    "    car.stop()\n",
    "    print('----------------')\n",
    "    \n",
    "    car = factory.create_sport()\n",
    "    car.start()\n",
    "    car.stop()\n",
    "    print('----------------')\n",
    "    \n",
    "    car = factory.create_luxury()\n",
    "    car.start()\n",
    "    car.stop()\n",
    "    print('----------------')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}