|
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