हमारी परियोजना में हम वेनिला बिल्डर्स दृष्टिकोण (@see प्रभावी जावा) का उपयोग करते हैं। निम्न उदाहरण पर विचार करें:
@Entity
public class Person {
public static class Builder {
private String firstName;
private String lastName;
private PhoneNumber phone;
public Builder() {}
public Builder withFullName(String fullName) {
Preconditions.notNull(fullName);
String[] split = fullName.split(" ");
if (split == null || split.length != 2) {
throw new IllegalArgumentException("Full name should contain First name and Last name. Full name: " + fullName);
}
this.firstName = split[0];
this.lastName = split[1];
return this;
}
public Builder withPhone(String phone) {
// valueOf does validation
this.phone = PhoneNumber.valueOf(phone);
return this;
}
public Person build() {
return new Person(this);
}
}
//@Columns
private long id;//@Id
private String firstName;
private String lastName;
private String phoneNumber;
// hibernate requires default constructor
private Person() {}
private Person(Builder builder) {
this.firstName = Preconditions.notNull(builder.firstName);
this.lastName = Preconditions.notNull(builder.lastName);
this.phoneNumber = builder.phone != null ? builder.phone : null;
}
//Getters
@Nonnull
public String getFirstName() { return firstName;}
@Nonnull
public String getLastName() { return lastName;}
@Nullable
public String getPhoneName() { return phone;}
public long getId() { return id;}
}
मामले में आप कभी कभी इकाई मैं new Builder(Person person)
जो सभी डेटा वापस की प्रतिलिपि बनाएगा शुरू करने की सिफारिश करेंगे उत्परिवर्तित करना चाहते हैं, तो आप बिल्डर के साथ उत्परिवर्तित कर सकते हैं। बेशक यह नई इकाई का उत्पादन करेगा, इसलिए पुराना केवल पढ़ा जाता है।
(उत्परिवर्तन) के साथ उपयोग के रूप में सरल है:
Person.Builder personBuilder = new Person.Builder();
Person person = personBuilder.withFullName("Vadim Kirilchuk").withPhone("12345678").build();
Person modified = new Person.Builder(person).withPhone("987654321").build();
यह भी ध्यान दें कि इस उदाहरण व्यक्ति में महत्वपूर्ण है 100% अपरिवर्तनीय नहीं है (और नहीं हो सकता है) वर्ग: सब से पहले क्योंकि आईडी जेपीए द्वारा निर्धारित किया जाएगा, आलसी संघों को रनटाइम पर भी लाया जा सकता है और आखिरकार क्योंकि आपके पास फ़ील्ड फ़ाइनल नहीं हो सकता है (आवश्यक डिफ़ॉल्ट कन्स्ट्रक्टर के कारण) :(बाद वाला बिंदु मल्टीथ्रेडेड वातावरण के लिए भी चिंता का विषय है, यानी यह यह संभव है कि #build() के बाद इकाई किसी अन्य धागे को पास कर दे, सभी प्रकार की त्रुटियों का कारण बन सकती है क्योंकि अदर थ्रेड को पूरी तरह से निर्मित ऑब्जेक्ट देखने की गारंटी नहीं है।
जेपीए 2.1 विनिर्देश, अनुभाग "2.1 इकाई कक्षा", कहते हैं:
की कोई विधि या संस्था वर्ग की लगातार उदाहरण चर अंतिम हो सकता है।
एक और समान दृष्टिकोण: http://vlkan.com/blog/post/2015/03/21/immutable-persistence/
मेरे मामले में मैं सिर्फ आईडी बिल्डर बजाय ड्राफ्ट के शीर्ष पर निर्माण सेवा ..
तो
स्रोत
2015-12-09 15:44:10
को जोड़ने के लिए, आप के निर्माण के लिए एक बिल्डर का उपयोग कर रहे हैं इकाई, लेकिन अभी भी mutators है? क्या आप थोड़ा सा विस्तार कर सकते हैं? –
यह वही है जो हम करते हैं (यह सभी अनुप्रयोगों पर वैश्विक रूप से लागू नहीं हो सकता है)। मान लें कि हमारे पास एक क्लास व्यक्ति है। उसके बाद हमारे पास PersonFactoryBuilder होगा जो एक व्यक्ति ऑब्जेक्ट बनाएगा लेकिन इसे रीडेबलपर्सन में डालेगा। पठनीय पर्सन एक इंटरफ़ेस है जो केवल "प्राप्त" विधियों को उजागर करता है जिससे इसे अपरिवर्तनीय बना दिया जाता है। डीबी से प्राप्त करते समय, हमारे पास पर्सनल रिपोजिटरी (डीएओ की तरह) होती है, जो व्यक्ति को डीबी से प्राप्त करती है और इरादे (अपडेट या डिस्प्ले) के आधार पर इसे रीड करने योग्य या व्यक्ति (उत्परिवर्तनीय) देता है। यह डिजाइन जोडा-टाइम लाइब्रेरी से प्रेरित था। http://joda-time.sourceforge.net –
इंटरफेस पर कास्टिंग! अमूर्तता के लिए हुरेय। यह एक लाजवाब विचार है। धन्यवाद। – b3bop