സ്റ്റേറ്റ് ടൈപ്പുകളായി, ഒരു ഡിസൈൻ പാറ്റേൺDraft

പ്രോഗ്രാമിംഗ് എന്നത് സ്റ്റേറ്റിനെക്കുറിച്ചാണ്.

കമ്പ്യൂട്ടർ സയന്റിസ്റ്റുകൾ നിങ്ങളോട് പറയും, പ്രോഗ്രാമിംഗ് ഭാഷകൾ എന്നത് ഒരു അമൂർത്ത ട്യൂറിംഗ് മെഷീന്റെ DFA (അല്ലെങ്കിൽ സ്റ്റേറ്റ് മെഷീൻ) നിർവചിക്കുന്നതിനുള്ള ഒരു മാർഗമാണെന്ന്. മറുവശത്ത്, ഹാർഡ്വെയർ എഞ്ചിനീയർമാർ നിങ്ങളോട് പറയും, പ്രോഗ്രാം പ്രവർത്തിപ്പിക്കുന്ന ഫിസിക്കൽ ഒബ്ജക്റ്റായ CPU എന്നത് അക്ഷരാർത്ഥത്തിൽ ട്രാൻസിസ്റ്ററുകളിൽ എൻകോഡ് ചെയ്ത ഒരു സ്റ്റേറ്റ് മെഷീൻ ആണെന്ന്.

പ്രോഗ്രാമിംഗ് എന്നത് സ്റ്റേറ്റിനെക്കുറിച്ചാണ്.

ഒരാൾക്ക് വാദിക്കാം, സിന്റാക്സ് അവഗണിച്ചാൽ, ഒരു പ്രോഗ്രാമിംഗ് ഭാഷയെ മറ്റൊന്നിൽ നിന്ന് വ്യത്യസ്തമാക്കുന്നത് അത് സ്റ്റേറ്റ് എങ്ങനെ കൈകാര്യം ചെയ്യുന്നു എന്നതാണ്. ഭാഷകൾ സ്റ്റേറ്റ് എങ്ങനെ കൈകാര്യം ചെയ്യുന്നുവെന്ന് തരംതിരിക്കാനുള്ള ഒരു മാർഗം, അത് എത്രമാത്രം കംപൈൽ-ടൈമിൽ vs. റൺ-ടൈമിൽ പരിഹരിക്കപ്പെടുന്നുവെന്ന് പരിഗണിക്കുക എന്നതാണ്.

പ്രോഗ്രാമിംഗ് ഭാഷകളുടെ സ്പെക്ട്രം
റൺ-ടൈം/കംപൈൽ-ടൈം സ്പെക്ട്രത്തിൽ സ്ഥാപിച്ചിരിക്കുന്ന പൊതു പ്രോഗ്രാമിംഗ് ഭാഷകൾ

ഏറ്റവും ഇടതുവശത്ത് പൂർണ്ണമായും ഇന്റർപ്രെറ്റ് ചെയ്യപ്പെടുന്ന ഭാഷകൾ 1 ഉണ്ട്, പൈത്തൺ, ലുവ പോലുള്ളവ, ഇവയ്ക്ക് റൺടൈമിൽ എന്ത് ഇൻസ്ട്രക്ഷനുകൾ എക്സിക്യൂട്ട് ചെയ്യണമെന്ന് പോലും അറിയില്ല. മറുവശത്ത്, റസ്റ്റ്, സി++ പോലുള്ള ശക്തമായ ടൈപ്പുകളുള്ള കംപൈൽ ചെയ്ത ഭാഷകൾ ഉണ്ട്, ഇവയ്ക്ക് പ്രോഗ്രാം കംപൈൽ ചെയ്യുന്നതിന് മുമ്പ് വിപുലമായ വിവരങ്ങൾ ആവശ്യമാണ്.

