JavaRush /Java блогы /Random-KK /Көптілді қолданбаны жүзеге асыру
Константин
Деңгей

Көптілді қолданбаны жүзеге асыру

Топта жарияланған
Көптілді қолданбаны жүзеге асыру – 1

Бүгін біз көптілділік туралы айтатын боламыз. Сонда бұл не?

Көптілділік, басқаша айтқанда, интернационалдандыру - бұл бағдарлама логикасын өзгертпестен бірнеше тілге бейімделетін қосымшаны әзірлеудің бір бөлігі. Жағдайды қарастырыңыз: сіз, мысалы, орыс, ағылшын және испан тілдерінде сөйлейтін көптеген елдердің тұрғындары үшін ірі сауда компаниясы үшін веб-қосымшаны жасайсыз. Сіз оны барлық пайдаланушылар үшін ыңғайлы етуіңіз керек. Идея мынада: орыстілді оқырман сіздің деректеріңізді орыс тілінде көре алуы керек, американдық материалды ағылшын тілінде, ал испан тілінде - испан тілінде (күтпеген жерден, солай емес пе?) Енді Көптілді қолданбаны жүзеге асыру – 2бірнеше интернационалдандыру үлгілерін қарастырайық. , және олардың біреуі үшін (бұл маған ең ұнайды :) Java тіліндегі іске асыруды қарастырайық. Гвинея шошқасы ретінде бүгін бізде фильмнің деректер тақтасы болады. Тым бұрмаланбайық, сондықтан бізде көп сөйлеушілер болмайды. Мысалы, бұл жақсы. Ал біз фильмдердің атын аударамыз (режиссерлер – қосымшалар үшін): Көптілді қолданбаны жүзеге асыру – 3

1. Әр тілге аудармасы бар кесте

Бұл модельдің мәні: әр тілде мәліметтер базасында аударманы қажет ететін барлық ұяшықтарды қамтитын жеке кесте бар. Бұл әдістің кемшілігі - біз жаңа тіл қосқан сайын жаңа кестені қосуымыз керек. Яғни, біздің тұтынушымыз өте жақсы жұмыс істеп жатыр деп елестетіп көрейік және ол әлемнің көптеген елдерінде (шын мәнінде, тілдерде) өз қолданбасын кеңейтіп жатыр. Бұл әр тілге бір таблетка қосу керек дегенді білдіреді. Нәтижесінде бізде жарты немесе толығымен дерлік көмекші аударма кестелерінен тұратын дерекқор болады: Көптілді қолданбаны жүзеге асыру – 4 Фильмдердің схемасы: Көптілді қолданбаны жүзеге асыру – 5Аударма кестелері:
  • орыс Көптілді қолданбаны жүзеге асыру – 6
  • испан Көптілді қолданбаны жүзеге асыру – 7
  • Ағылшын Көптілді қолданбаны жүзеге асыру – 8

2. Барлығы үшін бір

Белгілі бір үлгіге жататын әрбір кестеде тіл тақтасының идентификаторы бар өріс қосылады. Сәйкесінше, дерекқорда аудармалары бар осы кесте де бар. Мәселе мынада, бір an object бірнеше аудармаларға (тілдерге) сәйкес келуі мүмкін. Нәтижесінде нысандардың қайталануы орын алады және бұл логиканы қатты шатастырады және қиындатады, бұл жақсы емес. Біз UML-ге қараймыз: Көптілді қолданбаны жүзеге асыру – 9 Кестелік фильмдер: Көптілді қолданбаны жүзеге асыру – 10 Кесте тілдері: Көптілді қолданбаны жүзеге асыру – 11

3. Тілге арналған баған

Кестедегі әрбір тіл үшін әрбір баған үшін жеке аударма бағаны жасалады. Бұл тәсілдің кемшілігі, егер тағы да көп тілдер қосылса, дерекқор құрылымын әр уақытта өзгерту қажет болады және бұл нашар тәсіл болып саналады. Сондай-ақ интернационалдандыруды талап ететін белгілердің қаншалықты жоғары болатынын елестетіп көріңіз. Қолдау көрсетілетін тілдердің саны алдын ала белгілі, олардың саны тым көп емес және әрбір модель барлық тіл нұсқаларында болуы керек модельді қарастырған жөн. UML: Көптілді қолданбаны жүзеге асыру – 12Барлығы қосылған кесте: Көптілді қолданбаны жүзеге асыру – 13

4. Сыртқы аударма

