2011-12-20 15 views
5

मान लें कि हमारे पास एक ऐसी परियोजना है जो बहुत सारे डेटा (कर्मचारियों, शेड्यूल, कैलेंडर .... और बहुत कुछ) को संभालेगी। क्लाइंट विंडोज ऐप है, सर्वर पक्ष डब्ल्यूसीएफ है। डेटाबेस एमएस एसक्यूएल सर्वर है। मैं उलझन में हूं कि किस दृष्टिकोण का उपयोग करना है। मैंने कुछ लेख और ब्लॉग पढ़े हैं जो वे सभी अच्छे लगते हैं लेकिन मैं उलझन में हूं। मैं एक दृष्टिकोण से शुरू नहीं करना चाहता हूं और फिर दूसरे को चुनने पर पछतावा नहीं करना चाहता हूं। इस परियोजना में लगभग 30-35 विभिन्न ऑब्जेक्ट प्रकार होंगे। डाटा का एक बहुत अलग रिपोर्टों में पुन: प्राप्त करने ... आदिक्लाइंट/सर्वर प्रोजेक्ट के लिए कौन सा डिज़ाइन बेहतर है, डेटा साझा करने के साथ

दृष्टिकोण 1:

// classes that hold data 

public class Employee 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ..... 
} 

public class Assignment 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    ..... 
} 
..... 

डेटा बचत और वापस लाने से निपटने के लिए फिर हेल्पर कक्षाएं:

public static class Employees 
{ 
    public static int Save(Employee emp) 
    { 
     // save the employee 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 
    ..... 
} 

public static class Assignments 
{ 
    public static int Save(Assignment ass) 
    { 
     // save the Assignment 
    } 
    ..... 
} 

FYI करें, कर्मचारी और असाइनमेंट जैसे ऑब्जेक्ट क्लास सेवर और क्लाइंट के बीच साझा करने के लिए एक अलग असेंबली में होंगे। वैसे भी, इस दृष्टिकोण के साथ मेरे पास एक क्लीनर ऑब्जेक्ट्स होगा। हेल्पर कक्षाएं अधिकांश काम करेंगे।

दृष्टिकोण 2:

// classes that hold data and methods for saving and retrieving 

public class Employee 
{ 
    // constructors 
    public Employee() 
    { 
     // Construct a new Employee 
    } 
    public Employee(int Id) 
    { 
     // Construct a new Employee and fills the data from db 
    } 

    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ..... 

    public int Save() 
    { 
     // save the Employee 
    } 
    ..... 
} 

public class Assignment 
{ 
    // constructors 
    public Assignment() 
    { 
     // Construct a new assignment 
    } 
    public Assignment(int Id) 
    { 
     // Construct a new assignment and fills the data from db 
    } 

    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    ..... 

    public int Save() 
    { 
     // save the Assignment 
    } 
    ..... 
} 
..... 
इस दृष्टिकोण के साथ

, प्रत्येक वस्तु का अपना काम करना होगा .. अब भी डेटा WCF से ग्राहक के लिए आसानी से WCF केवल शेयर गुण के बाद से स्थानांतरित किया जा सकता।

दृष्टिकोण 3:

इकाई की रूपरेखा का उपयोग करना .. तथ्य यह है कि मैं इसके साथ काम नहीं (जो अच्छा है के बाद से मैं कुछ नया सीखने के लिए है) मैं ग्राहक के बीच डेटा स्थानांतरित करने के Pocos बनाने की आवश्यकता होगी बगल में और डब्ल्यूसीएफ ..

अब, कौन सा बेहतर है? अधिक विकल्प?

+0

एक अच्छा सवाल है, लेकिन शायद प्रोग्रामर के लिए बेहतर फिट है। – jwiscarson

उत्तर

0

मैं इकाई फ्रेमवर्क + रिपोजिटरी पैटर्न का उपयोग करने का सुझाव दूंगा। इस तरह आपकी संस्थाएं बिना किसी तर्क के सरल वस्तुएं होती हैं। सभी पुनर्प्राप्ति-सहेजने वाले तर्क भंडार में रहते हैं। मेरे पास जेनेरिक रिपोजिटरी का उपयोग करने के साथ कुछ सफल अनुभव है, जिसे इकाई के साथ टाइप किया गया है, कुछ इसी तरह वर्णित है here (आलेख का सामान्य भंडार भाग)। इस तरह आप केवल एक बार रिपोजिटरी कोड लिखते हैं और आप इसे अपने सभी संस्थाओं के लिए पुन: उपयोग कर सकते हैं। उदाहरण के लिए:

interface IRepositry<T> 
{ 
T GetById(long id); 
bool Save(T entity); 
} 

public class Repository<T> : IRepository<T> {...} 

var repository = new Repository<MyEntity>(); 
var myEntity = repository.GetById(1); 
var repository2 = new Repository<MySecondEntity>(); 
var mySecondEntity = repository.GetById(1); 

जब भी एक इकाई कुछ बहुत ही विशेष आपरेशन की जरूरत है, तो आप IRepository का एक ठोस टाइप किया कार्यान्वयन के लिए यह कार्रवाई जोड़ सकते हैं:

interface IMySuperRepositry : IRepository<MySuperEntity> 
{ 
    MySuperEntity GetBySuperProperty(SuperProperty superProperty); 
} 

public class MySuperEntityRepository : Repository, IMySuperRepository 
{...} 

खजाने बनाने के लिए यह एक कारखाना है, उपयोग करने के लिए अच्छा है जो कॉन्फ़िगरेशन फ़ाइल पर उदाहरण के लिए आधारित है। इस तरह आप भंडारों के कार्यान्वयन को स्विच कर सकते हैं, उदा।

public class RepositoryFactory 
{ 
    IRepository<T> GetRepository<T>() 
{ 
    if (config == production) 
    return new Repository<T>(); // this is implemented with DB access through EF 
    if (config == test) 
    return new TestRepository<T>(); // this is implemented with test values without DB access 
} 
} 

} }

