paint-brush
ソフトウェア開発におけるテンプレート化: より深く考える@pro1code1hack
377 測定値
377 測定値

ソフトウェア開発におけるテンプレート化: より深く考える

Yehor Dremliuha8m2024/07/16
Read on Terminal Reader

長すぎる; 読むには

多くのコア機能は、さまざまなプロジェクトで再利用されています。これらの機能には、ユーザー認証、支払い処理、ユーザー管理などが含まれます。この記事では、これらすべてのパターンが過去のプログラマーによってすでに作成されていたという点を指摘したいと思います。現在使用しているほとんどすべてのものは、すでに実装されています。特定のプロジェクトに基づいて一部の機能を変更するだけです。
featured image - ソフトウェア開発におけるテンプレート化: より深く考える
Yehor Dremliuha HackerNoon profile picture
0-item
1-item

1. はじめに

プログラミングの旅を始めて以来、私は興味深いパターンに気づきました。それは、ほとんどのアプリケーションがテンプレート化されているということです。はい、これは純粋な事実です。この記事の冒頭で立ち止まって、これまでに開発したすべてのプロジェクトについて考えてみましょう。


これらに共通するものは何でしょうか?よく見ると、多くのコア機能がさまざまなプロジェクト間で再利用されていることがわかります。これらのコア機能には、多くの場合、ユーザー認証、支払い処理、ユーザー管理などが含まれます。


この記事では、これらのパターンはすべて過去のプログラマーによってすでに作成されていたという点を指摘したいと思います。実際、現在使用しているものはほとんどすべて、すでに実装されていました。特定のプロジェクトに基づいて一部の機能を変更するだけです。


ここでは、Python でのバックエンド開発の観点から例を紹介しますが、これはどのプログラミング言語にも、またソフトウェア エンジニアリングの領域内のどの分野にも適用できます。


では、すべてのバックエンド アプリケーションに共通するものは何でしょうか? 見てみましょう。


: OOP (オブジェクト指向プログラミング) に精通している場合は、テンプレート化されたモジュールをアプリケーション レベルでの最高レベルの抽象化と見なし、この原則に従って記述する必要があります。

2. 認証と承認

各セクションを、ほぼすべてのバックエンド アプリケーションに適用できる基本コンポーネントに分解したいと思います。


基本コンポーネント

  1. ユーザー モデル:ユーザー名、パスワード、電子メール、ロールなどの属性を含むユーザーの表現。
  2. パスワード管理:パスワードをハッシュして検証する機能。
  3. トークン生成:トークン (JWT、OAuth2 など) を生成および検証するメカニズム。
  4. ミドルウェア/デコレータ:認証を必要とするルート/エンドポイントを保護します。
  5. ロール管理:ユーザー ロールと権限を割り当て、検証します。


2.1 ユーザーモデル

特定のユーザーに適用できる属性を持つ、最も一般的なUserクラスを定義しています。

 from werkzeug.security import generate_password_hash, check_password_hash class User: def __init__(self, username, password, email): self.username = username self.password_hash = generate_password_hash(password) self.email = email self.roles = [] def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)


2.2 トークン管理

トークンベースの認証に JWT を使用することは、サイバーセキュリティとバックエンド開発のベストプラクティスの観点からは良い選択です。

 def generate_token(user): payload = { 'username': user.username, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1) } return jwt.encode(payload, SECRET_KEY, algorithm='HS256') def verify_token(token): try: payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) return payload['username'] except jwt.ExpiredSignatureError: return None except jwt.InvalidTokenError: return None


2.3 デコレータ

  • ユーザーがページへのアクセスを許可されているかどうかを確認するデコレータ。
 from functools import wraps from flask import request, jsonify, session def is_authenticated(func): @wraps(func) def decorated_function(*args, **kwargs): if 'user' not in session: return jsonify({"error": "User not authenticated"}), 401 return func(*args, **kwargs) return decorated_function


  • ユーザーの役割を確認するためのデコレータ。
 def roles_required(*roles): def decorator(func): @wraps(func) def decorated_function(*args, **kwargs): user_roles = session.get('roles', []) if not any(role in user_roles for role in roles): return jsonify({"error": "User does not have the required role"}), 403 return func(*args, **kwargs) return decorated_function return decorator


基本的にはこれで完了です。この定義済み機能をすべてのプロジェクトにわたる認証に使用できます。

3. 支払いと請求

ほとんどすべてのアプリケーションは金融取引を処理します。地元の肉屋でも大企業でも、支払いを収集するには効果的なシステムを使用する必要があります。


基本コンポーネント

  1. 決済ゲートウェイの統合: StripePayPalなどの決済ゲートウェイとの接続
  2. 支払いモデル:支払いデータを処理するためのモデルを定義します。
  3. 支払い処理:支払いライフサイクル (開始、確認など) を処理します。


3.1 決済ゲートウェイの統合

これは、Stripe の具体的な実装を使用して、さまざまな支払いゲートウェイを統合するためのベースとして使用できます。一般的に、私の個人的な好みは、支払いにはStripeAPIを使用することです。これは、市場に長い間存在しており、どのプロジェクトにも簡単に統合できるためです。


 class PaymentGateway(ABC): @abstractmethod def create_payment_intent(self, amount, currency='gbp'): pass @abstractmethod def confirm_payment(self, payment_id): pass @abstractmethod def handle_webhook(self, payload, sig_header): pass