ഭാഷ സ്പെക്ട്രത്തിൽ എവിടെയായിരുന്നാലും ട്രേഡ്-ഓഫുകൾ ഉണ്ട്. ടൈപ്പുകൾ, മെമ്മറി, ലൈഫ്‌ടൈം എന്നിവയെക്കുറിച്ച് വിപുലമായ വിവരങ്ങൾ ആവശ്യമുള്ള വളരെ കർശനമായ ഭാഷകൾ പലപ്പോഴും നിർമ്മിക്കാനും ഇറ്ററേറ്റ് ചെയ്യാനും ബുദ്ധിമുട്ടുള്ളതാണ്, പക്ഷേ റൺടൈമിൽ വളരെ കാര്യക്ഷമമാണ്. എന്നാൽ മറുവശത്തുള്ള ഭാഷകൾ വിപരീതമാണ്: എന്തെങ്കിലും വേഗത്തിൽ എഴുതാൻ എളുപ്പമാണ്, പക്ഷേ ഒരു പ്രധാന റൺടൈം ചെലവ് വരുന്നു.

ശക്തമായ ടൈപ്പുകളുള്ള ഭാഷകൾ തെറ്റുകളുടെ മാനേജ്മെന്റിൽ നിസ്സംശയമായി മികച്ചതാണ്. പലപ്പോഴും, ഇന്റർപ്രെറ്റ് ചെയ്യപ്പെടുന്ന ഭാഷകളുടെ തത്വം, എന്തെങ്കിലും അപ്രതീക്ഷിത എക്സെപ്ഷനുകൾ എറിയപ്പെടുന്നുണ്ടോ എന്ന് കാണാൻ ശേഷം ഡീബഗ് ചെയ്യുക എന്നതാണ്.

അൽഗോരിതം Y: ഇന്റർപ്രെറ്റ് ചെയ്യപ്പെടുന്ന ഭാഷ ഡീബഗ്ഗിംഗ് (ലളിതമാക്കിയത്)

  1. കോഡ് എഴുതുക
  2. കോഡ് റൺ ചെയ്യുക
  3. എങ്കിൽ എറർ ഇല്ലെങ്കിൽ, ഘട്ടം 6 ലേക്ക് പോകുക
  4. എറർ കൈകാര്യം ചെയ്യുക
  5. ഘട്ടം 2 ലേക്ക് പോകുക
  6. ഡിപ്ലോയ് ചെയ്യുക

നിങ്ങൾ ഡെവലപ്മെന്റ് സമയത്തെ റൺടൈം പ്രകടനത്തിന് മുകളിൽ വിലമതിക്കുന്നുണ്ടോ, അല്ലെങ്കിൽ തിരിച്ചും, പ്രോഗ്രാമുകൾ ശരിയായതും എററുകൾക്ക് ശക്തമായതും ആയിരിക്കണം എന്ന് നമുക്കെല്ലാവർക്കും സമ്മതിക്കാം.

ഞങ്ങൾ ഒരു ഡിസൈൻ പാറ്റേൺ നോക്കാൻ പോകുന്നു, അത് റൺടൈം ലോജിക്കിനെ വർഗീകരിക്കാനും കംപൈൽ ടൈം (അല്ലെങ്കിൽ കോഡ്-റൈറ്റിംഗ്-ടൈം, ഇന്റർപ്രെറ്റ് ചെയ്യപ്പെടുന്ന ഭാഷ ഉപയോഗിക്കുന്നുവെങ്കിൽ) വിവരങ്ങളിലേക്ക് മാറ്റാനും സഹായിക്കുന്നു. ഫലപ്രദമായി, അത് ഭാഷയുടെ ടൈപ്പ് സിസ്റ്റം ഉപയോഗിച്ച് നിയമവിരുദ്ധമായ ഒബ്ജക്റ്റ് സ്റ്റേറ്റുകൾ തടയുന്ന ഒരു സ്റ്റേറ്റ് പൈപ്പ്ലൈൻ സൃഷ്ടിക്കും. വിഷമിക്കേണ്ട, സ്റ്റാറ്റിക് ടൈപ്പിംഗ് ആവശ്യമില്ല.

ഈ പാറ്റേൺ ഉപയോഗിക്കുന്ന ഒരു റിഫാക്ടറിംഗ് ഉദാഹരണം നോക്കാം.

