一、UML

1、聚合(contains空心菱形)

整体与部分的关系(部分脱离整体可独立存在)。Java代码:部分对象可为整体类中的构造、set方法的参数

public class Car
{
    private Engine engine;
    public void Car(Engine engine){
        this.engine=engine;
    }
    public  void setEngine(Engine engine){
        this.engine=engine;
    }
}
public class Engine{}
2、组合(has实心菱形)

整体与部分的关系(部分不可脱离整体独立存在)。Java代码:在整体类的构造方法中创建部分的实例。

public class Head {
    public void Head(){
        Mouth mouth=new Mouth();
    }
}
public class Mouth(){}
3、依赖(虚线箭头)

一种使用关系。Java代码:在实用类中的方法中调用被使用类的实例方法。

public class Driver {
    public void drive(Car car){
        car.move();
    }
}
public class Car{
    public void move(){}
}
4、泛化(实线空心三角形)

也就是继承关系。Java代码:父类中有属性和方法,两个子类有各自的属性和方法(extends)。

public class Person {
    protected String name;
    protected int age;
    public void move(){}
    public void say(){}
}
public class student extends Person{
    private String studentNo;
    public void study(){}
}
public class teacher extends  Person{
    private String teacherNo;
    public  void teach(){}
}
5、接口与实现(虚线空心三角形)

接口的类图中只有方法,属性是空的。Java代码:主要侧重于重写接口中的方法。

public interface Vehicle {
    public void move();
}
public class Ship implements Vehicle{
    public void  move(){
        System.out.println("ship move");
    }
}public class Car implements Vehicle{
    public void  move(){
        System.out.println("Car move");
    }
}

二、设计模式

模式定义:模式是在特定环境下人们解决某类重复问题的一套成功或有效的解决方案

模式的基本结构:image-20211208210154897

设计模式定义:是在特定环境下为解决某一通用软件设计问题提供的一套定制的解决方案,该方案描述了对象和类之间的相互作用。

设计模式关键元素:模式名称、问题、解决方案、效果。

设计模式优点: (1)设计模式融合了众多专家的经验,并以一种标准的形势供广大开发人员使用.

​ (2)设计模式使人们可以更简单、方便的复用成功的设计和体系结构。

​ (3)设计模式使得设计方案更加灵活,且易与修改

​ (4)设计模式的使用将提高软件系统的开发效率和软件质量。

​ (5)设计模式有助于初学者更深入地理解面向对象思想。

1、单例模式

​ 定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例

​ Java代码:一个私有的构造函数、一个静态私有的成员变量、一个静态公有的工厂方法(检查实例的存在并实例化自己)

​ 角色:单例类

​ 优点:(1)单例模式提供了对唯一实例的受控访问。因为单例模式封装了他的唯一实例,所以他可以控制客户怎样以及何时访问它。

​ 优点:(2)由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式可以提 高系统的性能

​ 优点:(3)允许可变数目的实例。

​ 缺点:(1)由于单例模式没有抽象层,因此单例类的拓展有很大的困难。

​ 缺点:(2)单例类的职责过重,在一定程度上违反了单一职责原则。因为单例类即提供了业务方法,又提供了创建对象的方法,将对 象的创建和对象本身的功能耦合在一起

​ 缺点:(3)现在很多面向对象语言的运行环境都提供了自动垃圾回收术,因此如果实例化的共享对象长时间不被利用,系统会认为他 是垃圾,会自动销毁并回收资源。