आप बचत और इस पर आगे की विस्तृत के लिए सत्यापन नियमों जोड़ सकते हैं: इकाई परीक्षण के लिए, जब आप नहीं भंडार है कि वास्तव में डीबी तक पहुँचता उपयोग करना चाहते हैं। ईएफ आपको उत्पन्न इकाइयों को कुछ सरल तरीकों या गुणों को जोड़ने देता है, क्योंकि उनमें से सभी आंशिक कक्षाएं हैं।

इसके अलावा Pocos या STES (बाद में देखें) यह एक परियोजना में edmx डीबी मॉडल के लिए संभव है, और एक अन्य परियोजना में है और इस तरह से अपने सभी संस्थाओं ग्राहक को यह DLL (जो केवल अपनी संस्थाओं में शामिल होंगे) वितरित का उपयोग कर। जैसा कि मैंने समझा, वही है जो आप हासिल करना चाहते हैं।

Self tracking entities (और केवल पीओसीओ नहीं) का उपयोग करने पर गंभीरता से विचार करें। मेरी राय में वे डब्ल्यूसीएफ के उपयोग के लिए बहुत अच्छे हैं। जब आप डीबी से एक इकाई प्राप्त करते हैं और इसे क्लाइंट को पास करते हैं, तो क्लाइंट इसे बदल देता है और इसे वापस देता है, आपको पता होना चाहिए कि अगर इकाई बदल दी गई थी और क्या बदला गया था। एसटीई आपके लिए यह सब काम संभालते हैं और विशेष रूप से डब्ल्यूसीएफ के लिए डिजाइन किए जाते हैं। आप क्लाइंट से इकाई प्राप्त करते हैं, ApplyChanges और Save कहें, यही वह है।

0

एक एक्सटेंशन विधि के रूप में सहेजें को लागू करने के बारे में क्या? इस तरह आपकी कक्षाएं पहले विकल्प में साफ होती हैं, लेकिन दूसरे विकल्प में ऑब्जेक्ट पर विधियों को बुलाया जा सकता है।