ടാസ്ക്

ബോസ് നമ്മോട് പറയുന്നത്, ഏതെങ്കിലും URL ലൂടെ ചൂണ്ടിക്കാണിക്കുന്ന ഏത് ഫയലിലും ഒരു നിശ്ചിത കാരക്റ്ററിന്റെ എണ്ണം കണക്കാക്കുന്ന ഒരു ലൈബ്രറി എഴുതേണ്ടത് അത്യാവശ്യമാണെന്നാണ്. അതുപോലെ, ഫയൽ ഡൗൺലോഡ് ചെയ്യാൻ ഞങ്ങളുടെ കോഡ് ഉപയോഗിക്കുന്ന ഉപയോക്താവിന് ഏത് സമയത്തും സാധ്യമാകണം.

നല്ലത്. അത് കൃത്യമായി ചെയ്യുന്ന ഒരു ക്ലാസ് ഉണ്ടാക്കാം.

class FileDownloadCharCounter:
    def __init__(self, url):
		# ആർഗ്യുമെന്റ് ഇൻസ്റ്റൻസ് വേരിയബിളായി സംരക്ഷിക്കുക
        self.url = url

    def download(self):
		# ഉള്ളടക്കം ഡൗൺലോഡ് ചെയ്ത് പിന്നീട് ഉപയോഗിക്കാൻ സംരക്ഷിക്കുക
        self.downloaded_content = requests.get(self.url).text

    def create_index(self):
		# കാരക്റ്റർ എണ്ണം സംഭരിക്കുന്ന ഒരു ഡിക്ഷണറി സൃഷ്ടിക്കുക
        self.index = {}
        for char in self.downloaded_content:
            self.index[char] = self.index.get(char, 0) + 1

    def get_count(self, target_char):
		# ഡിക്ഷണറിയിൽ നിന്ന് എണ്ണം നേടുക
        return self.index.get(target_char, 0)

ഈ വ്യായാമത്തിനായി, requests.get ഒരിക്കലും പരാജയപ്പെടില്ലെന്ന് അനുമാനിക്കാം. ക്ലാസ് ടെസ്റ്റ് ചെയ്യാം.

counter = FileDownloadCharCounter(
	"https://world.hey.com/dhh/programming-types-and-mindsets-5b8490bc"
)
counter.download()
counter.create_index()
target = "a"
n = counter.get_count("a")
print(f"{target} appears {n} times")
a appears 477 times

കൊള്ളാം! ഇപ്പോൾ ഡിപ്ലോയ് ചെയ്യാമോ? അത്ര വേഗം അല്ല… നിങ്ങൾ ശ്രദ്ധാപൂർവ്വം നോക്കിയാൽ, ഞങ്ങൾ അവതരിപ്പിച്ചിട്ടുള്ള നിരവധി അൺകോട്ട് എക്സെപ്ഷനുകൾ ഉണ്ട്. ഉപയോക്താവ് ഇത് ചെയ്താൽ എന്ത് സംഭവിക്കും?

counter = FileDownloadCharCounter(
	"https://world.hey.com/dhh/programming-types-and-mindsets-5b8490bc"
)
counter.download()
target = "a"
n = counter.get_count("a")
AttributeError: 'FileDownloadCharCounter' object has no attribute 'index'

അയ്യോ. ഉപയോക്താവ് ഇൻഡെക്സ് സൃഷ്ടിക്കാൻ മറന്നാൽ, അവർക്ക് ഒരു AttributeError ലഭിക്കും, അത് വളരെ സഹായകമല്ല. എന്ത് തെറ്റായി എന്ന് കണ്ടെത്താൻ അവർ ലൈബ്രറി സോഴ്സ് കോഡ് വായിക്കേണ്ടി വരും, അത് ഒരു നല്ല ഉപയോക്തൃ അനുഭവമല്ല. ഉപയോക്താവിന് കാച്ച് ചെയ്യാനും പരിഹരിക്കാനും കഴിയുന്ന ഒരു സ്വയം വിശദീകരിക്കുന്ന എക്സെപ്ഷൻ സൃഷ്ടിക്കാം:

