ログインボックスを表示します

検索ガイド -Search Guide-

単語と単語を空白で区切ることで AND 検索になります。
例: python デコレータ ('python' と 'デコレータ' 両方を含む記事を検索します)
単語の前に '-' を付けることで NOT 検索になります。
例: python -デコレータ ('python' は含むが 'デコレータ' は含まない記事を検索します)
" (ダブルクオート) で語句を囲むことで 完全一致検索になります。
例: "python data" 実装 ('python data' と '実装' 両方を含む記事を検索します。'python data 実装' の検索とは異なります。)
当サイトのドメイン名は " getwebtips.net " です。
トップレベルドメインは .net であり、他の .com / .shop といったトップレベルドメインのサイトとは一切関係ありません。
practical_python_design_patterns

Practical Python Design Patterns - Python で学ぶデザインパターン: The Adapter Pattern - Part. 6 「アダプターパターン - ダメ押し確認 [Twitter への tweet 投稿機能の実装例]」の巻 投稿一覧へ戻る

Published 2022年6月3日17:58 by T.Tsuyoshi

SUPPORT UKRAINE

- Your indifference to the act of cruelty can thrive rogue nations like Russia -

Parting Shots (implementing the function to send tweet to Twitter)
(アダプターパターン - ダメ押し確認 [Twitter への tweet 投稿機能の実装例])

この章を通して、デザインが決まってしまっているものを自分の望む形で利用したい場合にアダプターが有用であることが理解できたと思います。既存のインターフェースに対して、現在のシステムで利用しているインターフェースでアクセス可能にするための方法を与えてくれるものでした。
アダプターパターンを構成する要素を以下にまとめておきます:
Target - 現在のシステムで利用したいインターフェースを定義するための抽象クラスです。クライアントはこのインターフェースを通してサービスを利用します。
Client - サービスを利用するために Target クラスで定義されたインターフェースを使用します。
Adaptee - Client の利用対象となる既存のサービスであり、Target クラスで定義しているものとは異なるインターフェースを提供しています。
Adapter - Adaptee が提供しているインターフェースを、Client が利用する (すなわち、現在のシステムで「望む」) インターフェースに変換する機能を提供します。
そしてアダプターパターンを実装するプロセスは非常に簡単です:
提供するサービスコンポーネントを定義します
クライアントが希望するインターフェースを確認し、必要であれば抽象クラスとして定義します
サービス側が提供するインターフェースをクライアントが希望するインターフェースにマップさせるためのアダプターを設計、実装します
クライアントからはインターフェースしか見えず、実際のサービスがどのように実現されているのか、からは切り離されています。これによって、システムの拡張性、メンテナンス性が向上します。
さて、本章の締めとして、この章を通じて作成してきたメール送信プログラムに、SNS への投稿機能も付加してみましょう。勿論、共通インターフェースとして採用している send() を通してサービスを利用できるようにします。ここでは Twitter への投稿機能の例を示しますが、どうぞご自分で Instagram への画像投稿、Youtube への動画投稿など、色々と挑戦してみてください。
NOTE
ここで示す Twitter への投稿機能を実際に試してみるには、Twitter Developer Platform へのサインアップが必要です。また、App の登録を行いアクセス時認証に必要なアクセストークン等を取得する必要があります。ググれば情報は色々と出てくると思いますので、是非「投稿」だけではなく様々な API を試してください:
Send email, print log, post tweet サービス対応アダプターパターン採用プログラム
- 共通インターフェース: send(sender, recipients, subject, message) -
import csv
import smtplib
from email.mime.text import MIMEText
from urllib.parse import quote
import oauth2

from user_fetcher import UserFetcher


class Mailer:
def send(self, sender, recipients: list[str], subject, message):
msg = MIMEText(message, _charset='utf-8')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = ','.join(recipients)

with smtplib.SMTP(host='server_name', port=123) as mail_sender:
mail_sender.login('user_name', 'password')
errors = mail_sender.send_message(msg)

if isinstance(errors, dict) and len(errors) > 0:
print(f'Error: {errors}')


class Logger:
def output(self, message):
print(f'[Logger] {message}')


class LoggerAdapter:
def __init__(self):
self.what_i_have = Logger()

def send(self, sender, recipients: list[str], subject, message):
log_message = f'From: {sender}\nTo: {recipients}\nSubject: {subject}\nMessage: {message}'
self.what_i_have.output(log_message)

def __getattr__(self, attr):
return getattr(self.what_i_have, attr)


class Tweets:
def post_tweets(self, message):
CONSUMER_KEY = 'API Key'
CONSUMER_KEY_SECRET = 'API Key Secret'
ACCESS_TOKEN = 'Access Token'
ACCESS_TOKEN_SECRET = 'Access Token Secret'

consumer = oauth2.Consumer(key=CONSUMER_KEY, secret=CONSUMER_KEY_SECRET)
token = oauth2.Token(key=ACCESS_TOKEN, secret=ACCESS_TOKEN_SECRET)
client = oauth2.Client(consumer, token)

url = 'https://api.twitter.com/1.1/statuses/update.json?status=' + quote(message)
res, content = client.request(url, method="POST")
print(f'Status: {res.status}')


class PostTweetsAdapter:
def __init__(self):
self.what_i_have = Tweets()

def send(self, sender, recipients: list[str], subject, message):
self.what_i_have.post_tweets(message)

def __getattr__(self, attr):
return getattr(self.what_i_have, attr)


if __name__ == '__main__':
user_fetcher = UserFetcher('users.csv')
mailer = Mailer()
logger = LoggerAdapter()
tweet_adapter = PostTweetsAdapter()

for x in user_fetcher.fetch_user():
mailer.send(
'python_blog@getwebtips.net',
[x['email']],
'ご挨拶とお知らせ',
f'{x["surname"]} {x["name"]} 様\n良い一日をお過ごしください'
)
logger.send(
'python_blog@getwebtips.net',
[x['email']],
'ご挨拶とお知らせ',
f'{x["surname"]} {x["name"]} 様\n良い一日をお過ごしください'
)
tweet_adapter.send(
'python_blog@getwebtips.net',
[x['email']],
'ご挨拶とお知らせ',
f'Oh, my - From {x["surname"]} {x["name"]} - python program からのツイートです!!'
)
実行結果はこんな感じです:
practical_python_design_patterns_chapter_6_6_twitter
Twitter 投稿画面 スクリーンショット
practical_python_design_patterns_chapter_6_6_mail
メールボックス スクリーンショット
practical_python_design_patterns_chapter_6_6_command_prompt
コマンドプロンプト スクリーンショット

この投稿をメールでシェアする

0 comments

コメントはまだありません。

コメントを追加する(不適切と思われるコメントは削除する場合があります)