image-20211208183452556
public class LoadBalance {
    //私有静态成员变量
    private static LoadBalance instance=null;
    //服务器集合
    private List servelist=null;
    //私有构造函数
    private void LoadBalance(){
        servelist=new ArrayList<Object>();
    }
    public static LoadBalance getLoadBalance(){
        if(instance==null){
            instance=new LoadBalance();
        }
        return instance;
    }
    public void addServe(String serve){
        servelist.add(serve);
    }
    public void removeServe(String serve){
        servelist.remove(serve);
    }
    public String getServer(){
        Random random=new Random();
        int i=random.nextInt(servelist.size());
        return (String)servelist.get(i);
    }
}
public class Clientdl {
    public static void main(String[] args) {
        LoadBalance loadBalance1,loadBalance2,loadBalance3,loadBalance4;
        loadBalance1=new LoadBalance();
        loadBalance2=new LoadBalance();
        loadBalance3=new LoadBalance();
        loadBalance4=new LoadBalance();
        if(loadBalance1==loadBalance2&&loadBalance2==loadBalance3&&loadBalance3==loadBalance4){
            System.out.println("服务器负载均衡具有唯一性");
        }
        loadBalance1.addServe("Server 1");
        loadBalance1.addServe("Server 2");
        loadBalance1.addServe("Server 3");
        loadBalance1.addServe("Server 4");

        for(int i=0;i<10;i++){
            String server=loadBalance1.getServer();
            System.out.println("分发请求至服务器:"+server);
        }
    }
}
2、适配器模式

定义:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

结构:image-20211209153013955

Java代码:目标接口:内涵两个目标功能;适配器类:创建两个适配者类对象,两个方法分别用对象调用适配者类的功能

​ 适配者类:功能的具体实现;

优点:(1)将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。

优点:(2)增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中

优点;(3)完全符合开闭原则。

缺点:(1)对于不支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配者。

缺点:(2)适配者类不能为最终类。

缺点:(3)在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定的局限性。

image-20211209153608055

抽象操作类:目标接口

public interface DataOperation {
public int[] sort(int array[]); //排序  
public int search(int array[],int key); //查找  
}

操作适配器:适配器

public class OperationAdapter implements DataOperation {
    private QuickSort sortObj; // 定义适配者QuickSort对象
    private BinarySearch searchObj; // 定义适配者BinarySearch对象

    public OperationAdapter() {
        sortObj = new QuickSort();
        searchObj = new BinarySearch();
    }

    public int[] sort(int array[]) {
        return sortObj.quickSort(array); // 调用适配者类QuickSort的排序方法
    }

    public int search(int array[], int key) {
        return searchObj.binarySearch(array, key); // 调用适配者类BinarySearch的查找方法
    }

}

快速排序类:适配者

public class QuickSort {
    public int[] quickSort(int array[]) {  
        sort(array,0,array.length-1);  
        return array;  
    }  
    public void sort(int array[],int p, int r) {  
        int q=0;  
        if(p<r) {  
            q=partition(array,p,r);  
            sort(array,p,q-1);  
            sort(array,q+1,r);  
        }  
    }  
    public int partition(int[] a, int p, int r) {  
        int x=a[r];  
        int j=p-1;  
        for (int i=p;i<=r-1;i++) {  
            if (a[i]<=x) {  
                j++;  
                swap(a,j,i);  
            }  
        }  
        swap(a,j+1,r);  
        return j+1;   
    }  
    public void swap(int[] a, int i, int j) {     
        int t = a[i];     
        a[i] = a[j];     
        a[j] = t;     
    }  
}

二分查找类:适配者

public class BinarySearch {
    public int binarySearch(int array[], int key) {
        int low = 0;
        int high = array.length - 1;
        while (low <= high) {
            int mid = (low + high) / 2;
            int midVal = array[mid];
            if (midVal < key) {
                low = mid + 1;
            } else if (midVal > key) {
                high = mid - 1;
            } else {
                return 1; // 找到元素返回1
            }
        }
        return -1; // 未找到元素返回-1
    }
}
3、装饰模式

定义:动态地给一个对象增加一些额外的职责。就拓展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。

结构:image-20211209144914295

角色:抽象构件(Component)、具体构件(ConcreteComponent)、抽象装饰类(Decorator)、具体装饰类(ConcreteDecorator)

Java代码:一个抽象构建类,三个具体构建类,一个抽象装饰类(有一个私有的component对象),两个具体抽象类

优点:(1)拓展对象功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加。

优点:(2)可以通过一种动态的方式来拓展一个对象的功能,

优点:(3)可以对一个对象进行多次装饰。

优点:(4)符合开闭原则。

缺点:(1)在使用装饰模式将产生很多小对象,大量小对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能。

