যেহেতু আপনি অনুরূপ প্রশ্ন জিজ্ঞাসা করেছেন , আসুন এটি ধাপে ধাপে নেওয়া যাক। এটি কিছুটা দীর্ঘ, তবে আমি এটি লেখার জন্য যে সময় ব্যয় করেছি তার চেয়ে বেশি সময় আপনার সাশ্রয় হতে পারে:
সম্পত্তি ক্লায়েন্ট কোডের পৃথক পৃথককরণের জন্য ডিজাইন করা একটি ওওপি বৈশিষ্ট্য। উদাহরণস্বরূপ, কিছু ই-শপে আপনার কাছে এই জাতীয় জিনিস থাকতে পারে:
function Product(name,price) {
this.name = name;
this.price = price;
this.discount = 0;
}
var sneakers = new Product("Sneakers",20); // {name:"Sneakers",price:20,discount:0}
var tshirt = new Product("T-shirt",10); // {name:"T-shirt",price:10,discount:0}
তারপরে আপনার ক্লায়েন্ট কোডে (ই-শপ), আপনি আপনার পণ্যগুলিতে ছাড় যোগ করতে পারেন:
function badProduct(obj) { obj.discount+= 20; ... }
function generalDiscount(obj) { obj.discount+= 10; ... }
function distributorDiscount(obj) { obj.discount+= 15; ... }
পরে, ই-শপ মালিক বুঝতে পারে যে ছাড়টি 80% বলার চেয়ে বেশি হতে পারে না। এখন আপনাকে ক্লায়েন্ট কোডে ছাড় সংশোধনের প্রতিটি ঘটনা খুঁজে পেতে এবং একটি লাইন যুক্ত করতে হবে
if(obj.discount>80) obj.discount = 80;
তারপরে ই-শপ মালিক তার কৌশলটি আরও পরিবর্তন করতে পারে, যেমন "যদি গ্রাহক পুনরায় বিক্রয়কারী হন, সর্বাধিক ছাড় 90% হতে পারে" । এবং আপনাকে আবার একাধিক স্থানে পরিবর্তন করতে হবে এবং কৌশলগুলি যে কোনও সময় পরিবর্তিত হওয়ার সাথে সাথে আপনার এই লাইনগুলি পরিবর্তন করতে হবে। এটি একটি খারাপ নকশা। এজন্যই এনক্যাপসুলেশন হ'ল ওওপির মূল নীতি। যদি কনস্ট্রাক্টরটি এমন হত:
function Product(name,price) {
var _name=name, _price=price, _discount=0;
this.getName = function() { return _name; }
this.setName = function(value) { _name = value; }
this.getPrice = function() { return _price; }
this.setPrice = function(value) { _price = value; }
this.getDiscount = function() { return _discount; }
this.setDiscount = function(value) { _discount = value; }
}
তারপর আপনি শুধু পরিবর্তন করতে পারেন getDiscount
( অ্যাকসেসর ) এবং setDiscount
( mutator ) পদ্ধতি। সমস্যাটি হ'ল বেশিরভাগ সদস্য সাধারণ ভেরিয়েবলের মতো আচরণ করেন, কেবল ছাড়টি এখানে বিশেষ যত্নের প্রয়োজন। তবে ভাল ডিজাইনের ক্ষেত্রে কোডটি সম্প্রসারণযোগ্য রাখতে প্রতিটি ডেটা সদস্যের এনক্যাপসুলেশন প্রয়োজন। সুতরাং আপনাকে প্রচুর কোড যুক্ত করতে হবে যা কিছুই করে না। এটি একটি খারাপ নকশা, একটি এবং ব্লক: বয়লারপ্লেট অ্যান্টিপ্যাটার্ন । কখনও কখনও আপনি কেবল ক্ষেত্রগুলিকে পরে পদ্ধতিগুলিতে সংশোধন করতে পারবেন না (ইশপ কোডটি বড় হতে পারে বা কোনও তৃতীয় পক্ষের কোডটি পুরানো সংস্করণের উপর নির্ভর করতে পারে), তাই বয়লারপ্লেটটি এখানে কম খারাপ। তবুও, এটি মন্দ। এ কারণেই বৈশিষ্ট্যগুলি বহু ভাষায় প্রবর্তিত হয়েছিল। আপনি মূল কোডটি রাখতে পারেন, কেবল ছাড় সদস্যকে একটি সম্পত্তিতে রূপান্তরিত করুনget
set
function Product(name,price) {
this.name = name;
this.price = price;
//this.discount = 0; // <- remove this line and refactor with the code below
var _discount; // private member
Object.defineProperty(this,"discount",{
get: function() { return _discount; },
set: function(value) { _discount = value; if(_discount>80) _discount = 80; }
});
}
// the client code
var sneakers = new Product("Sneakers",20);
sneakers.discount = 50; // 50, setter is called
sneakers.discount+= 20; // 70, setter is called
sneakers.discount+= 20; // 80, not 90!
alert(sneakers.discount); // getter is called
শেষ কিন্তু একটি লাইন নোট করুন: সঠিক ছাড়ের মানটির জন্য ক্লায়েন্ট কোড (ই-শপ সংজ্ঞা) থেকে পণ্যের সংজ্ঞাতে স্থানান্তরিত হয়েছিল। পণ্যটি তার ডেটা সদস্যদের ধারাবাহিক রাখার জন্য দায়ী। কোডটি যদি আমাদের চিন্তাভাবনাগুলির মতো একইভাবে কাজ করে তবে ভাল নকশা (মোটামুটিভাবে বলা হয়) is
সম্পত্তি সম্পর্কে তাই অনেক। তবে জাভাস্ক্রিপ্ট সি # এর মতো খাঁটি অবজেক্ট-ভিত্তিক ভাষা থেকে আলাদা এবং বৈশিষ্ট্যগুলি আলাদাভাবে কোড করে:
সি # তে , ক্ষেত্রগুলিকে বৈশিষ্ট্যগুলিতে রূপান্তর করা একটি ব্রেকিং পরিবর্তন , সুতরাং আপনার কোডটি পৃথকভাবে সংকলিত ক্লায়েন্টে ব্যবহার করা যেতে পারে তবে সর্বজনীন ক্ষেত্রগুলি স্বতঃ-প্রয়োগকৃত বৈশিষ্ট্য হিসাবে কোড করা উচিত ।
জাভাস্ক্রিপ্টে , স্ট্যান্ডার্ড বৈশিষ্ট্যগুলি (উপরে বর্ণিত গেটর এবং সেটার সহ ডেটা সদস্য) অ্যাক্সেসর বর্ণনাকারী দ্বারা সংজ্ঞায়িত করা হয়েছে (আপনার প্রশ্নের সাথে থাকা লিঙ্কটিতে)। একচেটিয়াভাবে, আপনি ব্যবহার করতে পারেন তথ্য বর্ণনাকারী (যাতে আপনি অর্থাত ব্যবহার করতে পারবেন না মান এবং সেট একই সম্পত্তি):
- অ্যাক্সেসর বর্ণনাকারী = পান + সেট (উপরে উদাহরণ দেখুন)
- get একটি ফাংশন হতে হবে; এর রিটার্ন মান সম্পত্তি পড়তে ব্যবহৃত হয়; যদি নির্দিষ্ট না করা থাকে তবে ডিফল্টটি অপরিজ্ঞাত হয় , যা এমন ফাংশনের মতো আচরণ করে যা অপরিবর্তিত থাকে returns
- সেট একটি ফাংশন হতে হবে; এর প্যারামিটারটি সম্পত্তিটির কোনও মূল্য নির্ধারণের ক্ষেত্রে আরএইচএস দিয়ে পূর্ণ; যদি নির্দিষ্ট না করা হয় তবে ডিফল্টটি অপরিজ্ঞাত , যা খালি ফাংশনের মতো আচরণ করে
- ডেটা বর্ণনাকারী = মান + লিখনযোগ্য (নীচের উদাহরণ দেখুন)
- মান ডিফল্ট undefined ; যদি লিখনযোগ্য , কনফিগারযোগ্য এবং গণনাযোগ্য (নীচে দেখুন) সত্য হয় তবে সম্পত্তিটি একটি সাধারণ ডেটা ক্ষেত্রের মতো আচরণ করে
- লিখনযোগ্য - ডিফল্ট মিথ্যা ; যদি সত্য না হয়তবে সম্পত্তিটি কেবল পঠিত হয়; লেখার চেষ্টা ত্রুটি ছাড়াই উপেক্ষা করা হয় *!
উভয় বর্ণনাকারীর এই সদস্য থাকতে পারে:
- কনফিগারযোগ্য - ডিফল্ট মিথ্যা ; যদি এটি সত্য না হয় তবে সম্পত্তিটি মোছা যাবে না; মুছে ফেলার চেষ্টা ত্রুটি ছাড়াই উপেক্ষা করা হয় *!
- গণনাযোগ্য - ডিফল্ট মিথ্যা ; যদি সত্য হয় তবে এটি পুনরাবৃত্তি হবে
for(var i in theObject)
; যদি মিথ্যা হয় তবে এটি পুনরাবৃত্তি হবে না, তবে এটি সর্বজনীন হিসাবে অ্যাক্সেসযোগ্য
* যদি না কঠোর মোডে থাকে - তবে সেক্ষেত্রে জেএস টাইপআরারের মাধ্যমে কার্যকর করা বন্ধ করে দেয় যদি না এটি ট্রাই -ক্যাচ ব্লকে ধরা পড়ে
এই সেটিংস পড়তে, ব্যবহার করুন Object.getOwnPropertyDescriptor()
।
উদাহরণ দিয়ে শিখুন:
var o = {};
Object.defineProperty(o,"test",{
value: "a",
configurable: true
});
console.log(Object.getOwnPropertyDescriptor(o,"test")); // check the settings
for(var i in o) console.log(o[i]); // nothing, o.test is not enumerable
console.log(o.test); // "a"
o.test = "b"; // o.test is still "a", (is not writable, no error)
delete(o.test); // bye bye, o.test (was configurable)
o.test = "b"; // o.test is "b"
for(var i in o) console.log(o[i]); // "b", default fields are enumerable
আপনি যদি ক্লায়েন্ট কোডকে এই জাতীয় চিটগুলি অনুমতি দিতে চান না, আপনি তিনটি মাত্রার বন্দিদণ্ড দ্বারা বিষয়টিকে সীমাবদ্ধ করতে পারেন:
- Object.preventExtensions (yourObject) নতুন বৈশিষ্ট্য যোগ করার জন্য বাধা দেয় yourObject । ব্যবহার করুন
Object.isExtensible(<yourObject>)
যদি পদ্ধতি বস্তুর উপর ব্যবহার করা হয়েছিল করো। প্রতিরোধ অগভীর (নীচে পড়ুন)।
- ওপজেক্ট.সিল (আপনারঅজেক্ট) উপরের মত এবং বৈশিষ্ট্যগুলি সরানো যাবে না (কার্যকরভাবে
configurable: false
সমস্ত বৈশিষ্ট্যেসেটকরে)। Object.isSealed(<yourObject>)
অবজেক্টে এই বৈশিষ্ট্যটি সনাক্ত করতেব্যবহার করুন। সিলটি অগভীর (নীচে পড়ুন)।
- ওজেক্ট.ফ্রিজে (আপনার অবজেক্ট) উপরের মত এবং বৈশিষ্ট্যগুলি পরিবর্তন করা যায় না (কার্যকরভাবে
writable: false
ডেটা বর্ণনাকারী সমস্ত বৈশিষ্ট্যের সাথেসেটকরে)। সেটারের লিখনযোগ্য সম্পত্তি প্রভাবিত হয় না (যেহেতু এটির একটি নেই)। হিমটি অগভীর : এর অর্থ হ'ল সম্পত্তি যদি অবজেক্ট হয় তবে এর বৈশিষ্ট্যগুলি হিমায়িত হয় না (আপনি যদি চান তবে আপনার "ডিপ ফ্রিজ" এর মতো কিছু করা উচিত, ডিপ কপি - ক্লোনিংয়ের মতো )। Object.isFrozen(<yourObject>)
এটি সনাক্ত করতেব্যবহার করুন।
আপনি যদি কয়েকটি লাইন মজাদার লিখেন তবে আপনাকে এটিকে বিরক্ত করার দরকার নেই। তবে আপনি যদি কোনও গেম কোড করতে চান (যেমন আপনি লিঙ্কযুক্ত প্রশ্নে উল্লেখ করেছেন), আপনার সত্যই ভাল নকশা সম্পর্কে যত্ন নেওয়া উচিত। অ্যান্টিপ্যাটার্ন এবং কোড গন্ধ সম্পর্কে কিছু গুগল করার চেষ্টা করুন । এটি আপনাকে "ওহ, আমার কোডটি পুরোপুরি আবার নতুন করে লিখতে হবে!" এর মতো পরিস্থিতি এড়াতে সহায়তা করবে ! , আপনি অনেক কোড করতে চাইলে এটি কয়েক মাস হতাশাকে বাঁচাতে পারে। শুভকামনা।