ডাটা বৈধতা: পৃথক শ্রেণি বা না?


16

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

আমার বিশেষ উদাহরণটি একটি টুর্নামেন্ট এবং একটি ইভেন্ট / বিভাগ শ্রেণীর বিষয়ে বিবেচনা করে: Tournamentএবং Event, কোন ক্রীড়া টুর্নামেন্টকে মডেল করে এবং প্রতিটি টুর্নামেন্টে এক বা একাধিক বিভাগ রয়েছে।

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

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

সুতরাং এটি সম্পর্কে কীভাবে ?: আমি আমার মডেল ক্লাসগুলির সেটারগুলি এবং ডেটা যুক্ত করতে অনুরূপ পদ্ধতিগুলি ব্যবহার করার সময় একেবারে কোনও প্রাক-চেক সম্পর্কে ভুলে গিয়েছি এবং পরিবর্তে আমি বৈধতা ক্লাসগুলিকে এটি পরিচালনা করতে দিই।

সুতরাং আমরা ভালো কিছু থাকবে EventValidatorএকটি সঙ্গে Eventএকজন সদস্য হিসাবে, এবং একটি validate()পদ্ধতি যে সমগ্র বস্তু যাচাই, প্লাস একবচন পদ্ধতি সকল সদস্যদের 'নিয়ম যাচাই করতে।

তারপরে, একটি বৈধযোগ্য অবজেক্টটি ইনস্ট্যান্ট করার আগে, আমি অবৈধ মানগুলি রোধ করার জন্য বৈধকরণটি সম্পাদন করব।

আমার নকশা কি সঠিক? আমার কি অন্যভাবে কিছু করা উচিত?

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

public Event() {
    EventValidator eventValidator = new EventValidator(this);
    if (!eventValidator.validate()) {
        // show error messages with methods defined in the validator
        throw new Exception(); // what type of exception would be best? should I create custom ones?
    }
}

উত্তর:


7

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

মনে রাখবেন যে বৈধতা বিভিন্ন মুহুর্তে ঘটতে পারে।

আপনার উদাহরণের মতো একটি কংক্রিট বৈধকরণকারী ইনস্ট্যান্ট করা একটি খারাপ ধারণা কারণ এটি আপনার ইভেন্ট শ্রেণিকে সেই নির্দিষ্ট বৈধকারীর সাথে সংযুক্ত করে।

ধরে নেওয়া যাক আপনি কোনও ডিআই ফ্রেমওয়ার্ক ব্যবহার করছেন না।

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

স্পষ্টতই একটি ভ্যালিডেটার ইন্টারফেস এবং বা বিমূর্ত শ্রেণীর লেখা উচিত যাতে আপনার ক্লাসগুলি নির্ভর করে কোনও কংক্রিট বৈধকরণকারীর উপর নয়।

কনস্ট্রাক্টরে বৈধতা পদ্ধতিটি কার্যকর করা সমস্যাযুক্ত হতে পারে কারণ আপনি যে রাষ্ট্রটি যাচাই করতে চান তা এখনও স্থানে থাকতে পারে না।

আমি প্রস্তাব দিচ্ছি যে আপনি একটি বৈধযোগ্য ইন্টারফেস তৈরি করুন এবং আপনার ক্লাসগুলি এটি প্রয়োগ করতে দিন, সেই ইন্টারফেসের একটি বৈধতা () পদ্ধতি থাকতে পারে।

এইভাবে আপনার আবেদনের উপরের উপাদানগুলি ইচ্ছামত বৈধতা পদ্ধতিটি কল করে (যা পরিবর্তিতভাবে বৈধকারীর সদস্যকে অর্পণ করা হয়)।

==> আইভালিডেবল.জভা <==

import java.util.List;

public interface IValidable {
    public void setValidator(IValidator<Event> validator_);
    public void validate() throws ValidationException;
    public List<String> getMessages();
}

==> আইভালিডেটর.জভা <==

import java.util.List;

public interface IValidator<T> {
    public boolean validate(T e);
    public List<String> getValidationMessages();
}

==> ইভেন্ট.জাভা <==

import java.util.List;

public class Event implements IValidable {

    private IValidator<Event> validator;

    @Override
    public void setValidator(IValidator<Event> validator_) {
        this.validator = validator_;
    }

    @Override
    public void validate() throws ValidationException {
        if (!this.validator.validate(this)){
            throw new ValidationException("WTF!");
        }
    }

    @Override
    public List<String> getMessages() {
        return this.validator.getValidationMessages();
    }

}

==> সিম্পিভেন্টভালিডেটর.জভা <==

import java.util.ArrayList;
import java.util.List;

public class SimpleEventValidator implements IValidator<Event> {

    private List<String> messages = new ArrayList<String>();
    @Override
    public boolean validate(Event e) {
        // do validations here, by accessing the public getters of e
        // propulate list of messages is necessary
        // this example always returns false    
        return false;
    }