缺点:(2)比继承更加易于出错,排错也更加困难,对于多次装饰的对象,在调试时寻找错误较为烦琐。

image-20211210115131399
package Decorator;
//抽象界面构件类:
public abstract class Component {
    public abstract void display();
}
//具体构件类1:
public class Window extends Component {
    public void display(){
        System.out.println("显示窗体");
    }
}
//具体构件类2:
public class TextBox extends Component {
    public void display(){
        System.out.println("显示文本框");
    }
}
//具体构件类3:
public class ListBox extends Component {
    public void display(){
        System.out.println("显示列表框");
    }
}
//抽象装饰类
public class ComponentDecorator extends Component{
    private Component component;
    public ComponentDecorator(Component component){
        this.component=component;
    }
    public void display(){
        component.display();
    }
}
//具体装饰类1:
public class ScrollBarDecorator extends ComponentDecorator {
    public ScrollBarDecorator(Component component){
        super(component);
    }
    public void display(){
        this.setScrollBar();
        super.display();
    }
    public void setScrollBar(){
        System.out.println("为构件增加滚动条");
    }
}
//具体装饰类2:
public class BlackBorderDecorator extends ComponentDecorator {
    public void display(){
        this.setBlackBorder();
        super.display();
    }
    public BlackBorderDecorator(Component component){
        super(component);
    }
    public void setBlackBorder(){
        System.out.println("为构件增加黑色色边框");
    }
}
//测试:
public class Client {
    public static void main(String[] args) {
        Component component,componentSB;
        component=new Window();
        componentSB=new ScrollBarDecorator(component);
        componentSB.display();
    }
}

4、观察者模式

定义:定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时其相关依赖对象皆都得通知并自动更新。

结构:image-20211211175532478

角色:目标(Subject)、具体目标(ConcreteSubject)、观察者(Observer)、具体观察者(ConcreteObserver)

Java代码:四个观察者类(doSomeThing),一个sensor(一个数组,一个tem,设置tem,add观察者类实例方法,遍历数组方法,设置tem,判断message满足调用遍历数组方法,不满足调用正常)

优点:(1)实现表现层和数据逻辑层的分离

优点:(1)在观察对象和观察者之间建立一个抽象的耦合

优点:(1)支持广播通信

优点:(4)符合开闭原则

缺点:(1)如果有很多间接观察者,所有的观察者收到通知的时间会延长

缺点:(2)如果观察者和观察目标之间存在循环依赖,可能会导致系统崩溃

缺点:(3)观察者不能观察目标对象是怎么变化的,只知道发生了变化

image-20211211182756848
//接口
public interface AlarmListener {
    public void doSomeThing();//警示灯闪烁,报警器发出警报,安全逃生门将自动开启、个热门自动关闭
}
//设备1
public class geDoor implements AlarmListener {
    public void close(){
        System.out.println("隔热门将自动关闭");
    }

    @Override
    public void doSomeThing() {
        close();
    }
}
//设备2
public class Light implements AlarmListener {
    @Override
    public void doSomeThing() {
        light();
    }
    public void light(){
        System.out.println("警示灯闪烁");
    }
}
//设备3
public class Safe implements AlarmListener {
    @Override
    public void doSomeThing() {
        open();
    }
    public void open(){
        System.out.println("安全门将自动开启");
    }
}
//设备4
public class Voice implements AlarmListener {
    @Override
    public void doSomeThing() {
        alarm();
    }
    public void alarm(){
        System.out.println("报警器发出警报");
    }
}
//观察目标
public class Sensor {
    private double tem;
    private ArrayList array=new ArrayList();
    public void add(AlarmListener listener){
        this.array.add(listener);
    }
    public void testAlarm(){
        for(AlarmListener obj:array){
            obj.doSomeThing();
        }
    }
    public void setTem(double tem){
        this.tem=tem;
    }
    public void sendMessage(){
        if(this.tem>40.0){
            testAlarm();
        }else{
            System.out.println("====正常工作====");
        }
    }
}
//测试
public class Client {
    public static void main(String[] args) {
        Voice voice=new Voice();
        Light light=new Light();
        geDoor geDoor=new geDoor();
        Safe safe=new Safe();
        Sensor sensor=new Sensor();
        //添加设备
        sensor.add(voice);
        sensor.add(light);
        sensor.add(geDoor);
        sensor.add(safe);
        //响应
        //正常
        sensor.setTem(30.0);
        sensor.sendMessage();
        //不正常
        sensor.setTem(50.0);
        sensor.sendMessage();
    }
}
5、组合模式

