কোনও শ্রেণীর কীভাবে তার ব্যবহারকারীর সাথে যোগাযোগ করা উচিত যা এটি প্রয়োগ করে এমন উপসেটগুলি?


12

দৃশ্যপট

একটি ওয়েব অ্যাপ্লিকেশন IUserBackendপদ্ধতিগুলির সাথে একটি ব্যবহারকারী ব্যাকএন্ড ইন্টারফেসকে সংজ্ঞায়িত করে

  • getUser (ইউআইডি)
  • createUser (ইউআইডি)
  • deleteUser (ইউআইডি)
  • সেটপ্যাসওয়ার্ড (ইউআইডি, পাসওয়ার্ড)
  • ...

বিভিন্ন ব্যবহারকারীর ব্যাকেন্ডস (যেমন এলডিএপি, এসকিউএল, ...) এই ইন্টারফেসটি বাস্তবায়িত করে তবে প্রতিটি ব্যাকএন্ড সব কিছু করতে পারে না। উদাহরণস্বরূপ একটি কংক্রিট এলডিএপি সার্ভার এই ওয়েব অ্যাপ্লিকেশনটিকে ব্যবহারকারীদের মুছতে দেয় না। সুতরাং যে LdapUserBackendশ্রেণি প্রয়োগ করে সেগুলি কার্যকর IUserBackendকরবে না deleteUser(uid)

কংক্রিট শ্রেণীর ওয়েব অ্যাপ্লিকেশনটির সাথে ব্যাকএন্ডের ব্যবহারকারীদের সাথে ওয়েব অ্যাপ্লিকেশনকে যা করার অনুমতি দেওয়া হয়েছে তা যোগাযোগ করা দরকার।

সমাধান জানা

আমি একটি সমাধান দেখেছি যেখানে IUserInterfaceএর একটি implementedActionsপদ্ধতি রয়েছে যা একটি পূর্ণসংখ্যা ফেরত দেয় যা অনুরোধকৃত ক্রিয়াগুলির সাথে বিটওয়াইড অ্যান্ডডের ক্রিয়া বিটওয়াইস ওআর ফলাফল is

function implementedActions(requestedActions) {
    return (bool)(
        ACTION_GET_USER
        | ACTION_CREATE_USER
        | ACTION_DELTE_USER
        | ACTION_SET_PASSWORD
        ) & requestedActions)
}

কোথায়

  • ACTION_GET_USER = 1
  • ACTION_CREATE_USER = 2
  • ACTION_DELETE_USER = 4
  • ACTION_SET_PASSWORD = 8
  • .... = 16
  • .... = 32

প্রভৃতি

সুতরাং ওয়েব অ্যাপ্লিকেশনটি যা প্রয়োজন তার সাথে একটি বিটমাস্ক সেট করে এবং implementedActions()এটি তাদের সমর্থন করে কিনা তা বুলিয়ান সহ উত্তর দেয়।

অভিমত

আমার এই বিট ক্রিয়াকলাপগুলি সি বয়সের অবলম্বনের মতো দেখায়, পরিষ্কার কোডের শর্তাবলী বুঝতে সহজভাবে প্রয়োজনীয় নয়।

প্রশ্ন

ক্লাসের জন্য প্রয়োগ করা ইন্টারফেস পদ্ধতির উপসেটটি যোগাযোগ করার জন্য আধুনিক (আরও ভাল?) প্যাটার্নটি কী? বা উপরে থেকে "বিট অপারেশন পদ্ধতি" এখনও সর্বোত্তম অনুশীলন?

( এটি বিবেচনার ক্ষেত্রে: পিএইচপি, যদিও আমি ওও ভাষাগুলির জন্য একটি সাধারণ সমাধান খুঁজছি )


5
সাধারণ সমাধান হ'ল ইন্টারফেস বিভক্ত করা। IUserBackendথাকা উচিত নয় deleteUserএ সব পদ্ধতি। এর অংশ হওয়া উচিত IUserDeleteBackend(বা আপনি যেটিকে কল করতে চান)) ব্যবহারকারীদের মুছতে হবে এমন IUserDeleteBackendকোডে যুক্তি থাকতে হবে , কোডটির প্রয়োজন নেই যে কার্যকারিতাটি ব্যবহার করবে IUserBackendএবং অযৌক্তিক পদ্ধতিতে কোনও সমস্যা হবে না ।
বাকুরিউ

