|
11 | 11 | "- topics:\n",
|
12 | 12 | " - the Singleton pattern\n",
|
13 | 13 | " - the Decorator pattern\n",
|
| 14 | + " - the Iterator pattern\n", |
14 | 15 | " - the Observer pattern\n",
|
15 | 16 | " - the Strategy pattern\n",
|
16 | 17 | " - the Command pattern\n",
|
|
227 | 228 | },
|
228 | 229 | {
|
229 | 230 | "cell_type": "code",
|
230 |
| - "execution_count": null, |
| 231 | + "execution_count": 1, |
231 | 232 | "id": "0f8a6536",
|
232 | 233 | "metadata": {},
|
233 | 234 | "outputs": [],
|
|
237 | 238 | "from typing import List\n",
|
238 | 239 | "\n",
|
239 | 240 | "\n",
|
240 |
| - "class Context():\n", |
| 241 | + "class Context:\n", |
241 | 242 | " \"\"\"\n",
|
242 | 243 | " The Context defines the interface of interest to clients.\n",
|
243 | 244 | " \"\"\"\n",
|
|
316 | 317 | },
|
317 | 318 | {
|
318 | 319 | "cell_type": "code",
|
319 |
| - "execution_count": null, |
| 320 | + "execution_count": 2, |
320 | 321 | "id": "51e94a76",
|
321 | 322 | "metadata": {},
|
322 |
| - "outputs": [], |
| 323 | + "outputs": [ |
| 324 | + { |
| 325 | + "name": "stdout", |
| 326 | + "output_type": "stream", |
| 327 | + "text": [ |
| 328 | + "Client: Strategy is set to normal sorting.\n", |
| 329 | + "Context: Sorting data using the strategy (not sure how it'll do it)\n", |
| 330 | + "a,b,c,d,e\n", |
| 331 | + "\n", |
| 332 | + "Client: Strategy is set to reverse sorting.\n", |
| 333 | + "Context: Sorting data using the strategy (not sure how it'll do it)\n", |
| 334 | + "e,d,c,b,a\n" |
| 335 | + ] |
| 336 | + } |
| 337 | + ], |
323 | 338 | "source": [
|
324 | 339 | "context = Context(ConcreteStrategyA())\n",
|
325 | 340 | "print(\"Client: Strategy is set to normal sorting.\")\n",
|
|
538 | 553 | },
|
539 | 554 | {
|
540 | 555 | "cell_type": "code",
|
541 |
| - "execution_count": 26, |
| 556 | + "execution_count": null, |
542 | 557 | "id": "c7e13bcd",
|
543 | 558 | "metadata": {},
|
544 | 559 | "outputs": [],
|
|
612 | 627 | "Concrete States implement various behaviors, associated with a state of the\n",
|
613 | 628 | "Context.\n",
|
614 | 629 | "\"\"\"\n",
|
615 |
| - "\n", |
616 |
| - "\n", |
617 | 630 | "class ConcreteStateA(State):\n",
|
618 | 631 | " def handle1(self) -> None:\n",
|
619 | 632 | " print(\"ConcreteStateA handles request1.\")\n",
|
|
939 | 952 | "result"
|
940 | 953 | ]
|
941 | 954 | },
|
942 |
| - { |
943 |
| - "cell_type": "markdown", |
944 |
| - "id": "88c5fa34", |
945 |
| - "metadata": {}, |
946 |
| - "source": [ |
947 |
| - "## The Single pattern\n", |
948 |
| - "\n", |
949 |
| - "- also called anti-pattern \n", |
950 |
| - "- more common in more strict OOP languages such as Java than in scripting languages such as Python\n", |
951 |
| - "- the basic idea is to allow exactly one instance of certain objects in the program\n", |
952 |
| - "\n", |
953 |
| - "\n", |
954 |
| - "\n", |
955 |
| - "- singletons are normally enforced by making the constructor private (so no one can create additional instances of it)\n", |
956 |
| - "- then providing a static method to retrieve the single instance. \n", |
957 |
| - " - this method creates a new instance the first time it is called and then returns that same instance for all subsequent calls\n", |
958 |
| - " \n", |
959 |
| - "- since python doesn't have a private access specifier, we've to be a little creative\n", |
960 |
| - "- can use `__new__()` method and class variable to ensure that only one instance is created" |
961 |
| - ] |
962 |
| - }, |
963 |
| - { |
964 |
| - "cell_type": "code", |
965 |
| - "execution_count": 38, |
966 |
| - "id": "57c525e2", |
967 |
| - "metadata": {}, |
968 |
| - "outputs": [], |
969 |
| - "source": [ |
970 |
| - "class OneOnly:\n", |
971 |
| - " _singleton = None\n", |
972 |
| - " # not the use of cls instead of self to clarify the usage of _sigleton class variable\n", |
973 |
| - " def __new__(cls, *args, **kwargs):\n", |
974 |
| - " if not cls._singleton:\n", |
975 |
| - " cls._singleton = super().__new__(cls, *args, **kwargs)\n", |
976 |
| - " return cls._singleton\n", |
977 |
| - " \n", |
978 |
| - " def business_operation(self):\n", |
979 |
| - " print('perform some business opearation')" |
980 |
| - ] |
981 |
| - }, |
982 |
| - { |
983 |
| - "cell_type": "code", |
984 |
| - "execution_count": 35, |
985 |
| - "id": "8b4c8be8", |
986 |
| - "metadata": {}, |
987 |
| - "outputs": [], |
988 |
| - "source": [ |
989 |
| - "s1 = OneOnly()\n", |
990 |
| - "s2 = OneOnly()" |
991 |
| - ] |
992 |
| - }, |
993 |
| - { |
994 |
| - "cell_type": "code", |
995 |
| - "execution_count": 36, |
996 |
| - "id": "151266d1", |
997 |
| - "metadata": {}, |
998 |
| - "outputs": [ |
999 |
| - { |
1000 |
| - "data": { |
1001 |
| - "text/plain": [ |
1002 |
| - "True" |
1003 |
| - ] |
1004 |
| - }, |
1005 |
| - "execution_count": 36, |
1006 |
| - "metadata": {}, |
1007 |
| - "output_type": "execute_result" |
1008 |
| - } |
1009 |
| - ], |
1010 |
| - "source": [ |
1011 |
| - "s1 == s2" |
1012 |
| - ] |
1013 |
| - }, |
1014 |
| - { |
1015 |
| - "cell_type": "code", |
1016 |
| - "execution_count": 37, |
1017 |
| - "id": "fce54ad5", |
1018 |
| - "metadata": {}, |
1019 |
| - "outputs": [ |
1020 |
| - { |
1021 |
| - "data": { |
1022 |
| - "text/plain": [ |
1023 |
| - "True" |
1024 |
| - ] |
1025 |
| - }, |
1026 |
| - "execution_count": 37, |
1027 |
| - "metadata": {}, |
1028 |
| - "output_type": "execute_result" |
1029 |
| - } |
1030 |
| - ], |
1031 |
| - "source": [ |
1032 |
| - "id(s1) == id(s2)" |
1033 |
| - ] |
1034 |
| - }, |
1035 |
| - { |
1036 |
| - "cell_type": "code", |
1037 |
| - "execution_count": 5, |
1038 |
| - "id": "9a1107c4", |
1039 |
| - "metadata": {}, |
1040 |
| - "outputs": [ |
1041 |
| - { |
1042 |
| - "name": "stdout", |
1043 |
| - "output_type": "stream", |
1044 |
| - "text": [ |
1045 |
| - "perform some business opearation\n" |
1046 |
| - ] |
1047 |
| - } |
1048 |
| - ], |
1049 |
| - "source": [ |
1050 |
| - "s1.business_operation()" |
1051 |
| - ] |
1052 |
| - }, |
1053 |
| - { |
1054 |
| - "cell_type": "code", |
1055 |
| - "execution_count": 6, |
1056 |
| - "id": "a3eacfbb", |
1057 |
| - "metadata": {}, |
1058 |
| - "outputs": [ |
1059 |
| - { |
1060 |
| - "data": { |
1061 |
| - "text/plain": [ |
1062 |
| - "<__main__.OneOnly at 0x7f9ce6a4f3d0>" |
1063 |
| - ] |
1064 |
| - }, |
1065 |
| - "execution_count": 6, |
1066 |
| - "metadata": {}, |
1067 |
| - "output_type": "execute_result" |
1068 |
| - } |
1069 |
| - ], |
1070 |
| - "source": [ |
1071 |
| - "s1" |
1072 |
| - ] |
1073 |
| - }, |
1074 |
| - { |
1075 |
| - "cell_type": "code", |
1076 |
| - "execution_count": 7, |
1077 |
| - "id": "611a4d3f", |
1078 |
| - "metadata": {}, |
1079 |
| - "outputs": [ |
1080 |
| - { |
1081 |
| - "data": { |
1082 |
| - "text/plain": [ |
1083 |
| - "<__main__.OneOnly at 0x7f9ce6a4f3d0>" |
1084 |
| - ] |
1085 |
| - }, |
1086 |
| - "execution_count": 7, |
1087 |
| - "metadata": {}, |
1088 |
| - "output_type": "execute_result" |
1089 |
| - } |
1090 |
| - ], |
1091 |
| - "source": [ |
1092 |
| - "s2" |
1093 |
| - ] |
1094 |
| - }, |
1095 |
| - { |
1096 |
| - "cell_type": "markdown", |
1097 |
| - "id": "395e9fc5", |
1098 |
| - "metadata": {}, |
1099 |
| - "source": [ |
1100 |
| - "### Python singleton\n", |
1101 |
| - "\n", |
1102 |
| - "- Python provides two built-in Singleton patterns we can leverage\n", |
1103 |
| - "- rather than invent something hard to read, there are two choices:\n", |
1104 |
| - "\n", |
1105 |
| - "1. Python *module*:\n", |
1106 |
| - " - One `import` will create a module\n", |
1107 |
| - " - all other attempts to import the module return the one-and-only singleton instance of the module\n", |
1108 |
| - "\n", |
1109 |
| - "2. Python *class* definition:\n", |
1110 |
| - " - a Python class can only be created once in a given namespace\n", |
1111 |
| - " - consider using a class with class-level attributes as a singleton object\n", |
1112 |
| - " - use `@staticmethod` decorator to not have to use instance variable `self`\n", |
1113 |
| - " \n", |
1114 |
| - "- see https://github.com/rambasnet/Kattis-Demos-Testing/blob/main/hello/python3/OOP/main.py solution that uses single object of Main class to solve the problem\n", |
1115 |
| - "- see https://github.com/rambasnet/Kattis-Demos-Testing/tree/main/egypt/python3/OOP/main_singleton.py solution that uses static methods and class level variables to use a single pattern" |
1116 |
| - ] |
1117 |
| - }, |
1118 | 955 | {
|
1119 | 956 | "cell_type": "markdown",
|
1120 | 957 | "id": "e12acc78",
|
|
1142 | 979 | ],
|
1143 | 980 | "metadata": {
|
1144 | 981 | "kernelspec": {
|
1145 |
| - "display_name": "Python 3 (ipykernel)", |
| 982 | + "display_name": "oop", |
1146 | 983 | "language": "python",
|
1147 | 984 | "name": "python3"
|
1148 | 985 | },
|
|
1156 | 993 | "name": "python",
|
1157 | 994 | "nbconvert_exporter": "python",
|
1158 | 995 | "pygments_lexer": "ipython3",
|
1159 |
| - "version": "3.10.8" |
| 996 | + "version": "3.10.9" |
1160 | 997 | }
|
1161 | 998 | },
|
1162 | 999 | "nbformat": 4,
|
|
0 commit comments