📜  java oop 设计模式 - Java (1)

📅  最后修改于: 2023-12-03 15:01:31.837000             🧑  作者: Mango

Java OOP 设计模式

Java OOP 设计模式是一系列常见的面向对象设计模式,它们可以帮助程序员更好地完成软件设计,并提高软件的可维护性、扩展性和可复用性。在本文中,我们将对 Java OOP 设计模式进行介绍。

设计模式概述

设计模式是针对某一类软件设计问题,提出的通用解决方案。它们由经验丰富的软件开发人员总结出来,因此在实际开发中被广泛使用。

设计模式分为三类:创建型模式、结构型模式和行为型模式。创建型模式主要用于对象的创建,结构型模式主要用于描述对象之间的关系,行为型模式主要用于描述对象之间的通信和协作。

Java OOP 设计模式介绍
创建型模式

工厂模式(Factory Pattern)

工厂模式是常用的创建型模式之一,通过定义一个工厂类来创建对象,可以将对象的创建与使用分离。工厂模式提供了一种灵活的创建对象的方式,可以根据需要返回不同类型的对象。

代码片段:

public interface Shape {
    void draw();
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle::draw()");
    }
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle::draw()");
    }
}

public class ShapeFactory {
    public Shape getShape(String shapeType){
        if(shapeType == null){
            return null;
        }
        if(shapeType.equalsIgnoreCase("CIRCLE")){
            return new Circle();
        } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return new Rectangle();
        }
        return null;
    }
}

public class FactoryPatternDemo {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();

        Shape shape2 = shapeFactory.getShape("RECTANGLE");
        shape2.draw();
    }
}

建造者模式(Builder Pattern)

建造者模式是一种对象构建的设计模式,它可以将一个复杂对象的构建过程与其表示分离。通过使用一些列简单的对象,可以构建出一个复杂的对象。

代码片段:

public class Burger {
    private String name;
    private String meat;
    private String sauce;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMeat() {
        return meat;
    }

    public void setMeat(String meat) {
        this.meat = meat;
    }

    public String getSauce() {
        return sauce;
    }

    public void setSauce(String sauce) {
        this.sauce = sauce;
    }
}

public abstract class BurgerBuilder {
    protected Burger burger;

    public Burger getBurger() {
        return burger;
    }

    public void createNewBurger() {
        burger = new Burger();
    }

    public abstract void buildName();
    public abstract void buildMeat();
    public abstract void buildSauce();
}

public class ClassicBurgerBuilder extends BurgerBuilder {
    @Override
    public void buildName() {
        burger.setName("Classic Burger");
    }

    @Override
    public void buildMeat() {
        burger.setMeat("Beef");
    }

    @Override
    public void buildSauce() {
        burger.setSauce("Ketchup");
    }
}

public class Director {
    public void constructBurger(BurgerBuilder builder) {
        builder.createNewBurger();
        builder.buildName();
        builder.buildMeat();
        builder.buildSauce();
    }
}

public class BuilderPatternDemo {
    public static void main(String[] args) {
        Director director = new Director();
        BurgerBuilder builder = new ClassicBurgerBuilder();
        director.constructBurger(builder);

        Burger burger = builder.getBurger();

        System.out.println("Burger : " + burger.getName() + ", Meat : " + burger.getMeat()
                + ", Sauce : " + burger.getSauce());
    }
}
结构型模式

适配器模式(Adapter Pattern)

适配器模式是一种将一个类的接口转换成客户希望的另一个接口的设计模式。适配器模式允许接口不兼容的类可以合作无间。

代码片段:

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. Name: "+ fileName);    
     }

     @Override
     public void playMp4(String fileName) {
        //什么也不做
     }
}

public class Mp4Player implements AdvancedMediaPlayer{

    @Override
    public void playVlc(String fileName) {
        //什么也不做
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: "+ 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();
        }  
    }

    @Override
    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; 

    @Override
    public void play(String audioType, String fileName) {    

        //播放 mp3 音乐文件的内置支持
        if(audioType.equalsIgnoreCase("mp3")){
            System.out.println("Playing mp3 file. Name: " + fileName);         
        } 
        //mediaAdapter 提供了播放其他文件格式的支持
        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");
        }
    }   
}

public class AdapterPatternDemo {
    public static void main(String[] args) {
        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");
    }
}

组合模式(Composite Pattern)

组合模式是一种使用树形结构实现的设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。 组合模式使得用户可以使用统一的方式处理单个对象以及对象的组合。

代码片段:

import java.util.ArrayList;
import java.util.List;

public interface Employee {
    public void add(Employee employee);
    public void remove(Employee employee);
    public Employee getChild(int i);
    public String getName();
    public double getSalary();
    public void print();
}

public class Developer implements Employee {
    private String name;
    private double salary;

    public Developer(String name,double salary){
        this.name = name;
        this.salary = salary;
    }

    public void add(Employee employee) {}

    public Employee getChild(int i) {
        return null;
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public void print() {
        System.out.println("-------------");
        System.out.println("Name ="+getName());
        System.out.println("Salary ="+getSalary());
        System.out.println("-------------");
    }

    public void remove(Employee employee) {}

}

public class Manager implements Employee {
    private String name;
    private double salary;