Бұл опция сыртқы құралдарды қосу арқылы жүзеге асырылады (Google translate, Bing translate және т.б.). Ол мүмкіндігінше көп келушілерге ақпарат беру қажет болған жағдайда қолданылады және бұл ақпарат өте көп. Өте көп. Бұл жағдайда сіз барлық тілдердегі мәліметтер базасында ақпаратты тікелей сақтамай, оны динамикалық түрде аударуды шеше аласыз. Бірақ машиналық аударманың сапасы көп нәрсені қалаусыз қалдыратынын есте ұстаған жөн. Опцияны өте үнемді деп санауға болады (әрбір басылымды аудару үшін ресурстар болмаған кезде). Дұрыс аудармаға қатысты жиі кездесетін мәселе – тілді жетік білмейтін аудармашылар сөздің қате мағынасын таңдап алып, пайдаланушыны шатастырып, түймеде жазылғанның мағынасын өз бетінше анықтауға мәжбүр етеді. Сондай-ақ сөйлемді дұрыс аударып қана қоймай, оның мағынасын белгілі бір тілге, ұлтқа жеткізу маңызды. Әзірлеушілер кейбір тілдерде жынысқа қатысты көптеген мәселелерге тап болады. Олар codeтағы сөз тіркесін қолданушының жынысына байланысты қайталауы керек, сонымен қатар тек зат есімдер ғана емес, сонымен қатар сын есімдер мен етістіктердің де әр түрлі септелетінін ескеруі керек. Қолданбада ағылшын тілінен басқа тілді таңдаған кезде таңдалған тілдің сөздерімен бірге әлі де аударылмаған элементтер болатын жағдайлар бар. Бірнеше тіл көрсетіліп, бәрі араласып, қолданушы қолданбаны түсінбейтін Вавилонның бір түрі болып шықса, одан да жаман. Мысалы: https://cloud.google.com/translate/

5. Қолданба деңгейінің қолдау файлдары

Аудармаларды сақтау үшін бөлек файлдар жасалады. Бұл бір тілге бір файл немесе бір планшетке бір тілге бір файл болуы мүмкін (ұсақ ұсату). Бұл опция осы файлдарда көптеген мәтіндерді сақтауға болатындықтан жиі пайдаланылады, яғни кестелер мен дерекқордың өзі толып кетпейді. Тағы бір ыңғайлылық - бұл өрістер үшін дерекқорды соғудың қажеті жоқ және codeтағы файлдар сұралған тілге байланысты динамикалық түрде ауыстырылуы мүмкін. Нәтижесінде файл біз үшін сөздік қызметін атқарады, ондағы кілт – тіл, мән – мәтін. Бірақ біз төмендегі ".properties" пішімімен шектелмейміз және бұл файл пішімдері әртүрлі болуы мүмкін - JSON, XML және т.б. Кемшіліктері - бұл жағдайда деректер қорын қалыпқа келтіру айтарлықтай азаяды. Сондай-ақ, деректер тұтастығы енді тек дерекқорға ғана емес, сонымен қатар сериялау механизміне де байланысты. Осы тақырып бойынша тамаша мақала Аудармасы бар сөздік файлдарының мысалы: Көптілді қолданбаны жүзеге асыру – 14
  • Ағылшын Көптілді қолданбаны жүзеге асыру – 15
  • орыс Көптілді қолданбаны жүзеге асыру – 16
  • испан Көптілді қолданбаны жүзеге асыру – 17

6. Әр кестеге арналған көмекші аударма кестесі

Менің ойымша, ең икемді шешім. Бұл тәсілдің мәні тілдер үшін жеке кесте құру болып табылады. Қарастырылып отырған кесте үшін аудармалар мүмкіндігін іске асыру қажет болғанда, тіл кестесімен сілтеме жасалады, ал сілтеме кестесінде тіл идентификаторы, элемент идентификаторы және аудармалары бар бағандар болады. Бұл айтылғандай қорқынышты емес. Бұл тәсіл қолдау көрсетілетін тілдердің жеткілікті икемді кеңейтілуіне мүмкіндік береді. Толығырақ қарастырайық. UML: Көптілді қолдануды жүзеге асыру – 18Фильмдер кестесі: Көптілді қолдануды жүзеге асыру – 19Тілдер кестесі: Көптілді қолдануды жүзеге асыру – 20Аудармалар кестесі: Көптілді қолданбаны жүзеге асыру – 21 Ал, мен жоғарыда айтқанымдай, Java codeындағы опциялардың бірінің орындалуын қарастырайық (сіз түсінгеніңіздей, бұл соңғы нұсқа болады). Қолданбаның өзінде мұндай ештеңе жоқ: біз контроллерлерден дао қабаттарына өтеміз. Біз жасау әдісін қарастырамыз - мысал үшін бұл жеткілікті. Ендеше кеттік)) Біздің болмысымыз фильм:
@Builder
@Getter
public class Movie {

   private Long id;

   private String producer;
}
Қызықты ештеңе жоқ, тек бірінші кестенің үлгісін енгізу. dto (Деректерді тасымалдау нысаны) түрлендіргіштері бар контроллер:
@RestController
@RequiredArgsConstructor
@RequestMapping(path = "/cities")
public class MovieController {

   private final MovieService movieService;

   @PostMapping
   public ResponseEntity<moviedto> create(MovieDTO movieDTO) {
       return new ResponseEntity<>(toDTO(movieService.create(fromDTO(movieDTO), movieDTO.getNameTranslations()), movieDTO.getNameTranslations()), HttpStatus.CREATED);
   }

