วิศวกรรมซอฟต์แวร์

ถาม - ตอบสำหรับมืออาชีพนักวิชาการและนักเรียนที่ทำงานในวงจรการพัฒนาระบบ

1
ทำไมทุกคนจะใช้ข้อมูลหลายส่วน / แบบฟอร์มสำหรับข้อมูลที่หลากหลายและการถ่ายโอนไฟล์?
ฉันทำงานใน C # และสื่อสารระหว่าง 2 แอพที่ฉันกำลังเขียน ฉันชอบ Web API และ JSON ตอนนี้ฉันมาถึงจุดที่ฉันกำลังเขียนกิจวัตรประจำวันเพื่อส่งบันทึกระหว่างเซิร์ฟเวอร์ทั้งสองที่มีข้อมูลตัวอักษรและไฟล์อยู่บ้าง ตามอินเทอร์เน็ตฉันควรใช้คำขอ multipart / form-data ตามที่แสดงที่นี่: ดังนั้นคำถาม "Multipart form จาก C # client" โดยทั่วไปคุณเขียนคำขอด้วยตนเองที่ตามรูปแบบดังนี้: Content-type: multipart/form-data, boundary=AaB03x --AaB03x content-disposition: form-data; name="field1" Joe Blow --AaB03x content-disposition: form-data; name="pics"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x-- คัดลอกมาจากRFC 1867 - …

3
ทำไม CSS ไม่อนุญาตให้แสดงความคิดเห็นบรรทัดเดียว [ปิด]
ปิด คำถามนี้เป็นคำถามความคิดเห็นตาม ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้สามารถตอบข้อเท็จจริงและการอ้างอิงได้โดยแก้ไขโพสต์นี้ ปิดให้บริการใน3 ปีที่ผ่านมา ฉันเข้าใจว่า CSS สนับสนุนเฉพาะความคิดเห็นหลายบรรทัดเช่นนี้ /* foobar */ ทำไมไม่มีการสนับสนุนสำหรับความคิดเห็นบรรทัดเดียว // foobar พวกเขาเป็นเรื่องธรรมดาในการเขียนโปรแกรมและดูเหมือนว่ามีประโยชน์อย่างยิ่งสำหรับภาษาเช่น CSS ที่แต่ละกฎอยู่ในสายของตัวเอง หากไม่มีเหตุผลในอดีตโดยเฉพาะสำหรับการตัดสินใจครั้งนี้สิ่งใดที่ทำให้เบราว์เซอร์ไม่สนับสนุนการสนับสนุน
14 css  css3 

2
อาร์กิวเมนต์เอาท์พุทคืออะไรตามที่อ้างถึงใน Clean Code ของ Martin
ในหน้า 45 ของรหัสสะอาดของโรเบิร์ตซี. มาร์ติน: คู่มืองานฝีมือซอฟต์แวร์เปรียวมาร์ตินเขียนว่าควรหลีกเลี่ยงข้อโต้แย้งเกี่ยวกับผลลัพธ์ ฉันมีปัญหาในการเข้าใจความหมายของ "เอาท์พุทอาร์กิวเมนต์" และทำไมพวกเขาควรหลีกเลี่ยง ตัวอย่างเช่นมาร์ตินสำหรับอาร์กิวเมนต์ส่งออกเรียกฟังก์ชันappendFooter(s); public void appendFooter(StringBuffer report)การปรับปรุงรหัสของเขาคือreport.appendFooter(); อาจเป็นเพราะการขาดบริบทของรหัส แต่ฉันไม่เห็นว่าการใช้ข้อโต้แย้งเอาท์พุทจะถือว่าการเข้ารหัสไม่ดี ใครช่วยอธิบายแนวคิดหรือให้ตัวอย่างโค้ดเพิ่มเติมเพื่อให้เข้าใจสิ่งนี้ ฟังก์ชั่นต่อไปนี้จะถือว่าเป็นตัวอย่างของโค้ดที่ไม่สะอาดตามหลักการข้างต้นหรือไม่ int[] numberArray = {3, 5, 7, 1}; sortArray(numberArray); ถ้าข้างต้นเป็นการละเมิดหลักการของ Martin ที่ไม่ได้ใช้อาร์กิวเมนต์เอาท์พุทจะดีกว่าไหมถ้ามีวัตถุที่มีอาร์เรย์เป็นเขตข้อมูลและฟังก์ชันที่สามารถเรียกให้เรียงลำดับอาร์เรย์ได้ ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1); numberArray.sort();
14 java  clean-code 