class IndexNotCreatedException(Exception):
	pass

class FileDownloadCharCounter:
    def __init__(self, url):
		# മറ്റ് കോഡ് ...
        self.index = {}

# മറ്റ് മെത്തേഡുകൾ ...

    def get_count(self, target_char):
        if len(self.index) == 0:
            raise IndexNotCreatedException
        return self.index[target_char]

ഇപ്പോൾ നമുക്ക് ഒരു നല്ല

File "example.py", line 31, in get_count
    raise IndexNotCreatedException
__main__.IndexNotCreatedException

ലഭിക്കുന്നു, അത് ഞങ്ങൾക്ക് ഇങ്ങനെ കൈകാര്യം ചെയ്യാം:

try:
	count = counter.get_count('a')
except IndexNotCreatedException:
	# പുനഃസ്ഥാപിക്കുക
	pass

ഇത് തകരാനുള്ള മറ്റൊരു വഴിയുണ്ടോ? അതെ:

counter.create_index()
target = "a"
n = counter.get_count("a")
  File "example.py", line 13, in create_index
    for char in self.downloaded_content:
AttributeError: 'FileDownloadCharCounter' object has no attribute 'downloaded_content'

ലൈബ്രറി ഉപയോക്താവ് ഫയൽ ഡൗൺലോഡ് ചെയ്യാൻ മറന്നാൽ, അത് മറ്റൊരു AttributeError എറിയുന്നു, അത് വളരെ സഹായകമല്ല. അത് കൈകാര്യം ചെയ്യാം:

class FileNotDownloadedException(Exception):
    pass

class FileDownloadCharCounter:
    def __init__(self, url):
		# ...
        self.downloaded = False

    def download(self):
		# ...
        self.downloaded = True

    def create_index(self):
        if not self.downloaded:
            raise FileNotDownloadedException
		# ...

ഇപ്പോൾ, ഉപയോക്താവിന് ഈ എക്സെപ്ഷൻ മുകളിൽ ചെയ്തതുപോലെ കൈകാര്യം ചെയ്യാം. ഇപ്പോഴും മറ്റൊരു ബഗ് ഉണ്ട്; നിങ്ങൾക്ക് അത് കണ്ടെത്താമോ? ഉപയോക്താവ് ആകസ്മികമായി ഇത് ചെയ്താൽ:

counter = FileDownloadCharCounter(
	"https://world.hey.com/dhh/programming-types-and-mindsets-5b8490bc"
)
counter.download()
counter.create_index()
# മറ്റ് പ്രധാനപ്പെട്ട കാര്യങ്ങൾ...
counter.create_index()
# കൂടുതൽ പ്രധാനപ്പെട്ട കാര്യങ്ങൾ...
target = "a"
n = counter.get_count("a")
print(f"{target} appears {n} times")

ഇപ്പോൾ നമുക്ക് ഇരട്ടി യഥാർത്ഥ എണ്ണം ലഭിക്കും!

a appears 954 times

ഒപ്പം എക്സെപ്ഷൻ ഇല്ല. അതായത്, ഈ ബഗ് Algorithm Y യിൽ പിടികിട്ടിയില്ല. വീണ്ടും, ഇത് കൈകാര്യം ചെയ്യാം:

class IndexNotCreatedException(Exception):
    pass

class FileDownloadCharCounter:
	# മെത്തേഡുകൾ...

    def create_index(self):
        if len(self.index) > 0:
            raise IndexAlreadyCreatedException
		# കൂടുതൽ കോഡ്...

ഫ്യൂ! അത് എല്ലാ സ്റ്റേറ്റ്-ബന്ധിത പിശകുകളും തോന്നുന്നു. ഇതാണ് ഞങ്ങളുടെ ഫൈനൽ കോഡ്:

class IndexNotCreatedException(Exception):
    pass

class IndexAlreadyCreatedException(Exception):
    pass

class FileNotDownloadedException(Exception):
    pass