定义:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。

结构:image-20211211195601776

角色:抽象构件(Component)、叶子构件(Leaf)、容器构件(Composite)

java代码:

优点(1):清楚定义分层次的复杂对象

优点(2):简化了客户端代码

优点(3):符合开闭原则

优点(4):对树形结构的控制非常简单

缺点(1):增加新构件很难对容器内的构件类型进行限制

image-20211211203216230
//抽象构建类
public abstract  class AbstractFile {
    public  abstract void add(AbstractFile file);
    public  abstract void remove(AbstractFile file);
    public  abstract AbstractFile getChild(int i);
    public  abstract void killVirus();
}
//叶子构件类1
public class ImageFile extends AbstractFile {
    private  String name;
    public ImageFile(String name){
        this.name=name;
    }
    public void add(AbstractFile file){
        System.out.println("对不起,不支持该方法");

    }
    public void remove(AbstractFile file){
        System.out.println("对不起,不支持该方法");
    }
    public  AbstractFile getChild(int i){
        System.out.println("对不起,不支持该方法");
        return null;
    }
    public  void killVirus(){
        System.out.println("---对图像文件"+name+"进行杀毒");
    }

}
//叶子构件类2
public class TextFile extends AbstractFile {
    private  String name;
    public TextFile(String name){
        this.name=name;
    }
    public void add(AbstractFile file){
        System.out.println("对不起,不支持该方法");

    }
    public void remove(AbstractFile file){
        System.out.println("对不起,不支持该方法");
    }
    public  AbstractFile getChild(int i){
        System.out.println("对不起,不支持该方法");
        return null;
    }
    public  void killVirus(){
        System.out.println("---对文本文件"+name+"进行杀毒");
    }
}
//叶子构件类3
public class VideoFile extends AbstractFile{
    private  String name;
    public VideoFile(String name){
        this.name=name;
    }
    public void add(AbstractFile file){
        System.out.println("对不起,不支持该方法");

    }
    public void remove(AbstractFile file){
        System.out.println("对不起,不支持该方法");
    }
    public  AbstractFile getChild(int i){
        System.out.println("对不起,不支持该方法");
        return null;
    }
    public  void killVirus(){
        System.out.println("---对视频文件"+name+"进行杀毒");
    }
}
//容器构件类
public class Folder extends AbstractFile {
    private ArrayList filelist=new ArrayList();
    private String name;
    public void Folder(String name){
        this.name=name;
    }
    public void add(AbstractFile file){
        filelist.add(file);
    }
    public  void remove(AbstractFile file){
        filelist.remove(file);
    }
    public AbstractFile getChild(int i){
        return (AbstractFile)filelist.get(i);
    }
    public void killVirus() {
        System.out.println("对文件夹" + name + "进行杀毒");

        for (Object obj : filelist) {
            ((AbstractFile) obj).killVirus();
        }
    }
}
//测试类
public class Client {
    public static void main(String[] args) {
        AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;
        folder1=new Folder("sunny的资料");
        folder2=new Folder("图像文件");
        folder3=new Folder("视频文件");
        folder4=new Folder("文本文件");

        file1=new ImageFile("小龙女。jpg");
        file2=new ImageFile("张无忌.jpj");
        file3=new TextFile("九阴真经。txt");
        file4=new TextFile("葵花宝典。txt");
        file5=new VideoFile("笑傲江湖");

        folder2.add(file1);
        folder2.add(file2);
        folder3.add(file3);
        folder3.add(file4);
        folder4.add(file5);
        folder1.add(folder2);
        folder1.add(folder3);
        folder1.add(folder4);

        folder1.killVirus();
    }
}

更多推荐