2
กำลังสร้างรายการใหม่เพื่อปรับเปลี่ยนคอลเลกชันในแต่ละลูปสำหรับข้อบกพร่องในการออกแบบหรือไม่
เมื่อเร็ว ๆ นี้ฉันได้พบกับการดำเนินการที่ไม่ถูกต้องทั่วไปCollection was modifiedใน C # และในขณะที่ฉันเข้าใจอย่างเต็มที่ดูเหมือนว่าจะเป็นปัญหาที่พบบ่อย (google ผลลัพธ์ประมาณ 300k!) แต่มันก็ดูเหมือนจะเป็นตรรกะและตรงไปตรงมาในการปรับเปลี่ยนรายการในขณะที่คุณทำมัน List<Book> myBooks = new List<Book>(); public void RemoveAllBooks(){ foreach(Book book in myBooks){ RemoveBook(book); } } RemoveBook(Book book){ if(myBooks.Contains(book)){ myBooks.Remove(book); if(OnBookEvent != null) OnBookEvent(this, new EventArgs("Removed")); } } บางคนจะสร้างรายการใหม่เพื่อทำซ้ำ แต่นี่เป็นเพียงการหลีกเลี่ยงปัญหา ทางออกที่แท้จริงคืออะไรหรือปัญหาการออกแบบจริงที่นี่คืออะไร เราทุกคนต้องการทำสิ่งนี้ แต่มันบ่งบอกถึงข้อบกพร่องในการออกแบบหรือไม่?
14 c# 

1
ความแตกต่างระหว่างองค์ประกอบของเว็บและองค์ประกอบที่กำหนดเองคืออะไร?
"ส่วนประกอบของเว็บ" และ "องค์ประกอบที่กำหนดเอง" มักจะสับสนและการค้นหาเว็บสำหรับชื่อของคำถามนี้ยังไม่ได้สร้างความชัดเจนมากนัก มาแก้ไขกันเถอะ