class FileDownloadCharCounter:
    def __init__(self, url):
        self.url = url
        self.index = {}
        self.downloaded = False

    def download(self):
        self.downloaded_content = requests.get(self.url).text
        self.downloaded = True

    def create_index(self):
        if not self.downloaded:
            raise FileNotDownloadedException

        if len(self.index) == 0:
            raise IndexAlreadyCreatedException

        for char in self.downloaded_content:
            self.index[char] = self.index.get(char, 0) + 1

    def get_count(self, target_char):
        if len(self.index) == 0:
            raise IndexNotCreatedException

        return self.index.get(target_char, 0)

എറ്റ് വോയില! ഞങ്ങളുടെ ഒബ്ജക്റ്റ് ഓറിയന്റഡ് കോഡ്… ഭയങ്കരമാണ്. കുറച്ച് ലളിതമായ പൈത്തൺ കോഡിന് പകരം, ഞങ്ങൾക്ക് 3 കസ്റ്റം എക്സെപ്ഷനുകളും സ്റ്റേറ്റ് ട്രാക്ക് ചെയ്യുന്ന ഒരു കൂട്ടം ലോജിക്കും ഉണ്ട്, അത് ഒന്നും തെറ്റായില്ലെന്ന് ഉറപ്പാക്കുന്നു.

ഇപ്പോൾ, 3 ഇൻസ്റ്റൻസ് വേരിയബിളുകൾക്ക് പകരം 30 ഉണ്ടായിരുന്നെങ്കിൽ, എല്ലാ അനധികൃത സ്റ്റേറ്റുകളും അറിയാനോ എണ്ണാനോ സാധ്യമായേക്കില്ല.

നിർഭാഗ്യവശാൽ, നിരവധി ഇന്റർപ്രെറ്റഡ് ഭാഷകൾ റോബസ്റ്റ് കോഡ് എഴുതുന്നത് ക്ഷീണിപ്പിക്കുന്നതാക്കാറുണ്ട്. ഇത് കൈകാര്യം ചെയ്യാൻ, ഞാൻ ഒരു പുതിയ ഡിസൈൻ പാറ്റേൺ അവതരിപ്പിക്കും, അതിനെ ഞാൻ ടൈപ്പ് പൈപ്പ്ലൈൻ, അല്ലെങ്കിൽ ടൈപ്പ്ലൈൻ എന്ന് വിളിക്കും.

അസ്തിത്വം അവസ്ഥ

ഈ ട്രിക്ക് ഉപയോഗിച്ച്, സ്റ്റാറ്റിക്കലി-ടൈപ്പ് ചെയ്ത ഭാഷകളിൽ, അനധികൃത അവസ്ഥയുള്ള കോഡ് കംപൈൽ ചെയ്യില്ല. ഡൈനാമിക്കലി ടൈപ്പ് ചെയ്തവയിൽ, നിങ്ങൾക്ക് ഒരു TypeError ലഭിക്കുന്നില്ലെങ്കിൽ, നിങ്ങൾക്ക് ഒരു ഗ്യാരണ്ടീഡ് ലീഗൽ അവസ്ഥ ഉണ്ടാകും.

ഇത് ഇങ്ങനെ പ്രവർത്തിക്കുന്നു:

  • ഒരു ടൈപ്പ് ഒരു അവസ്ഥ യുമായി ബന്ധിപ്പിക്കുക
  • യുടെ ഒരു ഇൻസ്റ്റൻസ് ഒബ്ജക്റ്റ് ന്റെ അസ്തിത്വം ഞങ്ങൾ അവസ്ഥയിലാണെന്ന് ഉറപ്പാക്കുക

ഇത് അത്ര ലളിതമാണ്. ഇനി നമുക്ക് മുമ്പത്തെ കോഡ് റീഫാക്ടർ ചെയ്യാൻ ശ്രമിക്കാം. നമ്മുടെ പ്രോഗ്രാമിന്റെ സാധുവായ അവസ്ഥകൾ പരിഗണിക്കുക