3
একটি গুরুত্বপূর্ণ নকশার বিবেচনা হ'ল কোনও ক্রিয়াকলাপের প্রাপ্যতা রানটাইম পরিস্থিতিতে নির্ভর করে কিনা। এটি কি সমস্ত এলডিএপি সার্ভারগুলি মুছে ফেলা সমর্থন করে না? বা এটি কি কোনও সার্ভারের কনফিগারেশনের সম্পত্তি এবং কোনও সিস্টেম পুনরায় আরম্ভের সাথে পরিবর্তিত হতে পারে? আপনার এলডিএপ সংযোগকারীটি কি স্বয়ংক্রিয়ভাবে এই পরিস্থিতিটি আবিষ্কার করতে পারে, বা কনফিগারেশনটি আলাদা আলাদা এলডিএপ সংযোগকারীকে বিভিন্ন ক্ষমতা সহ প্লাগ করতে পরিবর্তন করা উচিত? এই বিষয়গুলির শক্তিশালী প্রভাব রয়েছে যার উপর সমাধানগুলি কার্যকর হয়।
সেবাস্তিয়ান রেডল

@ সেবাস্তিয়ানআরডেল হ্যাঁ, এটি এমন কিছু যা আমি বিবেচনায় নিই না। রানটাইমের জন্য আমার আসলে সমাধান দরকার। যেহেতু আমি খুব ভাল উত্তরগুলিকে অকার্যকর করতে চাইনি, তাই আমি একটি নতুন প্রশ্ন খুললাম যা রানটাইমকে কেন্দ্র করে
সমস্যাফিকার ২fic

উত্তর:


24

বিস্তৃতভাবে বলতে গেলে, এখানে আপনি নিতে পারেন এমন দুটি পদ্ধতির রয়েছে: পলিমারফিজমের মাধ্যমে পরীক্ষা ও নিক্ষেপ বা রচনা।

পরীক্ষা এবং নিক্ষেপ

এটি ইতিমধ্যে আপনি বর্ণিত পদ্ধতির। কিছু উপায়ের মাধ্যমে, আপনি শ্রেণীর ব্যবহারকারীকে নির্দিষ্ট করে দিয়েছেন যে নির্দিষ্ট কিছু পদ্ধতি প্রয়োগ করা হয়েছে কি না indicate এটি একটি একক পদ্ধতিতে এবং কিছুটা বিস্তৃত গণনা (যেমন আপনি বর্ণনা করেছেন), বা supportsDelete()বিভিন্ন পদ্ধতির একটি সিরিজের মাধ্যমে করা যেতে পারে ।

তারপরে, যদি supportsDelete()ফিরে আসে false, কল করার deleteUser()ফলে NotImplementedExeptionনিক্ষেপ হতে পারে বা পদ্ধতিটি কেবল কিছু না করে।

এটি কারওর মধ্যে একটি জনপ্রিয় সমাধান, এটি সহজ। যাইহোক, অনেক - আমার অন্তর্ভুক্ত - যুক্তিযুক্ত যে এটি লিসকোভের প্রতিস্থাপনের নীতির লঙ্ঘন (সোলিডে এল) এবং অতএব এটি একটি দুর্দান্ত সমাধান নয়।

পলিমারফিজমের মাধ্যমে রচনা

এখানে পন্থাটি IUserBackendযতটা দূরের কোনও সরঞ্জামকে দেখায় । ক্লাসগুলি যদি সবসময় এই ইন্টারফেসের সমস্ত পদ্ধতি প্রয়োগ করতে না পারে তবে ইন্টারফেসটিকে আরও বেশি কেন্দ্রীভূত অংশে বিভক্ত করুন। সুতরাং আপনার কাছে থাকতে পারে: IGeneralUser IDeletableUser IRenamableUser ... অন্য কথায়, আপনার সমস্ত ব্যাকেন্ডগুলি কার্যকর করতে পারে এমন সমস্ত পদ্ধতি প্রবেশ করতে পারে IGeneralUserএবং আপনি প্রতিটি ক্রিয়াটির জন্য একটি পৃথক ইন্টারফেস তৈরি করেন যা কেবলমাত্র কিছু লোক সম্পাদন করতে পারে।