   private Movie fromDTO(MovieDTO dto) {
       return Movie.builder()
               .id(dto.getId())
               .producer(dto.getProducer())
               .build();
   }

   private MovieDTO toDTO(Movie movie, Map<string, string=""> nameTranslation) {
       return MovieDTO.builder()
               .id(movie.getId())
               .producer(movie.getProducer())
               .nameTranslations(nameTranslation)
               .build();
   }
}
DTO-да біз аудармаларды карта ретінде береміз, кілт - тілдің аббревиатурасы, мән - аударма мәні (фильмнің аты). DTO:
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class MovieDTO {

   @JsonProperty("id")
   private Long id;

   @JsonProperty("name")
   private String producer;

   @JsonProperty("nameTranslations")
   private Map<String, String> nameTranslations;//example = "{'en': 'The Matrix', 'ru' : 'Матрица'}"
}
Мұнда біз жоғарыда жазылғандай dto класының өзін көреміз, аудармалар картасы, қалған өрістер Фильм үлгісінің дисплейі болып табылады.Кино қызметіне көшейік:
public interface MovieService {

   Movie create(Movie movie, Map nameList);
}
Оны жүзеге асыру:
@Service
@RequiredArgsConstructor
public class MovieServiceImpl implements MovieService {

   private final MovieDAO movieDAO;
   private LanguageService languageService;

   @Override
   public Movie create(Movie movie, Map<string, string=""> nameList) {
       movieDAO.create(movie);
       Map<Long, String> map = new HashMap<>();
       nameList.forEach((x, y) -> map.put(languageService.getIdByLangCode(x), y));
       movieDAO.createTranslator(movie.getId(), map);
       return movie;
   }
}
Мұнда аббревиатура бойынша тіл идентификаторын алу үшін салыстырмалы түрде үшінші тараптың LanguageService қызметін пайдалануды көреміз. Және осы идентификатор арқылы біз аудармаларымызды (сонымен қатар карта түрінде) қосылым кестесіне сақтаймыз. DAO-ны қарастырайық:
public interface MovieDAO {

   void create(Movie movie);

   void createTranslator(Long movieId, Map<Long,String> nameTranslations);
}
Іске асыру:
@RequiredArgsConstructor
@Repository
public class MovieDAOImpl implements MovieDAO {
   private final JdbcTemplate jdbcTemplate;

   private static final String CREATE_MOVIE = "INSERT INTO movies(id, producer) VALUES(?, ?)";

   private static final String CREATE_TRANSLATOR = "INSERT INTO movies_translator(movies_id, language_id, name) VALUES(?, ?, ?)";

   @Override
   public void create(Movie movie) {
       jdbcTemplate.update(CREATE_MOVIE, movie.getId(), movie.getProducer());
   }

   @Override
   public void createTranslator(Long movieId, Map<Long, String> nameTranslations) {
       nameTranslations.forEach((x, y) -> jdbcTemplate.update(CREATE_TRANSLATOR, movieId, x, y));
   }
}
Мұнда біз оның мәні мен тілдерінің сақталуын көреміз (сөздік). Иә, мұнда Spring JDBC қолданылады: мен оны жаңадан бастағандар үшін жақсы деп санаймын, өйткені ол ашық. «Үшінші тарап» қызметіне көшейік. Тіл қызметі:
public interface LanguageService {

   Long getIdByLangCode(String lang);
}
Іске асыру:
@Service
@RequiredArgsConstructor
public class LanguageServiceImpl implements LanguageService {
   private final LanguageDAO languageDAO;

   @Override
   public Long getIdByLangCode(String lang) {
       return languageDAO.getIdByLangCode(lang);
   }
}
Ерекше ештеңе жоқ, қысқартылған атау бойынша іздеңіз. ДАО:
public interface LanguageDAO {

   Long getIdByLangCode(String lang);
}
Іске асыру:
@RequiredArgsConstructor
@Repository
public class LanguageDAOImpl implements LanguageDAO {
   private final JdbcTemplate jdbcTemplate;

   private static final String FIND_ID_BY_LANG_CODE = "SELECT id FROM languages WHERE lang_code = ?";

   @Override
   public Long getIdByLangCode(String lang) {
       return jdbcTemplate.queryForObject(FIND_ID_BY_LANG_CODE, Long.class, lang);
   }
}
Құрылымы: Көптілді қолданбаны жүзеге асыру – 23 Жоғарыда сипатталған барлық модельдер өмір сүруге құқылы. Жағдайға байланысты қайсысын қолдану керектігін шешу керек. Әрине, бұл бәрі емес: көптеген басқа тәсілдер бар, соның ішінде әртүрлі тілдер үшін әртүрлі дерекқорларды пайдалану, кэштерді, әртүрлі фреймворктарды және т.б. Бүгін мен үшін барлығы осы және... Көптілді қолданбаны жүзеге асыру – 24
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION