একটি পরিষ্কার আর্কিটেকচার - স্প্রিংয়ের জন্য আমার কি পরিষেবা এবং ভান্ডারগুলির মধ্যে একটি স্তর ব্যবহার করা উচিত?


9

আমি একটি আর্কিটেকচারে কাজ করছি, এটি ওয়েব ক্লায়েন্ট এবং মোবাইল অ্যাপ্লিকেশনগুলির জন্য একটি বিশ্রাম এপিআই প্রদান করবে। আমি স্প্রিং (স্প্রিং এমভিসি, স্প্রিং ডেটা জেপি, ... ইত্যাদি) ব্যবহার করছি। ডোমেন মডেলটি জেপিএ স্পেসিফিকেশন সহ কোডড।

আমি পরিষ্কার আর্কিটেকচারের কিছু ধারণাগুলি প্রয়োগ করার চেষ্টা করছি ( https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html )। সমস্ত নয়, কারণ আমি জেপিএ ডোমেন মডেল রাখছি।

স্তরগুলির মাধ্যমে প্রকৃত প্রবাহটি হ'ল:

সম্মুখ সমাপ্তি <--> এপিআই পরিষেবা -> পরিষেবা -> সংগ্রহস্থল -> ডিবি

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

আমার সন্দেহ: পরিষেবা এবং ভান্ডারগুলির মধ্যে আমার কি অতিরিক্ত স্তর ব্যবহার করা উচিত?

আমি এই নতুন প্রবাহের পরিকল্পনা করছি:

সম্মুখ সমাপ্তি <--> এপিআই পরিষেবা -> পরিষেবা -> অধ্যবসায় -> ভান্ডার -> ডিবি

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

class ProductServiceImpl implements ProductService {
    ProductRepository productRepository;
    void save(Product product) {
        // do business logic
        productRepository.save(product)
    }
}

সুতরাং আমি ভাবছি এইরকম একটি অধ্যবসায় স্তর ব্যবহার করুন:

class ProductServiceImpl implements ProductService {
    ProductPersistence productPersistence;
    void save(Product product) {
        // do business logic
        productPersistence.save(product)
    }
}

এবং অবিরাম স্তরের বাস্তবায়ন:

class ProductPersistenceImpl implements ProductPersistence {
    ProductRepository productRepository;
    void save(Product product) {
        productRepository.save(product)
    }
}

সুতরাং আমার কেবল দৃ pers়তার স্তরটির প্রয়োগগুলি পরিবর্তন করা দরকার, পরিবর্তন ছাড়াই পরিষেবাটি ছেড়ে দেওয়া হয়েছে the সংগ্রহস্থল কাঠামোর সাথে সম্পর্কিত with

আপনি কি মনে করেন? ধন্যবাদ।


3
সংগ্রহস্থলটি বিমূর্ত স্তর। আরেকটি সাহায্য না করে
ইওয়ান

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

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

উত্তর:


6

সম্মুখ সমাপ্তি <--> এপিআই পরিষেবা -> পরিষেবা -> সংগ্রহস্থল -> ডিবি

ঠিক। স্প্রিং ফ্রেমওয়ার্ক প্রস্তাবিত উদ্বেগগুলি পৃথক করে এটির মূল নকশা। সুতরাং আপনি " বসন্তের সঠিক পথে " রয়েছেন

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

স্প্রিং উপাদানগুলিতে অনুবাদিত, আপনার নকশার অনুরূপ

@RestController > @Service > @Repository >  EntityManager

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

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

    @Repository
    public class MyRepositoryImpl implements MyRepository{
        private EntityManager em;

        @Autowire
        public MyRepository (EntityManager em){    
             this.em = em;
        }

        //Interface implentation
        //...
    }

ডেটা উত্স পরিবর্তন করা এখন একটি নতুন বাস্তবায়ন নেবে যা সত্তা ম্যানেজারকে একটি অন্য ডেটা উত্সের সাথে প্রতিস্থাপন করে ।

    //@RestController > @Service > @Repository >  RestTemplate

    @Repository
    public class MyRepositoryImpl implements MyRepository{
        private RestTemplate rt;

        @Autowire 
        public MyRepository (RestTemplate rt){    
             this.rt = rt;
        }

        //Interface implentation
        //...
    }
    //@RestController > @Service > @Repository >  File

    @Repository
    public class MyRepositoryImpl implements MyRepository{

        private File file; 
        public MyRepository (File file){    
            this.file = file;
        }

        //Interface implentation
        //...
    }
    //@RestController > @Service > @Repository >  SoapWSClient

    @Repository
    public class MyRepositoryImpl implements MyRepository{

        private MyWebServiceClient wsClient; 

        @Autowire
        public MyRepository (MyWebServiceClient  wsClient){    
               this.wsClient = wsClient;
        }

        //Interface implentation
        //...
    }

ইত্যাদি। 2

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


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

2: অনুরূপ সমাধান হ'ল বসন্তের সংগ্রহস্থল ইন্টারফেসগুলিকে কাস্টম ইন্টারফেসের সাথে মিশ্রিত করে। আরও তথ্যের জন্য, বেসরেপোজিটরিফ্যাক্টরিবিয়ান এবং @ নোরোপোসিটরিবিয়ান অনুসন্ধান করুন । যাইহোক, আমি এই পদ্ধতিরটি জটিল এবং বিভ্রান্তিকর পেয়েছি।


3

কোনও নকশা নমনীয় তা প্রমাণ করার সর্বোত্তম উপায় হ'ল এটি নমনীয়।

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

ঠিক আছে, পরীক্ষা করা যাক এই শান্ট স্তরটি কোনও ভাল কাজ করেছে কিনা। এমন একটি সমতল ফাইল স্তর তৈরি করুন যা আপনার পণ্যগুলিতে ফাইলগুলিতে বজায় থাকবে। এখন এই নকশায় এই নতুন স্তরটি কোথায় যায়?

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

বিবেচনা করুন, সম্ভবত সংগ্রহস্থল একটি বাস্তবায়ন বিশদ। সর্বোপরি আমি সংগ্রহস্থল প্যাটার্নটি ব্যবহার না করেই ডিবির সাথে কথা বলতে পারি।

Front end <--> API Service -> Service -> Repository -> DB

Front end <--> API Service -> Service -> Repository -> Files

Front end <--> API Service -> Service -> Persistence -> DB

Front end <--> API Service -> Service -> Persistence -> Files

আপনি যদি পরিষেবাটি স্পর্শ না করে সমস্ত কাজ করতে পারেন তবে আপনার নমনীয় কোড রয়েছে।

তবে এর জন্য আমার কথাটি নেবেন না। এটি লিখুন এবং দেখুন কি হয়। আমি নমনীয় হতে বিশ্বাস করি একমাত্র কোড হ'ল ফ্লেক্স কোড।

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