এইভাবে, LdapUserBackendবাস্তবায়ন করে না IDeletableUserএবং আপনি (সি # সিনট্যাক্স ব্যবহার করে) এর মতো একটি পরীক্ষা ব্যবহার করে এর জন্য পরীক্ষা করেন:

if (backend is IDeletableUser deletableUser)
{
    deletableUser.deleteUser(id);
}

(কোনও উদাহরণ কোনও ইন্টারফেস প্রয়োগ করে এবং আপনি কীভাবে সেই ইন্টারফেসে কাস্ট করেন তা নির্ধারণের জন্য আমি পিএইচপি-তে থাকা প্রক্রিয়া সম্পর্কে নিশ্চিত নই, তবে আমি নিশ্চিত যে সেই ভাষার কোনও সমতুল্য আছে)

এই পদ্ধতির সুবিধাটি হ'ল এটি আপনার কোডকে সলাইড নীতিমালা মেনে চলতে সক্ষম করতে পলিমারফিজমের ভাল ব্যবহার করে এবং এটি আমার দৃষ্টিতে আরও মার্জিত।

নেতিবাচক দিকটি হ'ল এটি খুব সহজেই অনাস্থার হয়ে উঠতে পারে। যদি উদাহরণস্বরূপ, আপনি কয়েক ডজন ইন্টারফেস বাস্তবায়ন করতে পারেন কারণ প্রতিটি কংক্রিটের ব্যাকএন্ডে কিছুটা আলাদা ক্ষমতা থাকে, তবে এটি কোনও ভাল সমাধান নয়। সুতরাং আমি এই পরামর্শটি আপনার পক্ষে এই উপলক্ষে আপনার জন্য ব্যবহারিক কিনা এবং যদি তা হয় তবে তা ব্যবহার করার জন্য কেবল আপনাকে পরামর্শ দেব।


4
সলিড ডিজাইন বিবেচনার জন্য +1। কোড ক্লিনারটিকে এগিয়ে রাখার জন্য বিভিন্ন পদ্ধতির সাথে উত্তরগুলি দেখানো সর্বদা সুন্দর!
কালেব

2
পিএইচপি-তে এটি হবেif (backend instanceof IDelatableUser) {...}
Rad80

আপনি ইতিমধ্যে এলএসপি লঙ্ঘনের উল্লেখ করেছেন। আমি সম্মত, তবে এতে কিছুটা যোগ করতে চেয়েছি: ইনপুট মানটি ক্রিয়াটি সম্পাদন করা অসম্ভব করে তোলে, উদাহরণস্বরূপ, কোনও Divide(float,float)পদ্ধতিতে একটি বিভাজক হিসাবে 0কে পাস করা যদি পরীক্ষা এবং থ্রো বৈধ হয় । ইনপুট মান পরিবর্তনশীল, এবং ব্যতিক্রম সম্ভাব্য মৃত্যুদণ্ডের একটি ছোট উপসেট জুড়ে। তবে আপনি যদি আপনার প্রয়োগের ধরণের উপর ভিত্তি করে ফেলে দেন তবে কার্যকর করার ক্ষেত্রে এর অক্ষমতা একটি প্রদত্ত সত্য। ব্যতিক্রমগুলি কেবলমাত্র একটি উপসেট নয়, সমস্ত সম্ভাব্য ইনপুটগুলি কভার করে। এটি এমন এক পৃথিবীর প্রতিটি ভেজা মেঝেতে "ভেজা মেঝে" চিহ্ন লাগানোর মতো যেখানে প্রতিটি তল সর্বদা ভিজে থাকে।
ফ্লাটার

কোনও ধরণের উপর নিক্ষেপ না করার নীতির জন্য একটি ব্যতিক্রম রয়েছে (পাং উদ্দেশ্যে নয়)। সি # এর জন্য, এটি হ'ল NotImplementedException। এই ব্যতিক্রমটি অস্থায়ী বিঘ্নের জন্য উদ্দিষ্ট , অর্থাত্ কোড যা এখনও বিকশিত হয়নি তবে বিকাশ করা হবে । এটি নিশ্চিতভাবে সিদ্ধান্ত নেওয়ার মতো নয় যে বিকাশ শেষ হওয়ার পরেও কোনও প্রদত্ত শ্রেণি কোনও প্রদত্ত পদ্ধতিতে কখনই কিছু করতে পারে না
ফ্ল্যাটার

উত্তরের জন্য ধন্যবাদ. আমার আসলে একটি রানটাইম সমাধান প্রয়োজন তবে এটি আমার প্রশ্নে জোর দিতে ব্যর্থ হয়েছিল। যেহেতু আমি আপনার উত্তরটি আক্রমণ করতে চাইনি, তাই আমি একটি নতুন প্রশ্ন তৈরি করার সিদ্ধান্ত নিয়েছি ।
সমস্যাসংখ্যক

5

বর্তমান অবস্থা

বর্তমান সেটআপটি ইন্টারফেস বিভাজন নীতি লঙ্ঘন করে (IOL in SOLID)।

উল্লেখ

উইকিপিডিয়া অনুসারে ইন্টারফেস পৃথককরণ নীতি (আইএসপি) বলেছে যে কোনও ক্লায়েন্টকে যে পদ্ধতিগুলি ব্যবহার না করে তার উপর নির্ভর করতে বাধ্য করা উচিত নয় । ইন্টারফেস পৃথককরণের নীতিটি ১৯৯০ এর দশকের মাঝামাঝি সময়ে রবার্ট মার্টিনই তৈরি করেছিলেন।

অন্য কথায়, এটি যদি আপনার ইন্টারফেস হয়:

public interface IUserBackend
{
    User getUser(int uid);
    User createUser(int uid);
    void deleteUser(int uid);
    void setPassword(int uid, string password);
}

তারপরে প্রতিটি শ্রেণি যা এই ইন্টারফেসটি প্রয়োগ করে তাদের অবশ্যই ইন্টারফেসের প্রতিটি তালিকাভুক্ত পদ্ধতিটি ব্যবহার করবে। বিকল্প নেই.

একটি সাধারণ পদ্ধতি আছে কিনা তা কল্পনা করুন:

public void HaveUserDeleted(IUserBackend backendService, User user)
{
     backendService.deleteUser(user.Uid);
}

আপনি যদি বাস্তবে এটি তৈরি করে থাকেন যাতে কেবল প্রয়োগকারী কিছু শ্রেণিই একজন ব্যবহারকারীকে মুছতে সক্ষম হয়, তবে এই পদ্ধতিটি মাঝে মধ্যে আপনার মুখের মধ্যে ফুঁসে উঠবে (বা কিছুই করতে পারে না)। এটি ভাল নকশা নয়।


আপনার প্রস্তাবিত সমাধান

আমি একটি সমাধান দেখেছি যেখানে IUserInterface এর একটি প্রয়োগকৃত পদ্ধতি রয়েছে যা একটি পূর্ণসংখ্যা ফেরত দেয় যা অনুরোধকৃত ক্রিয়াকলাপগুলির সাথে বিটওয়াইড অ্যান্ডেড ক্রিয়াকলাপের বিটওয়াই ওআর ফলাফল।

আপনি মূলত যা করতে চান তা হ'ল:

public void HaveUserDeleted(IUserBackend backendService, User user)
{
     if(backendService.canDeleteUser())
         backendService.deleteUser(user.Uid);
}

প্রদত্ত শ্রেণি কোনও ব্যবহারকারীকে মুছতে সক্ষম কিনা তা আমরা ঠিক কীভাবে নির্ধারণ করি তা উপেক্ষা করছি । এটি কোনও বুলিয়ান, কিছুটা পতাকা, ... তাতে কিছু আসে যায় না। এটি সমস্ত বাইনারি উত্তরে ফোটে: এটি কোনও ব্যবহারকারীকে মুছতে পারে, হ্যাঁ বা না?

যে সমস্যাটি সমাধান করবে, তাই না? ভাল, প্রযুক্তিগতভাবে, এটি না। তবে এখন, আপনি লিসকভ সাবস্টিটিউশন নীতিমালা ( এসওএলআইডিতে এল) লঙ্ঘন করছেন ।

বরং জটিল উইকিপিডিয়া ব্যাখ্যার জন্য, আমি স্ট্যাকওভারফ্লোতে একটি শালীন উদাহরণ পেয়েছি । "খারাপ" উদাহরণটি নোট করুন:

void MakeDuckSwim(IDuck duck)
{
    if (duck is ElectricDuck)
        ((ElectricDuck)duck).TurnOn();

    duck.Swim();
}

আমি ধরে নিই যে আপনি এখানে মিল খুঁজে পেয়েছেন। এটি এমন একটি পদ্ধতি যা কোনও বিমূর্ত বস্তু ( IDuck, IUserBackend) হ্যান্ডেল করার কথা বলে মনে করা হয় , তবে আপোষযুক্ত শ্রেণির নকশার কারণে প্রথমে নির্দিষ্ট প্রয়োগগুলি হ্যান্ডেল করতে বাধ্য করা হয় ( ElectricDuckএটি নিশ্চিত করুন যে এটি এমন কোনও IUserBackendশ্রেণি নয় যা ব্যবহারকারীদের মুছে ফেলতে পারে না)।

এটি একটি বিমূর্ত পদ্ধতির বিকাশের উদ্দেশ্যকে পরাস্ত করে।

দ্রষ্টব্য: এখানে উদাহরণটি আপনার কেসের চেয়ে ঠিক করা আরও সহজ। উদাহরণস্বরূপ, এটি আছে যথেষ্ট ElectricDuckবাঁকের নিজেই ভিতরেSwim() পদ্ধতি। দুটি হাঁস এখনও সাঁতার কাটতে সক্ষম, তাই কার্যকরী ফলাফল একই।

আপনি অনুরূপ কিছু করতে চাইতে পারেন। না । আপনি কেবল কোনও ব্যবহারকারীকে মুছার ভান করতে পারবেন না তবে বাস্তবে একটি শূন্য পদ্ধতি রয়েছে। যদিও এটি প্রযুক্তিগত দৃষ্টিকোণ থেকে কাজ করে, আপনার বাস্তবায়নকারী শ্রেণি যখন কিছু করার কথা বলছে তখন আসলে কিছু করবে কিনা তা জানা অসম্ভব করে তোলে। এটি অবিবেচনাযোগ্য কোডের একটি প্রজনন ক্ষেত্র।


আমার প্রস্তাবিত সমাধান

তবে আপনি বলেছিলেন যে বাস্তবায়নকারী শ্রেণীর পক্ষে এই কয়েকটি পদ্ধতিতে কেবল পরিচালনা করা সম্ভব (এবং সঠিক)।

উদাহরণস্বরূপ, আসুন আমরা বলি যে এই পদ্ধতির প্রতিটি সম্ভাব্য সংমিশ্রণের জন্য, একটি শ্রেণি রয়েছে যা এটি বাস্তবায়ন করবে। এটি আমাদের সমস্ত ঘাঁটিগুলিকে coversেকে রেখেছে।

সমাধানটি এখানে ইন্টারফেসটি বিভক্ত করা

public interface IGetUserService
{
    User getUser(int uid);
}

public interface ICreateUserService
{
    User createUser(int uid);
}

public interface IDeleteUserService
{
    void deleteUser(int uid);
}

public interface ISetPasswordService
{
    void setPassword(int uid, string password);
}

নোট করুন যে আপনি আমার উত্তরের শুরুতে এটি দেখতে পেতেন। ইন্টারফেস বিচ্ছিন্নতার নীতি নামটি ইতিমধ্যেই জানায় যে এই নীতি আপনি করতে ডিজাইন করা হয়েছে ইন্টারফেসগুলি দলবদ্ধ করা অবশ্যই যথেষ্ট মাত্রায়।

এটি আপনাকে দয়া করে যেমন ইন্টারফেসগুলিকে মিক্স এবং মেলানোর অনুমতি দেয়:

public class UserRetrievalService 
              : IGetUserService, ICreateUserService
{
    //getUser and createUser methods implemented here
}

public class UserDeleteService
              : IDeleteUserService
{
    //deleteUser method implemented here
}

public class DoesEverythingService 
              : IGetUserService, ICreateUserService, IDeleteUserService, ISetPasswordService
{
    //All methods implemented here
}

প্রতিটি শ্রেণী তাদের ইন্টারফেসের চুক্তি ভঙ্গ না করে সিদ্ধান্ত নিতে পারে যে তারা কী করতে চায় do

এর অর্থ হ'ল আমাদের কোনও নির্দিষ্ট শ্রেণি কোনও ব্যবহারকারী মুছে ফেলতে সক্ষম কিনা তা খতিয়ে দেখার দরকার নেই। IDeleteUserServiceইন্টারফেস প্রয়োগ করে এমন প্রতিটি শ্রেণি একটি ব্যবহারকারীকে মুছতে সক্ষম হবে = লিসকভ সাবস্টিটিউশন নীতি লঙ্ঘন করবে না ।

public void HaveUserDeleted(IDeleteUserService backendService, User user)
{
     backendService.deleteUser(user.Uid); //guaranteed to work
}

যদি কেউ বাস্তবায়িত না করে এমন কোনও বস্তু পাস করার চেষ্টা করে IDeleteUserServiceতবে প্রোগ্রামটি সংকলন করতে অস্বীকার করবে। এ কারণেই আমরা টাইপ সুরক্ষা পছন্দ করি।

HaveUserDeleted(new DoesEverythingService());    // No problem.
HaveUserDeleted(new UserDeleteService());        // No problem.
HaveUserDeleted(new UserRetrievalService());     // COMPILE ERROR

পাদটীকা

আমি একটি চূড়ান্তভাবে উদাহরণটি গ্রহণ করেছি, ইন্টারফেসটিকে সবচেয়ে ছোট সম্ভাব্য অংশে আলাদা করে। তবে, যদি আপনার পরিস্থিতি আলাদা হয় তবে আপনি আরও বড় অংশ নিয়ে পালাতে পারেন।

উদাহরণস্বরূপ, ব্যবহারকারী তৈরি করতে পারে এমন প্রতিটি পরিষেবা যদি সর্বদা একজন ব্যবহারকারীকে মুছতে সক্ষম হয় (এবং তদ্বিপরীত), আপনি এই পদ্ধতিগুলি একটি একক ইন্টারফেসের অংশ হিসাবে রাখতে পারেন:

public interface IManageUserService
{
    User createUser(int uid);
    void deleteUser(int uid);
}

ছোট খণ্ডগুলিতে আলাদা হওয়ার পরিবর্তে এটি করার কোনও প্রযুক্তিগত সুবিধা নেই; তবে এটি উন্নয়ন কিছুটা সহজ করে তুলবে কারণ এর জন্য কম বয়লারপ্লাইটিংয়ের প্রয়োজন।


তারা যে আচরণ করে তার দ্বারা ইন্টারফেস বিভক্ত করার জন্য +1, যা একটি ইন্টারফেসের পুরো উদ্দেশ্য।
গ্রেগ বার্গার্ড্ট

উত্তরের জন্য ধন্যবাদ. আমার আসলে একটি রানটাইম সমাধান প্রয়োজন তবে এটি আমার প্রশ্নে জোর দিতে ব্যর্থ হয়েছিল। যেহেতু আমি আপনার উত্তরটি আক্রমণ করতে চাইনি, তাই আমি একটি নতুন প্রশ্ন তৈরি করার সিদ্ধান্ত নিয়েছি ।
সমস্যাসংখ্যক

@ প্রব্লেমোফিকার: এই ক্ষেত্রেগুলির জন্য রানটাইম মূল্যায়ন খুব কমই সেরা বিকল্প, তবে এটি করার ক্ষেত্রে সত্যই আছে। এই জাতীয় ক্ষেত্রে, আপনি হয় এমন একটি পদ্ধতি তৈরি করেন যা বলা যেতে পারে তবে কোনও কাজ না করে শেষ হতে পারে (এটি TryDeleteUserপ্রতিফলিত করার জন্য কল করুন ); অথবা আপনার যদি পদ্ধতিটি সম্ভাব্য-তবে-সমস্যাজনিত পরিস্থিতি হয় তবে ইচ্ছাকৃতভাবে একটি ব্যতিক্রম ছুঁড়ে ফেলুন। একটি CanDoThing()এবং DoThing()পদ্ধতির পদ্ধতির ব্যবহার ব্যবহার করে, তবে এতে আপনার বাহ্যিক কলারদের দুটি কল ব্যবহার করা প্রয়োজন (এবং এটি করতে ব্যর্থ হওয়ার জন্য শাস্তি পেতে হবে) যা স্বজ্ঞাত হ'ল এবং মার্জিত নয়।
ফ্ল্যাটার

0

আপনি যদি উচ্চ স্তরের প্রকারগুলি ব্যবহার করতে চান তবে আপনি নিজের পছন্দ মতো ভাষাতে সেট টাইপের সাথে যেতে পারেন। আশা করা যায় এটি সেট ছেদ এবং উপসেট-নির্ধারণের জন্য কিছু সিনট্যাক্স চিনির সরবরাহ করে।

এটি মূলত জাভা এনামসেটের সাথে যা করে (সিনট্যাক্স চিনির বিয়োগ করে তবে এই, এটি জাভা)


0

.NET বিশ্বে আপনি কাস্টম বৈশিষ্ট্যযুক্ত পদ্ধতি এবং ক্লাসগুলি সাজাতে পারেন। এটি আপনার ক্ষেত্রে প্রাসঙ্গিক নাও হতে পারে।

এটি আমার কাছে মনে হচ্ছে যদিও আপনার কাছে ইস্যুটি উচ্চতর স্তরের ডিজাইনের সাথে করা আরও বেশি হতে পারে।

এটি যদি কোনও ইউআই বৈশিষ্ট্য, যেমন সম্পাদনা ব্যবহারকারী পৃষ্ঠা বা উপাদান হিসাবে থাকে তবে বিভিন্ন ক্ষমতা কীভাবে মুখোশ পরা হচ্ছে? এক্ষেত্রে 'পরীক্ষা ও নিক্ষেপ' সেই উদ্দেশ্যে একটি দুর্দান্ত অক্ষম পদ্ধতি হবে। এটি ধরে নেওয়া হয় যে প্রতিটি পৃষ্ঠা লোড করার আগে আপনি উইজেট বা উপাদানটি গোপন রাখতে হবে বা আলাদাভাবে উপস্থাপন করা উচিত কিনা তা নির্ধারণ করতে প্রতিটি ফাংশনে একটি মক কল চালাবেন। বিকল্পভাবে, আপনার একটি ওয়েব পৃষ্ঠা রয়েছে যা মূলত ব্যবহারকারীকে যে কোনও কোডিংয়ের পথে 'টেস্ট অ্যান্ড থ্রোক' ম্যানুয়াল দ্বারা উপলব্ধ তা আবিষ্কার করতে বাধ্য করে, কারণ কোনও পপ-আপ সতর্কতা না দেখানো অবধি কোনও কিছু অনুপলব্ধ তা ব্যবহারকারী আবিষ্কার করেন না।

একটি ইউআই এর জন্য, আপনি কীভাবে বৈশিষ্ট্য পরিচালনা করবেন তা সন্ধান করতে পারেন এবং নির্বাচিত বাস্তবায়নগুলি কী বৈশিষ্ট্যগুলি পরিচালনা করতে পারে তা চালিয়ে যাওয়ার পরিবর্তে সেইগুলি উপলভ্য বাস্তবায়নের পছন্দটি টাই করতে পারেন। আপনি বৈশিষ্ট্য নির্ভরতা রচনা করার জন্য ফ্রেমওয়ার্কগুলি দেখতে চাইতে পারেন এবং আপনার ডোমেন মডেলটিতে সুনির্দিষ্টভাবে সক্ষমতা সংজ্ঞায়িত করতে পারেন। এটি এমনকি অনুমোদনে বাঁধা যেতে পারে। মূলত, অনুমোদন স্তরের ভিত্তিতে কোনও সক্ষমতা উপলব্ধ কিনা বা না তা সিদ্ধান্ত নেওয়ার ক্ষেত্রে বাড়ানো যেতে পারে যে কোনও ক্ষমতা আসলে বাস্তবায়িত হয় কিনা এবং তারপরে উচ্চ স্তরের ইউআই 'বৈশিষ্ট্যগুলি' সক্ষমতা সেটগুলিতে সুস্পষ্ট ম্যাপিংস থাকতে পারে।

এটি যদি কোনও ওয়েব এপিআই হয়, তবে সময়কালের ক্ষমতা বাড়ার সাথে সাথে 'ম্যানেজার ইউজার' এপিআই বা 'ইউজার' আরএসটি রিসোর্সের একাধিক সর্বজনীন সংস্করণ সমর্থন করে সামগ্রিক নকশা পছন্দ জটিল হতে পারে।

সুতরাং সংক্ষিপ্তসার হিসাবে,। নেট বিশ্বে আপনি বিভিন্ন প্রতিবিম্ব / বৈশিষ্ট্যগুলি আগে থেকেই নির্ধারণের বিভিন্ন উপায়গুলি কাজে লাগাতে পারেন যা কোন ক্লাসগুলি প্রয়োগ করে তবে কোনও অবস্থাতেই মনে হয় আসল বিষয়গুলি সেই তথ্যের সাথে আপনি কী করছেন be

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.