Java设计模式的原则有哪些
更新时间:2023-07-16
Java编程中设计模式大多使用了GOF的23种设计模式,这些模式可以等价地被分为三类——创建型模式、结构型模式和行为型模式。每一种模式都要使用在正确的情况下,并要确保代码的可读性和维护性。本文将会从以上三种模式的角度阐述Java设计模式的原则和实践。
### 创建型模式
创建型模式在对象的创建上提供了更好的方式,例如:工厂模式、单例模式和原型模式、建造者模式。
#### 工厂模式
工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式,而无需指定其确切的类。在工厂模式中,我们只是在创建对象时调用一个工厂方法,它会为我们生成所需类型的对象。例如:
```java
public interface Animal {
void speak();
}
public class Cat implements Animal {
public void speak() {
System.out.println("Meow");
}
}
public class Dog implements Animal {
public void speak() {
System.out.println("Woof");
}
}
public class AnimalFactory {
public Animal createAnimal(String type) {
if("Cat".equals(type)) {
return new Cat();
} else if("Dog".equals(type)) {
return new Dog();
} else {
return null;
}
}
}
//使用代码
AnimalFactory factory = new AnimalFactory();
Animal cat = factory.createAnimal("Cat");
cat.speak(); // Meow
Animal dog = factory.createAnimal("Dog");
dog.speak(); // Woof
```
#### 单例模式
单例模式中,一个类只会创建一个对象的实例,并提供了全局访问点。在Java中,常常使用这种模式来保证创建一个对象的实例,并且不希望它被创建多次。例如:
```java
public class SingletonObject {
private static SingletonObject instance = new SingletonObject();
private SingletonObject() {}
public static SingletonObject getInstance() {
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
//使用代码
SingletonObject instance = SingletonObject.getInstance();
instance.showMessage(); // Hello World!
```
#### 原型模式
原型模式是一种创建型模式,它允许我们复制一个对象,而不会影响原始对象的属性和行为。在Java中,提供了clone()方法来实现原型模式。例如:
```java
public abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType() {
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
public class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square extends Shape {
public Square() {
type = "Square";
}
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class ShapeCache {
public static Hashtable shapeMap = new Hashtable();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(),square);
Rectangle rectangle = new Rectangle();
rectangle.setId("3");
shapeMap.put(rectangle.getId(),rectangle);
}
}
//使用代码
ShapeCache.loadCache();
Shape clonedShape = ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape.getType());
Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
Shape clonedShape3 = ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType());
```
#### 建造者模式
建造者模式是一种创建型模式,它提供了一种分步构建复杂对象的方式。例如:
```java
public class Meal {
private List- items = new ArrayList
- ();
public void addItem(Item item) {
items.add(item);
}
public float getCost() {
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems() {
for (Item item : items) {
System.out.print("Item : " + item.name());
System.out.print(", Packing : " + item.packing().pack());
System.out.println(", Price : " + item.price());
}
}
}
public interface Item {
public String name();
public Packing packing();
public float price();
}
public interface Packing {
public String pack();
}
public class Wrapper implements Packing {
public String pack() {
return "Wrapper";
}
}
public class Bottle implements Packing {
public String pack() {
return "Bottle";
}
}
public abstract class Burger implements Item {
public Packing packing() {
return new Wrapper();
}
public abstract float price();
}
public abstract class ColdDrink implements Item {
public Packing packing() {
return new Bottle();
}
public abstract float price();
}
public class VegBurger extends Burger {
public float price() {
return 25.0f;
}
public String name() {
return "Veg Burger";
}
}
public class ChickenBurger extends Burger {
public float price() {
return 50.5f;
}
public String name() {
return "Chicken Burger";
}
}
public class Coke extends ColdDrink {
public float price() {
return 30.0f;
}
public String name() {
return "Coke";
}
}
public class Pepsi extends ColdDrink {
public float price() {
return 35.0f;
}
public String name() {
return "Pepsi";
}
}
public class MealBuilder {
public Meal prepareVegMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
//使用代码
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " + vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " + nonVegMeal.getCost());
```
### 结构型模式
结构型模式可以让对象间的关系更加有效和标准,例如:适配器模式、桥接模式、过滤器模式、合成模式、外观模式、装饰器模式和享元模式。其中,适配器模式是最常用且最基础的模式。
#### 适配器模式
适配器模式是一种结构型模式,通过它我们可以改变接口的现有实现,以便其他类和接口可以适当地工作。例如:
```java
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer {
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: "+ fileName);
}
public void playMp4(String fileName) {}
}
public class Mp4Player implements AdvancedMediaPlayer{
public void playVlc(String fileName) {}
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName);
}
}
public interface MediaPlayer {
public void play(String audioType, String fileName);
}
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: " + fileName);
}
else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
}
else{
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
//使用代码
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
```
### 行为型模式
行为型模式定义了对象之间的通信模式,例如:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板模式和访问者模式。
#### 观察者模式
观察者模式是一种行为型模式,在对象之间定义一对多的依赖,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。例如:
```java
public class Subject {
private List
observers = new ArrayList();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer){
observers.add(observer);
}
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
public class BinaryObserver extends Observer{
public BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
public void update() {
System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) );
}
}
public class OctalObserver extends Observer{
public OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
public void update() {
System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) );
}
}
public class HexaObserver extends Observer{
public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
public void update() {
System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() );
}
}
//使用代码
Subject subject = new Subject();
new HexaObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);
System.out.println("First state change: 15");
subject.setState(15);
System.out.println("\nSecond state change: 10");
subject.setState(10);
```
总结:本文阐述了Java编程中设计模式的原则、种类和示例。每一种模式都要根据情况和需求使用,同时也要保证代码的可读性和维护性。要总结Java设计模式,我们需要深入掌握这个领域中的原则和模式,这样才能更高效、更优雅地编写代码。