അവസ്ഥ URL അറിയാം ഫയൽ ഡൗൺലോഡ് ചെയ്തു ഫയൽ ഇൻഡെക്സ് ചെയ്തു
1
2
3

ഇത് ഒരു ലളിതമായ ലീനിയർ പൈപ്പ്ലൈൻ ആണെന്ന് വ്യക്തമാണ്. അവസ്ഥ 1 ലേക്ക് ഒരു URL ഇൻപുട്ട് ആവശ്യമാണ്, അവസ്ഥ 2 ലേക്ക് അവസ്ഥ 1 ആവശ്യമാണ്, അവസ്ഥ 3 ലേക്ക് അവസ്ഥ 2 ആവശ്യമാണ്.

എന്നത് അവസ്ഥ യുമായി ബന്ധപ്പെട്ട ടൈപ്പ് ആണെങ്കിൽ, ന്റെ ഒരു ഇൻസ്റ്റൻസ് നിർമ്മിക്കുന്നത് ന്റെ ഒരു ഇൻസ്റ്റൻസ് വഴി മാത്രമേ ആകാനാകൂ. നമുക്ക് അവസ്ഥ 1 ഉപയോഗിച്ച് ആരംഭിക്കാം, അതിന് ഒരു സാധുവായ URL മാത്രമേ ആവശ്യമുള്ളൂ.

class FileURL: # അതായത് T_1
	def __init__(self, url):
		# ഐച്ഛികമായി URL സാധുത പരിശോധിക്കുക
		self.url = url

നിർമ്മിക്കുന്നത് ന്റെ ഒരു ഇൻസ്റ്റൻസ് വഴി മാത്രമേ ആകാനാകൂ എന്ന് ഞങ്ങൾ ആഗ്രഹിക്കുന്നതിനാൽ, ലേക്ക് ഒരു മെത്തേഡ് ചേർക്കാം, അത് നിർമ്മിക്കുന്നു (ഫയൽ ഡൗൺലോഡ് ചെയ്തു)

class FileURL:
	# മറ്റ് മെത്തേഡുകൾ ...
	def download_file(self, file_url: FileURL) -> DownloadedFile:
		file_contents = requests.get(file_url).text
		return DownloadedFile(file_contents)

class DownloadedFile:
	def __init__(self, file_contents: str):
		self.contents = file_contents

ഇനി ലേക്ക് ഇത് ആവർത്തിക്കാം, അത് ഒരു ഇൻഡെക്സ് ചെയ്ത ഫയൽ പ്രതിനിധീകരിക്കുന്നു

class DownloadedFile:
	# മറ്റ് മെത്തേഡുകൾ ...
	def index_file(self) -> IndexedFile:
		index = {}
		for char in content:
            index[char] = index.get(char, 0) + 1
		return IndexedFile(index)

class IndexedFile:
	def __init__(self, index: dict[str, int]):
		self.index = index

	def get_count(self, target_char):
		return self.index.get(target_char, 0)

ഇപ്പോൾ, ഈ ക്ലാസുകൾ എല്ലാം ആശയം പ്രദർശിപ്പിക്കുന്നതിന് മാത്രമാണ്. യഥാർത്ഥത്തിൽ ഞങ്ങൾക്ക് ഒരു ഡൗൺലോഡ് ചെയ്തതും ഇൻഡെക്സ് ചെയ്യാത്തതുമായ ഫയലിനോ അല്ലെങ്കിൽ ഒരു സ്ട്രിംഗ് മാത്രം റാപ്പ് ചെയ്യുന്ന URL ക്ലാസിനോ ഉപയോക്താവിന് ആവശ്യമില്ല. അവർക്ക് ഫയൽ ഡൗൺലോഡ് ചെയ്യാനും കാരക്റ്റർ കൗണ്ടുകൾ ലഭിക്കാനും മാത്രമേ ആവശ്യമുള്ളൂ.

അതിനാൽ, ഞങ്ങൾക്ക് ആ അവസ്ഥകളുമായി ബന്ധപ്പെട്ട ടൈപ്പുകൾ നീക്കം ചെയ്യാനും ലോജിക് ഒരു ട്രാൻസിഷൻ മെത്തേഡിലോ കൺസ്ട്രക്ടറിലോ സ്റ്റഫ് ചെയ്യാനും കഴിയും.