3
การออกแบบที่ดีสำหรับการอนุญาตให้ใช้งานร่วมกันได้ของไฟล์ย้อนหลังระหว่างซอฟต์แวร์รุ่นต่างๆคืออะไร
การออกแบบที่ดีสำหรับการอนุญาตให้ใช้งานร่วมกันได้ของชนิดไฟล์ระหว่างซอฟต์แวร์รุ่นต่าง ๆ คืออะไร ตัวอย่างเช่น Microsoft จะรับ Word 2007, 2010 และ 2013 และอื่น ๆ ... ไปยังไฟล์ docx ที่เปิดอยู่ทั้งหมดได้อย่างไร แต่รุ่นที่แตกต่างกันสามารถบันทึกข้อมูลได้มากขึ้นและน้อยลงและบันทึกข้อมูลในรูปแบบที่แตกต่างกันเล็กน้อย ไฟล์ที่บันทึกในรุ่นหนึ่งสามารถเปิดได้ในอีกรุ่นหนึ่ง แต่องค์ประกอบบางอย่างของไฟล์อาจไม่สามารถใช้งานได้ในเวอร์ชั่นที่เก่ากว่า ฉันหมายความว่าวิธีที่ชัดเจนจริงๆที่จะมีบางอย่าง private string openfile(string filename) { File.Open(filename) ... some logic that gets a header from the file that will never change switch (fileversion) case 2007: ..... case 2010 ..... case …

3
การเขียนโปรแกรมใช้งานและการผจญภัยข้อความ
นี่เป็นคำถามเชิงทฤษฎีส่วนใหญ่เกี่ยวกับ FP แต่ฉันจะผจญภัยข้อความ (เช่น Zork โรงเรียนเก่า) เพื่อแสดงจุดของฉัน ฉันต้องการทราบความคิดเห็นของคุณเกี่ยวกับวิธีจำลองสถานการณ์จำลองด้วย FP การผจญภัยข้อความดูเหมือนจะเรียก OOP ตัวอย่างเช่น "ห้อง" ทั้งหมดเป็นอินสแตนซ์ของRoomคลาสคุณสามารถมีItemคลาสพื้นฐานและอินเทอร์เฟซที่เหมือนกับItem<Pickable>สิ่งที่คุณสามารถพกพาไปเรื่อย ๆ การสร้างแบบจำลองโลกใน FP ทำงานแตกต่างกันโดยเฉพาะอย่างยิ่งถ้าคุณต้องการบังคับให้เปลี่ยนแปลงในโลกที่ต้องกลายพันธุ์ในขณะที่เกมดำเนินไป (วัตถุถูกย้ายศัตรูพ่ายแพ้การให้คะแนนเพิ่มขึ้น ฉันนึกภาพวัตถุชิ้นใหญ่ชิ้นเดียวWorldที่มีทุกอย่าง: มีห้องอะไรบ้างที่คุณสามารถสำรวจได้ว่ามันเชื่อมโยงกันอย่างไรสิ่งที่ผู้เล่นกำลังแบกคันโยกที่ถูกกระตุ้น ฉันคิดว่าวิธีการที่บริสุทธิ์จะส่งวัตถุขนาดใหญ่นี้ไปยังฟังก์ชันใด ๆ และให้พวกเขาส่งคืน (อาจแก้ไข) ตัวอย่างเช่นฉันมีmoveToRoomฟังก์ชั่นที่รับWorldและส่งคืนพร้อมWorld.player.locationเปลี่ยนเป็นห้องใหม่World.rooms[new_room].visited = Trueและอื่น ๆ แม้ว่านี่จะเป็นวิธีที่ "ถูกต้อง" มากกว่า แต่ก็ดูเหมือนว่าจะมีการบังคับใช้ความบริสุทธิ์เพื่อประโยชน์ของมัน ขึ้นอยู่กับภาษาการเขียนโปรแกรมการส่งผ่านWorldวัตถุที่มีขนาดใหญ่มากไปมาอาจมีราคาแพง นอกจากนี้ทุกฟังก์ชั่นอาจต้องมีการเข้าถึงWorldวัตถุใด ๆ ตัวอย่างเช่นห้องอาจเข้าถึงได้หรือไม่ขึ้นอยู่กับคันโยกที่ถูกเรียกในห้องอื่นเพราะอาจถูกน้ำท่วม แต่หากผู้เล่นมีเสื้อชูชีพก็สามารถเข้าได้ สัตว์ประหลาดอาจก้าวร้าวหรือไม่ขึ้นอยู่กับว่าผู้เล่นสังหารญาติของเขาในห้องอื่น ซึ่งหมายความว่าroomCanBeEnteredฟังก์ชั่นความต้องการที่จะเข้าถึงWorld.player.invetoryและWorld.rooms, describeMonsterความต้องการในการเข้าถึงWorld.monstersและอื่น ๆ (โดยทั่วไปคุณต้องผ่านภาระทั้งหมดไปรอบ ๆ ) นี่ดูเหมือนว่าฉันจะเรียกตัวแปรทั่วโลกถึงแม้ว่านี่จะเป็นรูปแบบการเขียนโปรแกรมที่ดีโดยเฉพาะใน FP คุณจะแก้ปัญหานี้อย่างไร

9
เหตุใดจึงไม่มีการแปลงโดยนัย
ดังที่ฉันเข้าใจแล้วการแปลงโดยนัยอาจทำให้เกิดข้อผิดพลาด แต่นั่นไม่สมเหตุสมผล - การแปลงปกติไม่ควรทำให้เกิดข้อผิดพลาดเช่นกัน? ทำไมไม่มี len(100) ทำงานโดยการแปลภาษา (หรือรวบรวม) มันเป็น len(str(100)) โดยเฉพาะอย่างยิ่งเนื่องจากเป็นวิธีเดียว (ฉันรู้) สำหรับการทำงาน ภาษารู้ว่าข้อผิดพลาดคืออะไรทำไมไม่แก้ไขมัน? สำหรับตัวอย่างนี้ฉันใช้ Python แต่ฉันรู้สึกว่าบางสิ่งเล็ก ๆ นี้มันเป็นสากล

3
วิธีที่ดีที่สุดในการจัดโครงสร้างและชื่อไฟล์ที่มีคลาสทั่วไปที่มีชื่อเดียวกันคืออะไร?
ในโครงการปัจจุบันของฉันฉันได้พบกับความต้องการในการสร้างชั้นเรียนทั่วไปที่มีชื่อเดียวกัน แต่จำนวนพารามิเตอร์ทั่วไปที่แตกต่างกัน ตัวอย่างเช่น: MyClass<T1> MyClass<T1, T2> MyClass<T1, T2, T3> เนื่องจากฉันต้องการสิ่งเหล่านี้ทั้งหมดในเนมสเปซเดียวกันฉันสับสนว่าจะจัดโครงสร้างและตั้งชื่อคลาสและไฟล์ของฉันได้อย่างไร หากเราปฏิบัติตามแนวคิดที่ว่าเราควรมีคลาสที่ จำกัด เพียงหนึ่งไฟล์ต่อไฟล์และไฟล์นั้นควรอยู่ในโครงสร้างโฟลเดอร์ที่แสดงถึงลำดับชั้นของเนมสเปซและชื่อของไฟล์ควรตรงกับชื่อของคลาสฉันจะจัดการกับสถานการณ์นี้อย่างไร ? สิ่งที่ฉันถามจริงๆนี่คือสิ่งที่ฉันควรตั้งชื่อไฟล์ที่มีMyClass<T1>และสิ่งที่ฉันควรตั้งชื่อไฟล์ที่มีMyClass<T1, T2>? ฉันไม่ได้ถามว่าชื่อของพารามิเตอร์ประเภทควรเป็นอะไร
14 c#  .net 

3
เราควรเพิ่มนวกรรมิกไว้ใน structs หรือไม่?
เรามักจะใช้ c ++ structs เพื่อกำหนดโครงสร้างข้อมูลเมื่อเทียบกับคลาสซึ่งสามารถเป็นโมดูลที่สมบูรณ์พร้อมเมธอดสมาชิก ตอนนี้ลึกลงไปเรารู้ว่าพวกเขาทั้งสองเหมือนกัน (พูดอย่างหลวม ๆ ) ความจริงที่ว่าเรามักจะใช้ / รักษา structs เป็นข้อมูลหน่วยงานเท่านั้นสร้างความอยากนี้ที่เราไม่ได้เพิ่มตัวสร้างเริ่มต้นเช่นกัน แต่คอนสตรัคเตอร์นั้นยอดเยี่ยมอยู่เสมอพวกเขาทำให้สิ่งต่าง ๆ ง่ายขึ้นและช่วยกำจัดข้อผิดพลาด มันจะขมวดคิ้วถ้าเพิ่มตัวสร้างเริ่มต้นให้กับโครงสร้างข้อมูลของฉัน? การใช้Constructor ที่เป็นค่าเริ่มต้นยังทำให้โครงสร้าง Non-POD (ชนิดข้อมูลเก่าแบบเดิม) จัดทำตามเกณฑ์อื่น ๆ เพื่อให้สิ่งต่าง ๆ ในมุมมองพิจารณาตัวอย่างง่าย ๆ แต่ในความเป็นจริง struct จะใหญ่กว่ามาก struct method { char name[32]; float temperature; int duration; }; ทุกครั้งที่ฉันสร้างวิธีการฉันต้องกังวลเกี่ยวกับ (พูดน้อยที่สุด) ถ้าฉันลืมตั้งค่าบางอย่าง ลองนึกภาพฉันลืมที่จะตั้งค่าtemperatureและใช้วิธีการกับระบบซึ่งตอนนี้เป็นค่าสูงแบบสุ่มและทำให้เกิดการทำร้ายร่างกาย หรือฉันลืมที่จะตั้งค่าdurationและตอนนี้วิธีการใช้ตัวเองสำหรับช่วงเวลาสูงที่ไม่รู้จัก ทำไมฉันต้องรับผิดชอบในการเริ่มต้นวัตถุทุกครั้งแทนที่จะใช้ตัวสร้างซึ่งรับประกันได้หรือไม่

3
การจัดกลุ่มที่เก็บ Git หลายแห่งซึ่งเป็นส่วนหนึ่งของโครงการโดยรวมเดียวกัน
สมมติว่าฉันมีโครงการที่มีส่วนประกอบหลายส่วน: ส่วนประกอบเซิร์ฟเวอร์, องค์ประกอบของเว็บแอป, ส่วนประกอบ iOS, ส่วนประกอบ Android, ฯลฯ ส่วนประกอบเหล่านี้เป็นรหัสฐานที่แยกจากกันทั้งหมด แต่ยังรวมกันอย่างหลวม ๆ รหัสอาจต้องการการเปลี่ยนแปลงส่วนประกอบอื่น ๆ ทั้งหมดด้วย) วิธีที่มีประสิทธิภาพที่สุดใน Git ในการจัดระเบียบโครงการนี้คืออะไร? หากคุณใส่ทั้งหมดไว้ในที่เก็บหนึ่งคุณจะมีเวอร์ชันล่าสุดเสมอ แต่สิ่งต่าง ๆ จะค่อนข้างยุ่งเหยิงเมื่อคุณเริ่มเปลี่ยนองค์ประกอบหนึ่งและไม่ใช่องค์ประกอบอื่น ๆ ในทางกลับกันถ้าคุณทำให้แต่ละองค์ประกอบเป็นที่เก็บแยกต่างหากคุณจะสามารถ "ลิงก์" ที่เก็บเหล่านี้ได้อย่างไรเพื่อที่คุณจะได้รู้ว่าเวอร์ชัน 2.0 ของแอปนั้นต้องการเวอร์ชั่น 1.5 ของส่วนประกอบเซิร์ฟเวอร์ ฯลฯ มีคุณสมบัติในการคอมไพล์นอกการรักษาที่ทันสมัย ​​readmes (หรือทางออกที่ดีกว่าฉันไม่เห็น) เพื่อจัดการ repos ที่เกี่ยวข้องหลายรายการได้อย่างมีประสิทธิภาพมากขึ้น?
14 git 

2
คำศัพท์ที่ถูกต้องในทฤษฎีประเภท: ประเภทประเภทก่อสร้างประเภท / ประเภทและค่า
ในคำตอบของคำถามก่อนหน้านี้การอภิปรายขนาดเล็กเริ่มต้นขึ้นเกี่ยวกับคำศัพท์ที่ถูกต้องสำหรับโครงสร้างบางอย่าง ขณะที่ฉันไม่พบคำถาม (นอกเหนือจากนี้หรือว่าซึ่งไม่ใช่สิ่งที่ถูกต้อง) ที่จะตอบคำถามนี้อย่างชัดเจนฉันกำลังสร้างคำถามใหม่ ข้อตกลงที่น่าสงสัยและความสัมพันธ์ของพวกเขาคือชนิดประเภทคอนสตรัคชนิดพารามิเตอร์ชนิดหรือประเภทและค่านิยม ฉันได้ตรวจสอบวิกิพีเดียเพื่อศึกษาทฤษฎีการพิมพ์ด้วย แต่ก็ไม่ได้อธิบายอย่างชัดเจนเช่นกัน ดังนั้นเพื่อให้มีคำตอบอ้างอิงที่ดีและตรวจสอบความเข้าใจของฉัน: สิ่งเหล่านี้ถูกกำหนดไว้อย่างเหมาะสมอย่างไร? ความแตกต่างระหว่างสิ่งเหล่านี้คืออะไร? พวกเขาเกี่ยวข้องกันอย่างไร

5
การจัดการข้อยกเว้นในโปรแกรมที่ต้องการเรียกใช้ 24/7
ฉันได้อ่านแล้วว่าเราควรจะจับข้อยกเว้นที่สามารถจัดการได้ซึ่งทำให้การจับคลาสยกเว้นฐาน (C # ในกรณีนี้) เป็นความคิดที่ไม่ดี (ด้วยเหตุผลอื่น) ปัจจุบันฉันเป็นส่วนหนึ่งของโครงการที่ฉันยังไม่เห็นอะไรเลยนอกจากข้อยกเว้นพื้นฐานที่ถูกจับได้ ฉันบอกว่ามันถือว่าเป็นการปฏิบัติที่ไม่ดี แต่การตอบสนองคือ "บริการนี้ต้องทำงานตลอด 24/7 ดังนั้นนี่คือวิธีที่มันเป็น" เนื่องจากฉันไม่ได้รับการตอบรับที่ดีสำหรับวิธีการจัดการข้อยกเว้นในโปรแกรมที่ต้องการเรียกใช้ 24/7 อย่างถูกต้องฉันจึงมาที่นี่ ฉันไม่ได้หาข้อมูล / คำแนะนำเกี่ยวกับวิธีจัดการกับการจัดการข้อยกเว้นในโปรแกรม / บริการ "วิกฤติ" ที่ต้องทำงานตลอดเวลา (และในกรณีนี้ฉันเชื่อว่ามันอาจใช้ได้ถ้าบริการหยุดทำงานเป็นเวลาหนึ่งนาที หรือสองจึงไม่สำคัญ) ฉันเข้าใจว่ามันขึ้นอยู่กับลักษณะที่แน่นอนของโปรแกรม ข้อกำหนดสำหรับโปรแกรมที่อาจทำให้เกิดปัญหาการคุกคามต่อชีวิตแตกต่างกันมากเมื่อเทียบกับเครื่องสแกนบันทึกสำหรับเกมออนไลน์ สองตัวอย่าง: 1: บริการพิมพ์ล่วงหน้าสำหรับลูกค้าของรถไฟ Brittish ใช้เมื่อค้นหาออนไลน์สำหรับสถานีรถไฟ 2: โปรแกรมที่ควบคุมสวิตช์รถไฟสำหรับรถไฟเหนือโดยอัตโนมัติตามข้อมูลเรียลไทม์ที่ได้รับจากเซ็นเซอร์ต่าง ๆ ในแทร็ครถไฟ ฯลฯ โปรแกรมแรกอาจไม่ทำให้เกิดปัญหาใหญ่หากลงไปหนึ่งหรือสองนาทีขณะที่หลังอาจทำให้เกิดการบาดเจ็บล้มตายของมนุษย์ ข้อเสนอแนะเกี่ยวกับวิธีการจัดการกับแต่ละคน? ชี้ไปที่ที่ฉันสามารถหาข้อมูลและความคิดเพิ่มเติมเกี่ยวกับปัญหานี้ได้หรือไม่

6
อะไรคือวิธีที่ดีที่สุดในการขยายและแยกทีมเปรียวที่สร้างแอปพลิเคชันบนเว็บ
เมื่อเร็ว ๆ นี้ฉันได้เข้าร่วม บริษัท ที่ฉันทำงานเป็นอาจารย์การต่อสู้ในโครงการพัฒนาแบบว่องไวที่สร้างแอปพลิเคชันเว็บ ทีมกำลังจะมีขนาดสูงสุดสำหรับทีมเปรียว (คาดว่า 9 สัปดาห์หน้า) เราได้พูดคุยเกี่ยวกับการแยกทีมออกเป็นสองทีมไม่มากนักที่จะทำให้สั้นลง (ซึ่งไม่มากเกินไปในขณะนี้) แต่เพื่อหยุดยั้งผู้คนจากการเบื่อในการวางแผนการวิ่งอย่างรวดเร็ว มีสองเลเยอร์ที่แตกต่างกันมากสำหรับโครงการ - แบ็กเอนด์ด้านเทคนิคขั้นสูง (เช่นซับซ้อนอย่างยิ่ง) และการออกแบบ / สร้าง / การรวม UI ดูเหมือนว่าเมื่อพวกแบ็กเอนด์กำลังพูดถึงด้านเทคนิค UI ของพวกเขาจะถูกแบ่งออกและในทางกลับกัน ดูเหมือนว่าจะมีเหตุผลในการแบ่งทีมถ้าจะมีเวลามากขึ้นอย่างมีประสิทธิภาพ แต่ฉันมีการจองครั้งใหญ่ครั้งหนึ่งในทุกสิ่งที่ฉันอาจจะทำจริงๆคือลดการทำงานร่วมกันและการแบ่งปันความรู้ ทั้งสองทีมไม่มีความคิดที่ดีเกี่ยวกับสิ่งที่เหลือของทีมกำลังสร้าง ใครบ้างมีประสบการณ์ในการจัดการกับสิ่งนี้?


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.