উত্তর:
টাইপস্ক্রিপ্টে একক ক্লাসগুলি সাধারণত একটি অ্যান্টি-প্যাটার্ন হয়। পরিবর্তে আপনি কেবল নেমস্পেস ব্যবহার করতে পারেন ।
class Singleton {
/* ... lots of singleton logic ... */
public someMethod() { ... }
}
// Using
var x = Singleton.getInstance();
x.someMethod();
export namespace Singleton {
export function someMethod() { ... }
}
// Usage
import { SingletonInstance } from "path/to/Singleton";
SingletonInstance.someMethod();
var x = SingletonInstance; // If you need to alias it for some reason
export default new Singleton()
?
টিএস ২.০, যেহেতু আমরা কনস্ট্রাক্টরগুলিতে ভিজিবিলিটি মডিফায়ারগুলি সংজ্ঞায়িত করার ক্ষমতা রাখি , তাই এখন আমরা টাইপসক্রিপ্টে যেমন সিঙ্গেলন করতে পারি ঠিক তেমনই আমরা অন্যান্য ভাষা থেকেও ব্যবহার করি।
উদাহরণ দেওয়া:
class MyClass
{
private static _instance: MyClass;
private constructor()
{
//...
}
public static get Instance()
{
// Do you need arguments? Make it a regular static method instead.
return this._instance || (this._instance = new this());
}
}
const myClassInstance = MyClass.Instance;
@ ড্রেনাই আপনাকে এই প্রতিশ্রুতি দেওয়ার জন্য ধন্যবাদ যে আপনি কাঁচা সংকলিত জাভাস্ক্রিপ্ট ব্যবহার করে কোড লিখলে আপনার একাধিক তদন্তের বিরুদ্ধে সুরক্ষা থাকবে না, কারণ টিএস-এর সীমাবদ্ধতাগুলি অদৃশ্য হয়ে যায় এবং কনস্ট্রাক্টরটি লুকানো থাকবে না।
আমি সবচেয়ে ভাল উপায় খুঁজে পেয়েছি:
class SingletonClass {
private static _instance:SingletonClass = new SingletonClass();
private _score:number = 0;
constructor() {
if(SingletonClass._instance){
throw new Error("Error: Instantiation failed: Use SingletonClass.getInstance() instead of new.");
}
SingletonClass._instance = this;
}
public static getInstance():SingletonClass
{
return SingletonClass._instance;
}
public setScore(value:number):void
{
this._score = value;
}
public getScore():number
{
return this._score;
}
public addPoints(value:number):void
{
this._score += value;
}
public removePoints(value:number):void
{
this._score -= value;
}
}
আপনি এটি কীভাবে ব্যবহার করবেন তা এখানে:
var scoreManager = SingletonClass.getInstance();
scoreManager.setScore(10);
scoreManager.addPoints(1);
scoreManager.removePoints(2);
console.log( scoreManager.getScore() );
https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/
নিম্নলিখিত পদ্ধতিটি একটি সিঙ্গলটন শ্রেণি তৈরি করে যা প্রচলিত শ্রেণির মতো বহুলভাবে ব্যবহার করা যেতে পারে:
class Singleton {
private static instance: Singleton;
//Assign "new Singleton()" here to avoid lazy initialisation
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
this. member = 0;
Singleton.instance = this;
}
member: number;
}
প্রতিটি new Singleton()
অপারেশন একই উদাহরণ ফিরে আসবে। এটি তবে ব্যবহারকারীর দ্বারা অপ্রত্যাশিত হতে পারে।
নিম্নলিখিত উদাহরণটি ব্যবহারকারীর কাছে আরও স্বচ্ছ তবে পৃথক ব্যবহারের প্রয়োজন:
class Singleton {
private static instance: Singleton;
//Assign "new Singleton()" here to avoid lazy initialisation
constructor() {
if (Singleton.instance) {
throw new Error("Error - use Singleton.getInstance()");
}
this.member = 0;
}
static getInstance(): Singleton {
Singleton.instance = Singleton.instance || new Singleton();
return Singleton.instance;
}
member: number;
}
ব্যবহার: var obj = Singleton.getInstance();
new Class(...)
বাক্য গঠন প্রয়োগ করা উচিত ।
আমি এখানে নিম্নলিখিত প্যাটার্নটি না দেখে অবাক হয়েছি, যা আসলে খুব সহজ দেখাচ্ছে।
// shout.ts
class ShoutSingleton {
helloWorld() { return 'hi'; }
}
export let Shout = new ShoutSingleton();
ব্যবহার
import { Shout } from './shout';
Shout.helloWorld();
Shout
ক্লাস তৈরি করা থেকে
আপনি এর জন্য ক্লাস এক্সপ্রেশন ব্যবহার করতে পারেন (আমার বিশ্বাস 1.6 হিসাবে)।
var x = new (class {
/* ... lots of singleton logic ... */
public someMethod() { ... }
})();
বা নামের সাথে যদি আপনার শ্রেণীর অভ্যন্তরীণভাবে এর ধরণের অ্যাক্সেসের প্রয়োজন হয়
var x = new (class Singleton {
/* ... lots of singleton logic ... */
public someMethod(): Singleton { ... }
})();
অন্য বিকল্পটি হ'ল কিছু স্থির সদস্য ব্যবহার করে আপনার সিঙ্গলটনের অভ্যন্তরে একটি স্থানীয় শ্রেণি ব্যবহার করা
class Singleton {
private static _instance;
public static get instance() {
class InternalSingleton {
someMethod() { }
//more singleton logic
}
if(!Singleton._instance) {
Singleton._instance = new InternalSingleton();
}
return <InternalSingleton>Singleton._instance;
}
}
var x = Singleton.instance;
x.someMethod();
যেকোন ক্লাসে এটি "সিঙ্গলটন" করতে নিম্নলিখিত 6 টি লাইন যুক্ত করুন।
class MySingleton
{
private constructor(){ /* ... */}
private static _instance: MySingleton;
public static getInstance(): MySingleton
{
return this._instance || (this._instance = new this());
};
}
var test = MySingleton.getInstance(); // will create the first instance
var test2 = MySingleton.getInstance(); // will return the first instance
alert(test === test2); // true
[সম্পাদনা]: আপনি যদি কোনও পদ্ধতির পরিবর্তে কোনও পদ্ধতির মাধ্যমে উদাহরণটি পেতে চান তবে অ্যালেক্সের উত্তরটি ব্যবহার করুন।
new MySingleton()
5 বার বললে কি হয় ? আপনার কোড একক উদাহরণ সংরক্ষণ করে?
আমি মনে করি সম্ভবত জেনারিক ব্যাটার হতে ব্যবহার করুন
class Singleton<T>{
public static Instance<T>(c: {new(): T; }) : T{
if (this._instance == null){
this._instance = new c();
}
return this._instance;
}
private static _instance = null;
}
ব্যবহারবিধি
ধাপ 1
class MapManager extends Singleton<MapManager>{
//do something
public init():void{ //do }
}
ধাপ ২
MapManager.Instance(MapManager).init();
আপনি ফাংশন অবজেক্ট.ফ্রিজে () ব্যবহার করতে পারেন । এটি সহজ এবং সহজ:
class Singleton {
instance: any = null;
data: any = {} // store data in here
constructor() {
if (!this.instance) {
this.instance = this;
}
return this.instance
}
}
const singleton: Singleton = new Singleton();
Object.freeze(singleton);
export default singleton;
if (!this.instance)
? আপনি যদি রফতানির আগে একাধিক উদাহরণ তৈরি করেন তবে এটি কি অতিরিক্ত সতর্কতা?
আমি এর একটি নতুন সংস্করণ পেয়েছি যে টাইপসক্রিপ্ট সংকলকটি সম্পূর্ণরূপে ঠিক আছে, এবং আমি মনে করি এটি আরও ভাল কারণ এটি getInstance()
নিয়মিত কোনও পদ্ধতি কল করার প্রয়োজন হয় না ।
import express, { Application } from 'express';
export class Singleton {
// Define your props here
private _express: Application = express();
private static _instance: Singleton;
constructor() {
if (Singleton._instance) {
return Singleton._instance;
}
// You don't have an instance, so continue
// Remember, to set the _instance property
Singleton._instance = this;
}
}
এটি একটি ভিন্ন অপূর্ণতা সঙ্গে আসে। আপনার Singleton
যদি কোনও বৈশিষ্ট্য থাকে, তবে টাইপসক্রিপ্ট সংকলক কোনও মান দিয়ে সেটিকে আরম্ভ না করা পর্যন্ত ফিট নিক্ষেপ করবে। এ কারণেই আমি একটি _express
সম্পত্তি আমার উদাহরণ শ্রেণিতে অন্তর্ভুক্ত করেছি কারণ আপনি যদি এটির সাথে কোনও মান দিয়ে আরম্ভ না করেন, আপনি যদি পরে এটি নির্মাতাকে অর্পণ করেন তবেও টাইপস্ক্রিপ্ট মনে করবে এটি সংজ্ঞায়িত হয়নি। কঠোর মোড অক্ষম করে এটি ঠিক করা যেতে পারে, তবে আমি যদি সম্ভব হয় তবে তা পছন্দ করি না। এই পদ্ধতির আরও একটি নেতিবাচক দিকও আমার উল্লেখ করা উচিত, কারণ কনস্ট্রাক্টর আসলে ডাকা হচ্ছে, প্রতিবার এটির মতো অন্য উদাহরণটি প্রযুক্তিগতভাবে তৈরি করা হলেও অ্যাক্সেসযোগ্য নয়। এটি তাত্ত্বিকভাবে মেমরি ফাঁস হতে পারে।
টাইপস্ক্রিপ্টে একটি সিঙ্গলটন তৈরি করা সম্ভবত এটি দীর্ঘতম প্রক্রিয়া, তবে বৃহত্তর অ্যাপ্লিকেশনগুলিতে আমার পক্ষে আরও ভাল কাজ করেছে।
প্রথমে আপনার একটি সিঙ্গলটন ক্লাস দরকার, আসুন এটি বলা যাক, "./utils/Singleton.ts" :
module utils {
export class Singleton {
private _initialized: boolean;
private _setSingleton(): void {
if (this._initialized) throw Error('Singleton is already initialized.');
this._initialized = true;
}
get setSingleton() { return this._setSingleton; }
}
}
এখন কল্পনা করুন আপনার একটি রাউটার সিঙ্গলটন প্রয়োজন ""। / ন্যাভিগেশন / রাউটার.টস " :
/// <reference path="../utils/Singleton.ts" />
module navigation {
class RouterClass extends utils.Singleton {
// NOTICE RouterClass extends from utils.Singleton
// and that it isn't exportable.
private _init(): void {
// This method will be your "construtor" now,
// to avoid double initialization, don't forget
// the parent class setSingleton method!.
this.setSingleton();
// Initialization stuff.
}
// Expose _init method.
get init { return this.init; }
}
// THIS IS IT!! Export a new RouterClass, that no
// one can instantiate ever again!.
export var Router: RouterClass = new RouterClass();
}
দুর্দান্ত !, এখন শুরু করুন বা আপনার প্রয়োজন যেখানেই আমদানি করুন:
/// <reference path="./navigation/Router.ts" />
import router = navigation.Router;
router.init();
router.init(); // Throws error!.
এইভাবে সিঙ্গলেটগুলি করার দুর্দান্ত জিনিসটি হ'ল আপনি এখনও টাইপস্ক্রিপ্ট ক্লাসগুলির সমস্ত সৌন্দর্য ব্যবহার করেন, এটি আপনাকে দুর্দান্ত বুদ্ধি দেয়, একক যুক্তি যুক্তিটি কিছুটা আলাদা করে রাখে এবং প্রয়োজনে অপসারণ করা সহজ।
এর জন্য আমার সমাধান:
export default class Modal {
private static _instance : Modal = new Modal();
constructor () {
if (Modal._instance)
throw new Error("Use Modal.instance");
Modal._instance = this;
}
static get instance () {
return Modal._instance;
}
}
return Modal._instance
। এইভাবে, আপনি যদি new
সেই শ্রেণি হন তবে আপনি বিদ্যমান বস্তুটি পাবেন, একটি নতুন নয়।
টাইপসক্রিপ্টে, অগত্যা একজনকে new instance()
সিঙ্গলটন পদ্ধতি অনুসরণ করতে হবে না । একটি আমদানিকৃত, কনস্ট্রাক্টর-কম স্ট্যাটিক ক্লাস পাশাপাশি সমানভাবে কাজ করতে পারে।
বিবেচনা:
export class YourSingleton {
public static foo:bar;
public static initialise(_initVars:any):void {
YourSingleton.foo = _initvars.foo;
}
public static doThing():bar {
return YourSingleton.foo
}
}
আপনি ক্লাসটি আমদানি করতে পারেন এবং YourSingleton.doThing()
অন্য কোনও ক্লাসে উল্লেখ করতে পারেন । তবে মনে রাখবেন, কারণ এটি একটি স্ট্যাটিক ক্লাস, এটির কোনও নির্মাণকারী নেই তাই আমি সাধারণত এমন intialise()
পদ্ধতি ব্যবহার করি যা ক্লাস থেকে ডাকা হয় যা সিঙ্গলটন আমদানি করে:
import {YourSingleton} from 'singleton.ts';
YourSingleton.initialise(params);
let _result:bar = YourSingleton.doThing();
ভুলে যাবেন না যে একটি স্ট্যাটিক ক্লাসে, প্রতিটি পদ্ধতি এবং ভেরিয়েবলেরও স্থিতিশীল হওয়া দরকার তাই আপনার পরিবর্তে this
পুরো শ্রেণীর নামটি ব্যবহার করা উচিত YourSingleton
।
আইএফএফই ব্যবহার করে আরও প্রচলিত জাভাস্ক্রিপ্ট পদ্ধতির সাথে এটি করার আরও একটি উপায় এখানে রয়েছে :
module App.Counter {
export var Instance = (() => {
var i = 0;
return {
increment: (): void => {
i++;
},
getCount: (): number => {
return i;
}
}
})();
}
module App {
export function countStuff() {
App.Counter.Instance.increment();
App.Counter.Instance.increment();
alert(App.Counter.Instance.getCount());
}
}
App.countStuff();
একটি ডেমো দেখুন
Instance
ভেরিয়েবল যুক্ত করার কারণ কী ? আপনি কৌকড কেবল ভেরিয়েবল এবং ফাংশনগুলি সরাসরি নীচে রাখেন App.Counter
।
আরেকটি বিকল্প হ'ল আপনার মডিউলে সিম্বলগুলি ব্যবহার করা। আপনার API এর চূড়ান্ত ব্যবহারকারীর সাধারণ জাভাস্ক্রিপ্ট ব্যবহার করা হয় এমনভাবেও আপনি নিজের শ্রেণিকে সুরক্ষা দিতে পারেন:
let _instance = Symbol();
export default class Singleton {
constructor(singletonToken) {
if (singletonToken !== _instance) {
throw new Error("Cannot instantiate directly.");
}
//Init your class
}
static get instance() {
return this[_instance] || (this[_instance] = new Singleton(_singleton))
}
public myMethod():string {
return "foo";
}
}
ব্যবহার:
var str:string = Singleton.instance.myFoo();
যদি ব্যবহারকারী আপনার সংকলিত এপিআই জেএস ফাইলটি ব্যবহার করে থাকে তবে সে যদি নিজের শ্রেণিতে ম্যানুয়ালি ইনস্ট্যান্ট করার চেষ্টা করে তবে একটি ত্রুটিও পাবেন:
// PLAIN JAVASCRIPT:
var instance = new Singleton(); //Error the argument singletonToken !== _instance symbol
এটি সহজতম উপায়
class YourSingletoneClass {
private static instance: YourSingletoneClass;
private constructor(public ifYouHaveAnyParams: string) {
}
static getInstance() {
if(!YourSingletoneClass.instance) {
YourSingletoneClass.instance = new YourSingletoneClass('If you have any params');
}
return YourSingletoneClass.instance;
}
}
namespace MySingleton {
interface IMySingleton {
doSomething(): void;
}
class MySingleton implements IMySingleton {
private usePrivate() { }
doSomething() {
this.usePrivate();
}
}
export var Instance: IMySingleton = new MySingleton();
}
এইভাবে আমরা একটি ইন্টারফেস প্রয়োগ করতে পারি, রায়ান ক্যাভনফের গৃহীত উত্তরের মতো নয়।
এই থ্রেডটি ঘায়েল করার পরে এবং উপরের সমস্ত বিকল্পের সাথে চারপাশে খেলার পরে - আমি একটি সিঙ্গলটনের সাথে স্থির হয়েছি যা সঠিক নির্মাতাদের দ্বারা তৈরি করা যেতে পারে:
export default class Singleton {
private static _instance: Singleton
public static get instance(): Singleton {
return Singleton._instance
}
constructor(...args: string[]) {
// Initial setup
Singleton._instance = this
}
work() { /* example */ }
}
এটির জন্য প্রাথমিক সেটআপ (ইন main.ts
, বা index.ts
) প্রয়োজন হবে, যা সহজেই প্রয়োগ করা যেতে পারে
new Singleton(/* PARAMS */)
তারপরে, আপনার কোডের যে কোনও জায়গায়, কেবল কল করুন Singleton.instnace
; এই ক্ষেত্রে, work
সম্পন্ন করার জন্য, আমি কল করবSingleton.instance.work()