class FileURL:
	def __init__(self, url):
		self.url = url

	# അവസ്ഥ 1 -> 3
	def fetch_index(self) -> CharIndex:
		# അവസ്ഥ 1 -> 2
		content = requests.get(url).text
		# അവസ്ഥ 2 -> 3
		return CharIndex(content)

class CharIndex:
	# അവസ്ഥ 2 -> 3
	def __init__(self, content: str):
		index = {}
		for char in content:
            index[char] = index.get(char, 0) + 1
		self.index = index

	def get_count(self, target_char):
		return self.index.get(target_char, 0)

ഉപയോഗം:

file = FileURL("https://world.hey.com/dhh/programming-types-and-mindsets-5b8490bc")
index = file.fetch_index()
count = index.get_count('a')

ഇപ്പോൾ നിങ്ങൾക്ക് കാണാനാകും, ട്രാൻസിഷൻ/കൺസ്ട്രക്ഷൻ ഗ്യാരണ്ടികൾ ഉപയോഗിച്ച് അനധികൃത അവസ്ഥ ഇനി ഒരു പ്രശ്നമല്ല.

എന്നിരുന്നാലും, ചില മുന്നറിയിപ്പുകൾ ഉണ്ട്. ഈ പാറ്റേൺ പ്രവർത്തിക്കുന്നത് ഇനിപ്പറയുന്നവയിലൂടെ മാത്രമാണ്:

  1. അവസ്ഥകൾ കംപൈൽ/കോഡ് എഴുതുന്ന സമയത്ത് അറിയാം (അതായത്, ലൈൻ ലെ ഒബ്ജക്റ്റിന് അവസ്ഥ ഉണ്ടായിരിക്കണം)
  2. അത്തരം അവസ്ഥകൾ കുറച്ച് മാത്രമേ ഉള്ളൂ, കാരണം നിങ്ങൾക്ക് ഓരോന്നിനും ഒരു പുതിയ ക്ലാസ് സൃഷ്ടിക്കേണ്ടി വന്നേക്കാം

ചില ഗുണങ്ങൾ

ഗാർബേജ് കളക്ട് ചെയ്യുന്ന ഭാഷകളിൽ, ഒരു വലിയ ഗുണം മെമ്മറി കാര്യക്ഷമതയാണ്. നമ്മുടെ ഉദാഹരണത്തിലേക്ക് തിരിച്ചുപോയാൽ, യഥാർത്ഥ ക്ലാസിൽ, ഡൗൺലോഡ് ചെയ്ത ഫയലിന് മുഴുവൻ ഒബ്ജക്റ്റിന്റെയും ലൈഫ്റ്റൈം ഉണ്ട്. ഇതിനർത്ഥം, ഒബ്ജക്റ്റിലേക്ക് എന്തെങ്കിലും റഫറൻസ് നിലനിൽക്കുന്നിടത്തോളം, സൈറ്റിന്റെ മുഴുവൻ സ്ട്രിംഗും മെമ്മറിയിൽ സംഭരിച്ചിരിക്കുന്നു.

counter = FileDownloadCharCounter(...)
counter.download_file()  # സ്ട്രിംഗിനായി സ്ഥലം അനുവദിച്ചു
counter.create_index()   # ഇൻഡെക്സ് ഡിക്ഷണറി അനുവദിച്ചു
counter.get_count('a')

# സ്കോപ്പ് അവസാനിക്കുമ്പോൾ എല്ലാം മോചിപ്പിക്കുന്നു

