Шаблоны проектирования играют решающую роль в создании надежных и удобных в обслуживании приложений Android. Они обеспечивают структурированный подход к решению распространенных проблем проектирования программного обеспечения и способствуют повторному использованию кода, масштабируемости и тестируемости. В этой статье мы рассмотрим несколько популярных шаблонов проектирования, используемых в приложениях Android, а также примеры кода.
- Шаблон Модель-Представление-Контроллер (MVC):
Шаблон MVC разделяет логику приложения на три компонента: Модель, Представление и Контроллер. Модель представляет данные и бизнес-логику, представление управляет пользовательским интерфейсом, а контроллер выступает в качестве посредника между моделью и представлением. Вот простой пример:
// Model
public class UserModel {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// View
public class MainActivity extends AppCompatActivity {
private TextView nameTextView;
// ...
public void updateName(String name) {
nameTextView.setText(name);
}
}
// Controller
public class UserController {
private UserModel userModel;
private MainActivity mainActivity;
public UserController(UserModel userModel, MainActivity mainActivity) {
this.userModel = userModel;
this.mainActivity = mainActivity;
}
public void updateUser(String name) {
userModel.setName(name);
mainActivity.updateName(name);
}
}
- Шаблон Модель-Представление-Презентатор (MVP):
Шаблон MVP — это развитие MVC, где Presenter выступает в роли посредника между Представлением и Моделью. Presenter обрабатывает взаимодействие с пользователем и соответствующим образом обновляет представление и модель. Вот пример:
// Model
public class UserModel {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// View
public interface UserView {
void updateName(String name);
}
public class MainActivity extends AppCompatActivity implements UserView {
private TextView nameTextView;
// ...
@Override
public void updateName(String name) {
nameTextView.setText(name);
}
}
// Presenter
public class UserPresenter {
private UserModel userModel;
private UserView userView;
public UserPresenter(UserModel userModel, UserView userView) {
this.userModel = userModel;
this.userView = userView;
}
public void updateUser(String name) {
userModel.setName(name);
userView.updateName(name);
}
}
- Шаблон Модель-Представление-ViewModel (MVVM):
Шаблон MVVM отделяет логику пользовательского интерфейса от бизнес-логики с помощью ViewModel, которая предоставляет данные и действия представлению. Это способствует связыванию данных и уменьшает связь между компонентами. Вот пример:
// Model
public class UserModel {
private MutableLiveData<String> name = new MutableLiveData<>();
public void setName(String name) {
this.name.setValue(name);
}
public LiveData<String> getName() {
return name;
}
}
// View
public class MainActivity extends AppCompatActivity {
private TextView nameTextView;
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
UserModel userModel = ViewModelProvider(this).get(UserModel.class);
userModel.getName().observe(this, name -> nameTextView.setText(name));
}
}
// ViewModel
public class UserModel extends ViewModel {
private MutableLiveData<String> name = new MutableLiveData<>();
public void setName(String name) {
this.name.setValue(name);
}
public LiveData<String> getName() {
return name;
}
}
- Шаблон Singleton:
Шаблон Singleton гарантирует, что создается только один экземпляр класса, и предоставляет глобальную точку доступа к нему. Он обычно используется для управления ресурсами, которые должны быть общими для всего приложения. Вот пример:
public class MySingleton {
private static MySingleton instance;
private MySingleton() {
// Private constructor to prevent instantiation
}
public static MySingleton getInstance() {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
// Other methods and properties
}
- Шаблон «Наблюдатель»:
Шаблон «Наблюдатель» позволяет объектам устанавливать зависимость «один ко многим», при которой несколько наблюдателей уведомляются при изменении состояния субъекта. Он широко используется для реализации архитектур, управляемых событиями. Вот пример:
public interface Observer {
void update();
}
public interface Subject {
void registerObserver(Observer observer);
void unregisterObserver(Observer observer);
void notifyObservers();
}
public class MySubject implements Subject {
private List<Observer> Oops! It seems that my response got cut off. Here's the continuation:
```java
public class MySubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void unregisterObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
// Other methods and properties
}
- Шаблон Factory:
Шаблон Factory предоставляет интерфейс для создания объектов, позволяя подклассам решать, экземпляр какого класса создавать. Это способствует слабой связи и повышает гибкость при создании объектов. Вот пример:public interface Animal { void sound(); }
публичный класс Dog реализует Animal {
@Override
public void sound() {
System.out.println(“Гав!”);
}
публичный класс Cat реализует Animal {
@Override
public void sound() {
System.out.println(“Meow!”);
}
public class AnimalFactory {
public Animal createAnimal(String type) {
if (type.equalsIgnoreCase(“dog”)) {
return new Dog();
} else if (type.equalsIgnoreCase(“cat”)) {
вернуть новый Cat();
вернуть ноль;
7. Adapter Pattern:
The Adapter pattern allows incompatible classes to work together by converting the interface of one class into another that the client expects. It is commonly used when integrating existing code into new systems. Here's an example:
```java
public interface MediaPlayer {
void play(String audioType, String fileName);
}
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
@Override
public void playMp4(String fileName) {
// Do nothing
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// Do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMediaPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer.playMp4(fileName);
}
}
}
public class AudioPlayer implements MediaPlayer {
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media type: " + audioType);
}
}
}
-
Шаблон Builder:
Шаблон Builder позволяет создавать сложные объекты шаг за шагом, позволяя создавать различные конфигурации без необходимости использования нескольких конструкторов или чрезмерных параметров. Это улучшает читаемость и удобство сопровождения кода. Вот пример:public class User { private final String firstName; private final String lastName; private final int age; private final String email; private User(UserBuilder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.email = builder.email; } // Getters public static class UserBuilder { private final String firstName; private final String lastName; private int age; private String email; public UserBuilder(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public UserBuilder age(int age) { this.age = age; return this; } public UserBuilder email(String email) { this.email = email; return this; } public User build() { return new User(this); } } } // Usage User user = new User.UserBuilder("John", "Doe") .age(30) .email("john.doe@example.com") .build();
В этой статье