Mapper (Распределитель)
Паттерн проектирования Mapper
Описание Mapper
Объект, который управляет сообщением между независимыми друг от друга объектами.
Иногда нужно установить сообщение между двумя подсистемами, которые, между тем должны оставаться в неведении друг о друге. Это может быть обусловлено невозможностью изменения этих объектов, или просто нежеланием создавать зависимости между ними или между ними и изолирующей частью.
Примеры реализации
// Mapper Pattern in JavaScript
class User {
constructor(id, name, email) {
this.id = id;
this.name = name;
this.email = email;
}
}
class UserDTO {
constructor(id, fullName, emailAddress) {
this.id = id;
this.fullName = fullName;
this.emailAddress = emailAddress;
}
}
class UserMapper {
static toDTO(user) {
return new UserDTO(
user.id,
user.name,
user.email
);
}
static toEntity(dto) {
return new User(
dto.id,
dto.fullName,
dto.emailAddress
);
}
static mapArray(users) {
return users.map(user => UserMapper.toDTO(user));
}
}
class NotificationService {
constructor() {
this.mapper = UserMapper;
}
sendWelcomeEmail(user) {
const userDTO = this.mapper.toDTO(user);
console.log(`Sending welcome email to ${userDTO.fullName} at ${userDTO.emailAddress}`);
return { success: true, messageId: `msg_${Date.now()}` };
}
}
// Usage
const user = new User(1, 'John Doe', 'john@example.com');
const notificationService = new NotificationService();
const result = notificationService.sendWelcomeEmail(user);
console.log('Notification result:', result);
<?php
// Mapper Pattern in PHP
class User {
private $id;
private $name;
private $email;
public function __construct($id, $name, $email) {
$this->id = $id;
$this->name = $name;
$this->email = $email;
}
public function getId() { return $this->id; }
public function getName() { return $this->name; }
public function getEmail() { return $this->email; }
}
class UserDTO {
private $id;
private $fullName;
private $emailAddress;
public function __construct($id, $fullName, $emailAddress) {
$this->id = $id;
$this->fullName = $fullName;
$this->emailAddress = $emailAddress;
}
public function getId() { return $this->id; }
public function getFullName() { return $this->fullName; }
public function getEmailAddress() { return $this->emailAddress; }
}
class UserMapper {
public static function toDTO($user) {
return new UserDTO(
$user->getId(),
$user->getName(),
$user->getEmail()
);
}
public static function toEntity($dto) {
return new User(
$dto->getId(),
$dto->getFullName(),
$dto->getEmailAddress()
);
}
public static function mapArray($users) {
return array_map(function($user) {
return UserMapper::toDTO($user);
}, $users);
}
}
class NotificationService {
private $mapper;
public function __construct() {
$this->mapper = UserMapper::class;
}
public function sendWelcomeEmail($user) {
$userDTO = UserMapper::toDTO($user);
echo "Sending welcome email to {$userDTO->getFullName()} at {$userDTO->getEmailAddress()}\n";
return ['success' => true, 'messageId' => 'msg_' . time()];
}
}
// Usage
$user = new User(1, 'John Doe', 'john@example.com');
$notificationService = new NotificationService();
$result = $notificationService->sendWelcomeEmail($user);
echo "Notification result: " . json_encode($result) . "\n";
?>
// Mapper Pattern in Go
package main
import (
"fmt"
"time"
)
type User struct {
ID int
Name string
Email string
}
type UserDTO struct {
ID int
FullName string
EmailAddress string
}
type UserMapper struct{}
func (um UserMapper) ToDTO(user User) UserDTO {
return UserDTO{
ID: user.ID,
FullName: user.Name,
EmailAddress: user.Email,
}
}
func (um UserMapper) ToEntity(dto UserDTO) User {
return User{
ID: dto.ID,
Name: dto.FullName,
Email: dto.EmailAddress,
}
}
func (um UserMapper) MapArray(users []User) []UserDTO {
dtos := make([]UserDTO, len(users))
for i, user := range users {
dtos[i] = um.ToDTO(user)
}
return dtos
}
type NotificationService struct {
mapper UserMapper
}
func NewNotificationService() *NotificationService {
return &NotificationService{
mapper: UserMapper{},
}
}
func (ns *NotificationService) SendWelcomeEmail(user User) map[string]interface{} {
userDTO := ns.mapper.ToDTO(user)
fmt.Printf("Sending welcome email to %s at %s\n", userDTO.FullName, userDTO.EmailAddress)
return map[string]interface{}{
"success": true,
"messageId": fmt.Sprintf("msg_%d", time.Now().Unix()),
}
}
// Usage
func main() {
user := User{ID: 1, Name: "John Doe", Email: "john@example.com"}
notificationService := NewNotificationService()
result := notificationService.SendWelcomeEmail(user)
fmt.Printf("Notification result: %+v\n", result)
}
Использована иллюстрация с сайта Мартина Фаулера.