എന്നാൽ ടാസ്കിൽ നിന്ന് നമുക്കറിയാം, ഇൻഡെക്സ് സൃഷ്ടിച്ച ശേഷം ഫയൽ ഉള്ളടക്കം ആവശ്യമില്ല. ടൈപ്പ്ലൈൻ ഡാറ്റ ട്രാൻസ്ഫോർമേഷനെ അടിസ്ഥാനമാക്കിയാണ് നിർമ്മിച്ചിരിക്കുന്നത്, അതിനാൽ ലൈഫ്റ്റൈമുകൾ വ്യക്തമായി നിർവചിച്ചിരിക്കുന്നു. ഒരു ഡാറ്റ ആവശ്യമില്ലെങ്കിൽ, അത് ജിസി ഉപയോഗിച്ച് സുരക്ഷിതമായി നശിപ്പിക്കാം.

file = FileURL(...)
index = file.fetch_index() # സ്ട്രിംഗ് അനുവദിച്ചു, ഉടൻ തന്നെ മോചിപ്പിക്കുന്നു
count = index.get_count('a') # ഇൻഡെക്സ് അനുവദിച്ചു
# സ്കോപ്പ് അവസാനിക്കുമ്പോൾ ഇൻഡെക്സ് മോചിപ്പിക്കുന്നു

ഇത് പ്രത്യേകിച്ചും ഉപയോഗപ്രദമാണ്, നമ്മൾ ഡൗൺലോഡ് ചെയ്ത ഫയൽ നിരവധി ജിബി ആണെങ്കിൽ, അല്ലെങ്കിൽ ആയിരക്കണക്കിന് വെബ്സൈറ്റുകൾ ഒരേസമയം സ്ക്രാപ്പ് ചെയ്യുകയാണെങ്കിൽ.

ഉപസംഹാരം

ഈ ലേഖനം streamrip v2 എഴുതുമ്പോൾ ഉപയോഗപ്രദമായ ഒരു ലളിതമായ ഡിസൈൻ പാറ്റേൺ വിവരിക്കുന്നു, ഇത് v1-ൽ സംഭവിക്കാൻ സാധ്യതയുള്ള വളരെയധികം സ്റ്റേറ്റ് പിശകുകൾ പരിഹരിക്കുകയും കോഡ്ബേസ് ഗണ്യമായി ലളിതമാക്കുകയും ചെയ്തു. ഈ കൃത്യമായ ആശയം ഞാൻ മുമ്പ് കണ്ടിട്ടില്ലെങ്കിലും, ഇത് ഒരു പുതിയ കണ്ടുപിടിത്തമല്ല. ടൈപ്പ്ലൈൻ എന്നത് ഒരു ഡിഎഫ്എ (DFA) ഒബ്ജക്റ്റ്-ഓറിയന്റഡ് രീതിയിൽ എൻകോഡ് ചെയ്യുന്നതാണ്, കൂടാതെ ചില സൈഡ് ഇഫക്റ്റ് മാനേജ്മെന്റും ഉണ്ട്. അതിനാൽ ഡിഎഫ്എയിൽ ചെയ്തിട്ടുള്ള എല്ലാ സൈദ്ധാന്തിക പ്രവർത്തനങ്ങളും ഇവിടെ തുല്യമായി ബാധകമാണ്.

ഈ പാറ്റേൺ നിങ്ങൾ എവിടെയെങ്കിലും കണ്ടെത്തിയിട്ടുണ്ടെങ്കിൽ എന്നെ അറിയിക്കുക!


  1. ഇന്റർപ്രെറ്റഡ് എന്ന് നാം വിളിക്കുന്ന ആധുനിക ഭാഷകൾ യഥാർത്ഥത്തിൽ JIT (ജസ്റ്റ്-ഇൻ-ടൈം) കംപൈലേഷൻ ഉപയോഗിച്ചാണ് കംപൈൽ ചെയ്യുന്നത്. “ഇന്റർപ്രെറ്റഡ്” എന്ന പദം ഉപയോഗിക്കുന്നത് തെറ്റായ ടൈപ്പിംഗ് ഉള്ള ഒരു പ്രോഗ്രാം ഇപ്പോഴും പ്രവർത്തിക്കാൻ കഴിയുമെന്ന് സൂചിപ്പിക്കാൻ ആണ്. ↩︎

✦ No LLMs were used in the ideation, research, writing, or editing of this article.