public static class Employee 
{ 
    public static int Save(this Employee emp) 
    { 
     // save the employee 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 

} 
2

ऑब्जेक्ट में परिशुद्धता तर्क रखना हमेशा एक बुरा विचार है।

मैं पहले अपहरण का उपयोग करूंगा। यह Repository pattern जैसा दिखता है। इस तरह, आप डेटा की प्रतिबिंब आसानी से डीबग कर सकते हैं, क्योंकि यह ऑब्जेक्ट के बाकी तर्क से स्पष्ट रूप से अलग हो जाएगा।

0

आप इसे सोच रहे हैं। प्रौद्योगिकियों और पैटर्न को लागू करने की कोशिश कर रहे हैं "सिर्फ इसलिए" या "वे यही कहते हैं" केवल समाधान को जटिल बनाता है। कुंजी एप्लिकेशन को डिज़ाइन कर रही है ताकि यह आसानी से बदल सके। यह शायद एक संदिग्ध उत्तर है, लेकिन यह सब कुछ नीचे आता है। कोड बेस को बनाए रखने और/या संशोधित करने के लिए कितना प्रयास आवश्यक है।

वर्तमान में यह लगता है कि पैटर्न और प्रथाएं अंत परिणाम के बजाय अंतिम परिणाम हैं।

+0

मैं इसे सोचने का इरादा रखता हूं .. सोचने पर आमतौर पर बुरा नहीं होता है।यह नई चीजों को सीखने की ओर जाता है .. किसी भी तरह से कोड को बनाए रखने के लिए आवश्यक प्रयासों के बारे में आपका बिंदु मुख्य बिंदु है .. लेकिन फिर भी कुछ नया करने का प्रयास करना एक बिंदु है .. –

0

इकाई फ्रेमवर्क एक अच्छा टूल है लेकिन सभी मामलों में सबसे अच्छा विकल्प नहीं है। यह इस बात पर निर्भर करेगा कि आप डेटाबेस से पढ़ने/लिखने की अपेक्षा करते हैं कि आप अपनी डब्ल्यूसीएफ सेवाओं को कितना पढ़ने/लिखने की उम्मीद करते हैं। संभवतः ईएफ की अद्भुत दुनिया में बेहतर व्यक्ति आपकी मदद करने में सक्षम होगा।अनुभव से बात करने के लिए, मैंने एक ऐसे अनुप्रयोग में LINQ-TO-SQL का उपयोग किया है जिसमें डब्ल्यूसीएफ सेवा एंडपॉइंट्स शामिल हैं और इसमें कोई समस्या नहीं थी (और वास्तव में एक लिंक के रूप में लिंक-टू-एसक्यूएल को प्यार करने के लिए आया था)।

ऐसा कहकर, यदि आप तय करते हैं कि ईएफ आपके लिए सही विकल्प नहीं है, तो ऐसा लगता है कि आप दृष्टिकोण 1 के साथ सही रास्ते पर हैं। हालांकि, मैं DataAccessLayer लागू करने की अनुशंसा करता हूं। यही है, अपने व्यवसाय वर्गों में Persist विधि को कार्यान्वित करें जो उसके बाद एक अलग डीएओ (डेटा एक्सेस ऑब्जेक्ट, या किसी ऑब्जेक्ट ऑब्जेक्ट से डेटा को बनाए रखने के लिए उपयोग की जाने वाली कक्षा) में विधियों को कॉल करता है ताकि वास्तव में इसे आपके डेटाबेस में सहेज सकें।

एक नमूना कार्यान्वयन इस प्रकार दिखाई देंगे:

public class Employee 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public void Persist() 
    { 
     EmployeeDAO.Persist(this); 
    } 
} 

public class Assignment 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 

    public void Persist() 
    { 
     AssignmentDAO.Persist(this); 
    } 
} 

public static class EmployeeDAO 
{ 
    public static int Persist(Employee emp) 
    { 
     // insert if new, else update 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 
    ..... 
} 

public static class AssignmentDAO 
{ 
    public static int Persist(Assignment ass) 
    { 
     // insert if new, else update 
    } 
    ..... 
} 

इस तरह एक पैटर्न को लाभ यह है कि आप अपने व्यापार के वर्गों साफ, अपने डेटा का उपयोग तर्क अलग रखने के लिए, जबकि अभी भी वस्तुओं दे मिलता है अपने कोड में new Employee(...).Persist(); लिखने में सक्षम होने का आसान वाक्यविन्यास।

तुम सच में पागल हो जाना चाहते हैं, तुम भी अपने Persistable वर्गों पर इंटरफेस को लागू करने पर विचार कर सकते हैं, और अपने डीएओ (रों) तर्क के रूप में उन IPersistable उदाहरणों को स्वीकार किया है।

+0

आपका दृष्टिकोण अच्छा है, ऐसा लगता है कि "दृष्टिकोण 1" और "दृष्टिकोण 2" विवाहित हो गया और आपका दृष्टिकोण एक बच्चे के रूप में था .. मैं और विकल्प और राय की प्रतीक्षा करूंगा .. –

संबंधित मुद्दे