    public Manager(String name,double salary){
        this.name = name;
        this.salary = salary;
    }

    List<Employee> employees = new ArrayList<Employee>();

    public void add(Employee employee) {
        employees.add(employee);
    }

    public Employee getChild(int i) {
        return employees.get(i);
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public void print() {
        System.out.println("-------------");
        System.out.println("Name ="+getName());
        System.out.println("Salary ="+getSalary());
        System.out.println("-------------");

        for (Employee employee : employees) {
            employee.print();
        }
    }

    public void remove(Employee employee) {
        employees.remove(employee);
    }   
}

public class CompositePatternDemo {

    public static void main(String[] args) {
        Employee emp1 = new Developer("John", 10000);
        Employee emp2 = new Developer("David", 15000);
        Employee manager1 = new Manager("Daniel",25000);
        manager1.add(emp1);
        manager1.add(emp2);
        Employee emp3 = new Developer("Michael", 20000);
        Manager generalManager = new Manager("Mark", 50000);
        generalManager.add(emp3);
        generalManager.add(manager1);
        generalManager.print();
    }
}
行为型模式

观察者模式(Observer Pattern)

观察者模式是对象之间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知并自动更新。

代码片段:

import java.util.ArrayList;
import java.util.List;

public interface Observer {
    public void update();
}

public class MyTopic implements Subject {

    private List<Observer> observers;
    private String message;
    private boolean changed;
    private final Object MUTEX= new Object();

    public MyTopic(){
        this.observers=new ArrayList<>();
    }

    @Override
    public void register(Observer obj) {
        if(obj == null) throw new NullPointerException("Null Observer");
        synchronized (MUTEX) {
            if(!observers.contains(obj)) observers.add(obj);
        }
    }

    @Override
    public void unregister(Observer obj) {
        synchronized (MUTEX) {
            observers.remove(obj);
        }
    }

    @Override
    public void notifyObservers() {
        List<Observer> observersLocal = null;
        //synchronization is used to make sure any observer registered after message is received is not notified
        synchronized (MUTEX) {
            if (!changed)
                return;
            observersLocal = new ArrayList<>(this.observers);
            this.changed=false;
        }
        for (Observer obj : observersLocal) {
            obj.update();
        }
    }

    @Override
    public Object getUpdate(Observer obj) {
        return this.message;
    }

    //method to post message to the topic
    public void postMessage(String msg){
        System.out.println("Message Posted to Topic:"+msg);
        this.message=msg;
        this.changed=true;
        notifyObservers();
    }

}

public interface Subject {

    //methods to register and unregister observers
    public void register(Observer obj);
    public void unregister(Observer obj);

    //method to notify observers of change
    public void notifyObservers();

    //method to get updates from subject
    public Object getUpdate(Observer obj);

}

public class MyTopicSubscriber implements Observer {

    private String name;
    private Subject topic;

    public MyTopicSubscriber(String name){
        this.name = name;
    }

    public void subscribe(Subject topic){
        this.topic = topic;
        topic.register(this);
    }

    public void unSubscribe(){
        topic.unregister(this);
    }

    @Override
    public void update() {
        String msg = (String) topic.getUpdate(this);
        if(msg == null){
            System.out.println(name+":: No new message");
        }else
        System.out.println(name+":: Consuming message::"+msg);
    }
}


public class ObserverPatternDemo {

    public static void main(String[] args) {
        //create subject
        MyTopic topic = new MyTopic();

        //create observers
        Observer obj1 = new MyTopicSubscriber("Obj1");
        Observer obj2 = new MyTopicSubscriber("Obj2");
        Observer obj3 = new MyTopicSubscriber("Obj3");

        //register observers to the subject
        topic.register(obj1);
        topic.register(obj2);
        topic.register(obj3);

        //attach observer to subject
        obj1.subscribe(topic);
        obj2.subscribe(topic);
        obj3.subscribe(topic);

        //check if any update is available
        obj1.update();

        //now send message to subject
        topic.postMessage("New Message");

        obj1.update();

        obj2.unSubscribe();

        topic.postMessage("New Message2");
    }

}

策略模式(Strategy Pattern)

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同。

代码片段:

public interface Strategy {
    public int doOperation(int num1, int num2);
}

public class OperationAdd implements Strategy{
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

public class OperationSubtract implements Strategy{
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

public class OperationMultiply implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

public class Context {
    private Strategy strategy;

    public Context(Strategy strategy){
        this.strategy = strategy;
    }

    public int executeStrategy(int num1, int num2){
        return strategy.doOperation(num1, num2);
    }
}

public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new OperationAdd());        
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

        context = new Context(new OperationSubtract());       
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

        context = new Context(new OperationMultiply());        
        System.out.println("10 x 5 = " + context.executeStrategy(10, 5));
    }
}
结语

以上是 Java OOP 设计模式的介绍,不同的设计模式在不同的场景下有不同的使用效果,请根据实际情况灵活使用。