これは支払いゲートウェイの最も一般的な例であり、ニーズに応じて特定の実装に焦点を当てることができます。


3.2 支払いモデル

支払い情報を保存するモデルを定義します。この例は、ORM での使用に適応できます。必要に応じて、より複雑なクラス階層を作成することもできますが、この例では、次のスニペットで十分でしょう。

 class Payment: def __init__(self, user_id, amount, currency): self.id = uuid.uuid4() self.user_id = user_id self.amount = amount self.currency = currency self.status = status payments = []


3.3 セクションでは、すべての支払いをデータベースに保存し、トランザクションを処理するためのCeleryタスクを設定します。データベース レコードは次のようになります。

 id | user_id | amount | currency | status --------------------------------------+-----------------------------------+--------+----------+---------- e532d653-7c8b-453a-8cd4-3ab956863d72 | 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 100.00 | USD | Failed 35985d41-5d54-4021-bed6-82d7233cc353 | a0984002-bace-478e-b6f9-6e4459e1b5ba | 250.50 | EUR | Pending 1ff9efb3-d5e8-4e53-854f-4246ba9ff638 | 9f896874-dc43-4592-8289-d0f7f8b8583a | 99.99 | GBP | Completed


これで、あらゆるプロジェクトに統合できる複雑なシステムが作成されました。まだパターンに従っていますか?これはどこでも使用できます。


結局のところ、このデータを視覚化するための別のアプリケーションを定義できます。テンプレート化のポイントは理解できました! 😉

4. 電子メールと通知サービス

メールと通知により、ユーザーはアプリの最新情報を入手し、アプリの利用を継続できます。アカウントの確認、パスワードのリセット、マーケティング コミュニケーションなど、どのようなプロジェクトでも、信頼性の高いメール サービスは不可欠です。

  1. 電子メール サービスの統合: SendGridAmazon SESなどの電子メール サービスと接続します。
  2. 電子メール テンプレート:さまざまな電子メール タイプのテンプレートを定義します。
  3. メールの送信:統合サービスを使用してメールを送信する機能。


4.1 電子メールサービスの統合

EmailServiceクラス内で電子メールを送信するためのSendGridのメイン ロジックを定義します。

 import sendgrid from sendgrid.helpers.mail import Mail class EmailService: def __init__(self, api_key): self.sg = sendgrid.SendGridAPIClient(api_key) def send_email(self, from_email, to_email, subject, html_content): email = Mail( from_email=from_email, to_emails=to_email, subject=subject, html_content=html_content ) try: response = self.sg.send(email) return response.status_code except Exception as e: return str(e)


決済ゲートウェイと同様に、市場にある特定のユーティリティや製品に焦点を当てる必要はありません。これは、あらゆるプロジェクト向けに一般化およびテンプレート化できる方法の一例にすぎません。


4.2 メールテンプレート

このようなシステムで私が気に入っているパターンは、ハンドラー パターンです。電子メールの種類として辞書にキーを追加し、コンテンツを含むファイルへのパスを追加するだけです。


 email_templates = { 'welcome': “welcome.html”, 'reset_password': "<h1>Reset Your Password</h1><p>Click <a href='{link}'>here</a> to reset your password.</p>" }


それ以外の場合は、同じ目的でEnumを定義すると便利です。


4.3メールの送信

魔法を起こすには関数が必要です! 次のように記述してみましょう:

 def send_email(email_service, from_email, to_email, subject, template_name, **template_vars): """ Send an email using the specified email service. """ html_content = get_email_template(template_name, **template_vars) return email_service.send_email(from_email, to_email, subject, html_content)


もう 1 つの重要なポイントは、 README .env config.pypyproject.toml, .pre-commit.ymlなどのいくつかのファイルをすべてのバックエンド プロジェクトに追加し、プロジェクト内のファイルの基本構造を作成することです。


提案された構造は Python 実装に少し限定されていますが、前述したように、他の言語や分野でも同様に行うことができます。


また、最高レベルの抽象化でテンプレート化を行い、アプリケーションの適切な構造を維持することは、

パッケージとして、またはマイクロサービス アーキテクチャへの追加として、他のプロジェクトに再利用されます。



図 1 - マイクロサービス アーキテクチャの例

5。結論

すべてをテンプレート化できます!


ここで紹介した例はほんの始まりに過ぎません。これらのパターンは、プロジェクトの進化に合わせて拡張および改良し、より複雑なシナリオに対応できます。 cachingを追加して、 k8sdockerDevopsインフラストラクチャ、 CI/CD 、パイプラインを構築することもできます。


1 つの簡単なステートメントを覚えておいてください。自分の仕事を適切に完了したら、同じ仕事を使用して別の仕事を完了することができます。


目標は、プロジェクト、インフラストラクチャ、コンポーネント、およびサービスをさまざまなアプリケーション間で再利用できるようにすることです。


お茶を淹れて、アプリケーションのどの部分を別のアプリで再利用できるか考えてみましょう。コードの一部だけを調整して、同様のサービスを作成し、作業を自動化してみてください。


読んでいただきありがとうございます。テンプレート作成を楽しんでください!