    @Override
    public List<String> getValidationMessages() {
        return this.messages;
    }

}

==> বৈধতা অনুগ্রহ। জাভা <==

public class ValidationException extends Exception {
    public ValidationException(String message) {
        super(message);
    }

    private static final long serialVersionUID = 1L;
}

==> টেস্ট.জভা <==

public class Test {
    public static void main (String args[]){
        Event e = new Event();
        IValidator<Event> v = new SimpleEventValidator();
        e.setValidator(v);
        // set other thins to e like
        // e.setPlayers(player1,player2,player3)
        // e.setNumberOfMatches(3);
        // etc
        try {
            e.validate();
        } catch (ValidationException e1) {
            System.out.println("Your event doesn't comply with the federation regulations for the following reasons: ");
            for (String s: e.getMessages()){
                System.out.println(s);
            }
        }
    }
}

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

আমার উত্তরটি মূলত জটিল বৈধকরণের জন্য অন্য শ্রেণি তৈরি করা ঠিক। হার্ড কাপলিং এড়াতে এবং আরও নমনীয়তা পেতে আমি আপনার জন্য কিছু পরামর্শ যুক্ত করেছি।
তুলাইনস কর্ডোভা

যদি আমি একটি তালিকা বা dictioary ত্রুটি বার্তা যোগ ছিল, এটা হওয়া উচিত Validatorবা Validable? এবং আমি কীভাবে এই বার্তাগুলির সাথে একযোগে কাজ করতে পারি ValidationException?
দাদাবাবা

1
@ দাদাবাবা তালিকাটি আইভালিডেটর বাস্তবায়নকারীদের সদস্য হওয়া উচিত, তবে আইভিলেডেবলের সেই পদ্ধতিতে অ্যাক্সেস যুক্ত করা উচিত যাতে বাস্তবায়নকারীরা এটি প্রতিনিধিত্ব করেন। আমি ধরে নিয়েছি একাধিক বৈধতা বার্তা ফিরে আসতে পারে। নীচে নীচে n মিনিট পূর্বে সম্পাদিত লিঙ্কটি ক্লিক করুন যাতে আপনি পার্থক্য দেখতে পাবেন। আপনি পাশের পাশের ভিউ (মার্কডাউন নেই) ব্যবহার করলে এটি আরও ভাল ।
তুলাইনস কর্ডোভা

3
সম্ভবত পেডেন্টিক হচ্ছে, তবে আমি অনুমান করি যে এটি আসল বিশেষণ হিসাবে Validatableঅনেক বেশি ভাল নামValidable
ব্যবহারকারী 919426

4

আমার মডেল ক্লাসগুলির সেটার এবং ডেটা যুক্ত করতে অনুরূপ পদ্ধতি ব্যবহার করার সময় আমি একেবারে কোনও প্রাক-চেক সম্পর্কে ভুলে যাই

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

পরিবর্তে আমি বৈধতা ক্লাসগুলি বৈধতা পরিচালনা করতে দিন।

এটি বৈপরীত্য নয়। যদি বৈধতা যুক্তিবিজ্ঞানটি তার নিজস্ব শ্রেণীর ওয়ারেন্ট দেওয়ার পক্ষে যথেষ্ট জটিল হয় তবে আপনি এখনও বৈধতা ডেলিগেট করতে পারেন। এবং যদি আমি আপনাকে সঠিক বুঝতে পারি তবে আপনি এখন যা করছেন ঠিক এটি এটিই:

তারপরে, একটি বৈধযোগ্য অবজেক্টটি ইনস্ট্যান্ট করার আগে, আমি অবৈধ মানগুলি রোধ করার জন্য বৈধকরণটি সম্পাদন করব।

যদি এখনও আপনার কাছে সেটটার থাকে যা অবৈধ অবস্থায় আসতে পারে তবে বাস্তবে রাষ্ট্র পরিবর্তন করার আগে বৈধতা নিশ্চিত করতে ভুলবেন না । অন্যথায় আপনার একটি ত্রুটি বার্তা রয়েছে তবে আপনার অবজেক্টটিকে অবৈধ স্থিতি দিয়ে রেখে দেয়। আবার: আপনার অবজেক্টগুলিকে অবৈধ অবস্থা হতে বাধা দিন

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

আমার কাছে ভাল লাগছে, যেমন বৈধকারক বৈধ বা অবৈধ ইনপুটটিকে তার দৃষ্টিকোণ থেকে প্রত্যাশা করে, অবৈধ ইনপুটটিও ব্যতিক্রম নয়।

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


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

@ দাবাদাবা আমার মন্তব্যের জন্য অপেক্ষা করছিলেন, দয়া করে উপরের আপডেটটি দেখুন
ফ্যাবিয়ান শেমংলার

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

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