(TIL) 9. React-Native:Clean Architecture Application-2-


1.
ボブおじさんのThe Clean Architecture冊のグラフです.
今日、私は一日中コードを見つめて、必ずClean Architectureを適用したいと思っています.
しかし魔法は起こらず、大きな悩みに陥っただけで、甘霖のようなOffice Timeがやってきた.
軽量化もclean architectureの本意であることを忘れてしまったので、私の悩みも深まりました.
次にハーモニーを見てみましょう
2.
Repository
まず、リポジトリの形式です.
import database, {FirebaseDatabaseTypes} from '@react-native-firebase/database';

type EventType = FirebaseDatabaseTypes.EventType;
type DataSnapshot = FirebaseDatabaseTypes.DataSnapshot;

export class UsingFirebaseDB {
  getDataFromDB(
    dir: string,
    eventType: EventType,
    successCallback: (a: DataSnapshot, b?: string | null) => any,
  ) {
    return database().ref(dir).once(eventType).then(successCallback);
  }

  setDataToDB(dir: string, value: any) {
    return database().ref(dir).set(value);
  }

  updateDataInDB(dir: string, value: any) {
    return database().ref(dir).update(value);
  }
}
結果を考慮すると、これらのコードは実際にはベースファイルであるべきです.

  • repositoryはCRUDメソッドの抽象だけが存在するのではなく,実際のアクセスを実現する論理を処理すべきである.

  • 次に、UserCaseにも登場しますが、Repositoryの重量が軽くなるにつれて、UserCaseで扱うロジックも多くなり、本来柔軟な変更が必要な条件とは異なります.

  • 後でデータベース全体を変更する必要がある場合、repositoryを作成するためにデータベースを比較的簡単に処理する方法.
  • など、Office時間質疑応答で入手することをお勧めします.
    次にUSESCASEに移動しましょう
    useCase
    import {Alert} from 'react-native';
    
    import {UsingFirebaseDB} from '../repository/UsingFirebaseDB';
    import {
      GoogleSignin,
      statusCodes,
    } from '@react-native-google-signin/google-signin';
    import auth from '@react-native-firebase/auth';
    
    import {CLIENT_ID} from '../../../env.json';
    export class SignInUseCase extends UsingFirebaseDB {
      async getAccessUserEmailFromDB() {
        try {
          const email = await super.getDataFromDB(
            '/access/email',
            'value',
            snapshot => {
              return [...snapshot.val()];
            },
          );
          return email;
        } catch {
          return null;
        }
      }
    
      async signInGoogleAuth() {
        GoogleSignin.configure({
          webClientId: CLIENT_ID,
        });
    
        try {
          const userInfo = await GoogleSignin.signIn();
          const {idToken, user} = userInfo;
          const googleCredential = auth.GoogleAuthProvider.credential(idToken);
          await auth().signInWithCredential(googleCredential);
          return user;
        } catch (e) {
          if (e.code === statusCodes.SIGN_IN_CANCELLED) {
            console.log('유저가 로그인 취소');
          } else if (e.code === statusCodes.IN_PROGRESS) {
            console.log('로그인 진행 중');
          } else if (e.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
            console.log('플레이 서비스를 사용할 수 없음');
          } else {
            console.log('그외 에러');
          }
          Alert.alert('다시 로그인 해주세요');
          return {};
        }
      }
    }
    USCaseのロジックは、私が作成したgetAccessUserEmailFromDBとSteveが作成したsignInGoogleAuthから構成されています.
    Singletonを深く学習していないため,応用については不明であるが,最適化を考慮して必要な部分に適用する考えである.
    USCaseでは、次の問題が発生しています.

  • リポジトリで使用できるメソッド.

  • 次に、ビジネスロジックが保守的すぎることについて説明します.
  • ここまでQ&Aタイムが頭に浮かぶ
    それではpresenter&viewを見ていきましょう
    Presenter & View
    まず司会者です
    import React, {useEffect, useState} from 'react';
    
    import {SignInUseCase} from '../model/useCase/SignInUseCase';
    import {SignIn} from '../view/SignIn';
    
    interface SignInUser {
      id: string;
      name: string | null;
      email: string;
      photo: string | null;
      familyName: string | null;
      givenName: string | null;
    }
    
    const signInLogic = new SignInUseCase();
    const {getAccessUserEmailFromDB, signInGoogleAuth} = signInLogic;
    
    const handleSocialSignIn = (
      setSignInUserInfo: React.Dispatch<React.SetStateAction<SignInUser | {}>>,
    ) => {
      signInGoogleAuth().then(userInfo => {
        setSignInUserInfo(userInfo);
      });
    };
    
    const loadAccessEmail = (
      setAccessUserEmail: React.Dispatch<React.SetStateAction<string[] | null>>,
    ) => {
      getAccessUserEmailFromDB().then(email => {
        setAccessUserEmail(email);
      });
    };
    
    const signInValidation = (
      signInUserInfo: SignInUser | {},
      accessUserEmail: string[] | null,
    ) => {
      if (signInUserInfo && accessUserEmail?.includes(signInUserInfo.email)) {
        return true;
      } else {
        return false;
      }
    };
    
    export const SignInPresenter = ({navigation}: any) => {
      const {navigate} = navigation;
    
      const [accessUserEmail, setAccessUserEmail] = useState<string[] | null>([]);
      const [signInUserInfo, setSignInUserInfo] = useState<SignInUser | {}>({});
    
      useEffect(() => {
        if (accessUserEmail !== null && accessUserEmail.length === 0) {
          loadAccessEmail(setAccessUserEmail);
        }
        if (signInValidation(signInUserInfo, accessUserEmail)) {
          navigate('Main');
        }
      }, [accessUserEmail, signInUserInfo]);
    
      return (
        <SignIn
          handleSocialSignIn={() => {
            handleSocialSignIn(setSignInUserInfo);
          }}
        />
      );
    };
    
  • プレゼンテーションプログラムは、設計目的ではなく、広範な論理を含む.
  • 一部USESCaseに移行する必要があると思います.
    たとえば、signInValidation、handleSocialSignin、loadAccessEmailなどの関数は、UserCaseで作成する必要があります.
    それ以外にはないようなのでスキップしましょう
    次はviewです.
    import React from 'react';
    import {StyleSheet} from 'react-native';
    import {Image, VStack} from 'native-base';
    import {GoogleSigninButton} from '@react-native-google-signin/google-signin';
    
    interface ISignInProps {
      handleSocialSignIn: () => void;
    }
    
    export const SignIn = ({handleSocialSignIn}: ISignInProps) => {
      const {googleButton} = style;
    
      return (
        <VStack flex={1} bg="white" justifyContent="center" alignItems="center">
          <Image
            source={require('../../data/images/soomgo_logo_rgb.png')}
            alt="Logo"
            w="70%"
            resizeMode="contain"
            marginBottom={75}
          />
          <GoogleSigninButton
            style={googleButton}
            size={GoogleSigninButton.Size.Wide}
            color={GoogleSigninButton.Color.Light}
            onPress={handleSocialSignIn}
          />
        </VStack>
      );
    };
    
    const style = StyleSheet.create({
      googleButton: {
        position: 'absolute',
        bottom: 90,
      },
    });
    
    はい.viewはviewに似ています
    問題ないように見えますが、問題があればNativeBaseとRNコンポーネントを混ぜて使うべき?
    その部分は問題だと思います.
    3.復気
    今日の質問
    Repository
  • リポジトリは、CRUDメソッドの抽象のみが存在するべきではなく、実際のアクセスを実現する論理に関連するべきである.
  • パス、リクエスト、CRUDを混在させた特定の機能を作成するために必要なDBリクエストメソッド.
  • リポジトリの重量が軽いほど、USCaseで処理するロジックが多くなり、本来柔軟に変更すべき条件とは異なり、異なる形式のアプリケーションとなっています.
  • 独立した形で!そっと!DRY-KISSは必須!
  • DBを全体的に置き換える必要がある場合は、リポジトリを作成しましょう.
  • 符号化を減らすことができれば、減少は常に考慮される.
    UseCase
  • Knowledge Baseで使用する方法.
  • 曖昧さから抜け出すための基準を制定しましょう.
  • ビジネスロジックは保守的すぎる.
  • 実は先に保存して、後で割り当てる方法も悪くないように見えます.
    Presenter
  • プレゼンテーションプログラムは、設計目的ではなく、広範な論理を含む.
  • 今誰がCaseを使いますか?
    View
  • ネイティブとRNコンポーネント(スタイルシート)を混合して使用してください.
  • もう少し文書を見れば解決できるだろうな~
    ここまでです.