HIT软件构造-Java设计模式

目录

1.创建型模式(Creational patterns)

2.结构型模式(Structural patterns)

(1) 适配器模式(adapter)

(2) 装饰器模式(Decorator)

3.行为类模式(Behavioral patterns)

(1) 策略模式(Strategy)

(2) 模板模式(Template)

(3) 迭代器模式(Iterator)

(4) 访问者模式(Visitor)


1.创建型模式(Creational patterns)

工厂方法模式: 当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体创建的实例时,用工厂方法。定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个类的实例化延迟到其子类。

1.	// 工厂模式  
2.	// 先建立工厂总接口,定义生产物品总接口的抽象方法  
3.	// 再实现子类工厂实例类,重写生产具体物品的方法  
4.	  
5.	public class FactoryPattern{  
6.	    public static void main(String[] args){  
7.	        new AppleFactory().makeObject().method(); 
            new GrapeFactory().makeObject().method();  
8.	    }  
9.	}  
10.	  
11.	// 工厂总接口  
12.	interface Factory{  
13.	    Fruit makeObject();  
14.	}  
15.	  
16.	// 苹果工厂子类接口  
17.	class AppleFactory implements Factory{  
18.	    @Override  
19.	    public Apple makeObject(){  
20.	        return new Apple();  
21.	    }  
22.	}  
23.	  
24.	// 葡萄工厂子类接口  
25.	class GrapeFactory implements Factory{  
26.	    @Override  
27.	    public Grape makeObject(){  
28.	        return new Grape();  
29.	    }  
30.	}  
31.	  
32.	// 水果总接口  
33.	interface Fruit{  
34.	    void method();  
35.	}  
36.	  
37.	// 苹果子类  
38.	class Apple implements Fruit{  
39.	    @Override  
40.	    public void method(){  
41.	        System.out.println("苹果");  
42.	    }  
43.	}  
44.	  
45.	// 葡萄子类  
46.	class Grape implements Fruit{  
47.	    public void method(){  
48.	        System.out.println("葡萄");  
49.	    }  
50.	}  

2.结构型模式(Structural patterns)

(1) 适配器模式(adapter)

当内部实现和客户端要求不匹配时,将某个类/接口转换为client期望的其他形式, 通过增加一个接口,将已存在的子类封装起来,client面向接口编程,从而隐藏了具体子类。

用电器来打个比喻:有一个电器的插头是三脚的,而现有的插座是两孔的,要使插头插上插座,我们需要一个插头转换器,这个转换器即是适配器。

具体解决方法:

// 适配器模式  
// 问题: 客户端要展示一个向量,需要起点的坐标和长度  
// 但是现在只提供了两点的坐标,且不能改动客户端的代码(display的参数)  
// *** 可以提供一个接口适配器Shape  
public class AdapterPattern{  
    public static void main(String[] args){  
        display(1, 2, 23, 1);  
    }  
  
    public static void display(double x1, double y1, double angle, double len){  
        Vector vector = VectorDisplay.make(x1, y1, angle, len);  
        vector.display(x1, y1, angle, len);  
    }  
}  
  
class Vector implements VectorDisplay{  
    double x1, y1;  
    double x2, y2;  
  
    public Vector(double x1, double y1, double x2, double y2){  
        this.x1 = x1;  
        this.x2 = x2;  
        this.y1 = y1;  
        this.y2 = y2;  
    }  
  
    public void display(double x1, double y1, double x2, double y2){  
        System.out.println("这就实现了鸭");  
    }  
  
    // 重写display2方法  
    @Override  
    public void display2(double x1, double y1, double angle, double len){  
        // 调用了转接口  
        display(x1, y1, y1 + len * Math.cos(angle), x1 + len * Math.sin(angle));  
    }  
}  
  
interface VectorDisplay{  
    // 静态工厂  
    static Vector make(double x1, double y1, double angle, double len){  
        return new Vector(x1, y1,y1 + len * Math.cos(angle), x1 + len * Math.sin(angle));  
    }  
  
    // 转化器,满足客户端的display2方法  
    void display2(double x1, double y1, double angle, double len);  
}  

(2) 装饰器模式(Decorator)

装饰器模式,顾名思义,就是在类上添加装饰,允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

// 装饰器模式,特点是构造方法参数是接口,继承接口又委托接口,构造时把参数接口赋值给自己接口(好绕口啊)  
// 参数接口相当于基础功能,然后在下面添加新的功能  
public class DecoratorPattern{  
    public static void main(String[] args){  
        Stack s1 = new ArrayStack();  
        Stack s2 = new ClearStack(new LockStack(s1));  
    }  
}  
  
// 总接口,有子类公用方法push, pop, size  
interface Stack{  
    List<Integer> list = new ArrayList<>();  
  
    default void push(int data){  
        list.add(data);  
    }  
  
    default int pop(){  
        if(list.isEmpty())  
            System.exit(0);  
        int data = list.get(list.size() - 1);  
        list.remove(list.size() - 1);  
        return data;  
    }  
  
    default int size(){  
        return list.size();  
    }  
}  
  
// 普通线性栈  
class ArrayStack implements Stack{}  
  
// 装饰类,重要作用:可装饰性(构造方法的接口就是装饰)  
abstract class StackDecorator implements Stack{  
    // 子类可以访问父类这个委托的接口,所以用protect  
    protected final Stack stack;  
  
    // 构造方法:传入基础接口  
    public StackDecorator(Stack stack){  
        this.stack = stack;  
    }  
}  
  
// 可锁栈,在实现接口的基础上装饰了一些其他功能  
class LockStack extends StackDecorator{  
    // 所有的装饰类都要继承抽象类StackDecorator  
    private boolean lock = true;  
  
    public LockStack(Stack stack){  
        super(stack);  
    }  
  
    // 以下是这个类需要新增加的功能  
    @Override  
    public void push(int data){  
        if(! lock)  
            super.push(data);  
        else  
            System.out.println("已上锁,不能操作");  
    }  
  
    @Override  
    public int pop(){  
        if(! lock)  
            return super.pop();  
        else{  
            System.out.println("已上锁,不能操作");  
            return list.get(size() - 1);  
        }  
    }  
  
    public void unlock(){  
        lock = true;  
    }  
  
    public void lock(){  
        lock = true;  
    }  
}  
  
// 可清空栈  
class ClearStack extends StackPattern{  
    public ClearStack(Stack stack){  
        super(stack);  
    }  
  
    public void clear(){  
        while(! list.isEmpty())  
            list.remove(0);  
    }  
}  

3.行为类模式(Behavioral patterns)

(1) 策略模式(Strategy)

有多种不同的算法来实现同一个任务,但需要client根据需要 动态切换算法,而不是写死在代码里, 为不同的实现算 法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例。

/* 策略模式 
   实现一个策略总接口 
   用不同的策略子类实现它,重写方法 
   使用某种策略时的参数是接口,传入多态对象(多态) 
 */  
public class StrategyPattern{  
    public static void main(String[] args){  
        Strategy strategy = new Method1();  
        Solute solute = new Solute();  
        solute.solute(strategy);  
    }  
}  
  
// 策略总接口  
interface Strategy{  
    void method();  
}  
  
// 策略方法1  
class Method1 implements Strategy{  
    @Override  
    public void method(){  
        System.out.println("方法1");  
    }  
}  
  
// 策略方法2  
class Method2 implements Strategy{  
    @Override  
    public void method(){  
        System.out.println("方法2");  
    }  
}  
  
// 解决问题的实例类  
// 只管解决问题,以何种方式解决,取决于使用的多态类  
class Solute{  
    public void solute(Strategy strategy){  
        strategy.method();  
    }  
} 

(2) 模板模式(Template)

用重写而不是委托实现共性操作,通常是同性的操作多,不同性的操作少。一个抽象类公开定义了执行它的方法的方式/模板,它的子类可以按需要重写方法实现,共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现,但调用将以抽象类中定义的方式进行。

// 模板模式  
// 按照模板往下写,一个模板可以被多个类继承,只能继承不能委托  
public class TemplatePattern{  
    public static void main(String[] args){  
        Doing study = new Study();  
        study.doing();  
        Doing play = new Play();  
        play.doing();  
    }  
}  
  
// 总抽象类  
abstract class Doing{  
    final void doing(){  
        start();  
        process();  
        end();  
    }  
  
    abstract void start();  
    abstract void process();  
    abstract void end();  
}  
  
// 实现抽象类的一个实例类  
class Play extends Doing{  
    @Override  
    void start(){  
        System.out.println("开始玩");  
    }  
  
    @Override  
    void process(){  
        System.out.println("正在玩");  
    }  
  
    @Override  
    void end(){  
        System.out.println("还玩?不玩了");  
    }  
}  
  
// 实现抽象类的另一个实例类  
class Study extends Doing{  
    @Override  
    void start(){  
        System.out.println("开始学习");  
    }  
  
    @Override  
    void process(){  
        System.out.println("正在学习");  
    }  
  
    @Override  
    void end(){  
        System.out.println("学个屁,不学了");  
    }  
}  

(3) 迭代器模式(Iterator)

迭代器模式是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。 

// 迭代器模式  
public class IteratorPattern{  
    public static void main(String[] args){  
        MyList list = new MyList();  
        MyIterator iterator = list.getIterator();  
        while(iterator.hasNext())  
            System.out.println(iterator.next());  
    }  
}  
  
// 迭代器接口  
interface MyIterator{  
    boolean hasNext();  
    String next();  
}  
  
// 容器接口  
interface Contain{  
    MyIterator getIterator();  
}  
  
// 数组接口  
class MyList implements Contain{  
    String[] arr = new String[]{"1", "4", "3", "2"};  
    // 获取迭代器  
    @Override  
    public MyIterator getIterator(){  
        // 返回内部数组  
        return new InnerList();  
    }  
  
    // 用一个内部数组类实现迭代器接口,重写  
    class InnerList implements MyIterator{  
        private int index = 0;  
  
        @Override  
        public boolean hasNext(){  
            return index < arr.length;  
        }  
  
        @Override  
        public String next(){  
            index ++;  
            return arr[index - 1];  
        }  
    }  
}  

(4) 访问者模式(Visitor)

使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

// Visitor模式  
public class VisitorModel{  
    public static void main(String[] args){  
        Visitor visitorA = new VisitA(); // 访问者A  
        Visitor visitorB = new VisitB(); // 访问者B  
        // 被访问者只需要一个就行了,因为不同的是访问者,他们决定访问策略  
        VisitObject visitObject = new VisitObject(1, 2); // 被访问者  
          
        visitObject.accept(visitorA);  
        visitObject.accept(visitorB);  
    }  
}  
  
// 被访问的类  
class VisitObject{  
    int a;  
    int b;  
  
    public VisitObject(int a, int b){  
        this.a = a;  
        this.b = b;  
    }  
  
    // 被访问者要提供接受访问者的方法,参数为访问者接口  
    // 传进来的对象自然是多态  
    public void accept(Visitor visitor){  
        visitor.visit(this);  
    }  
}  
  
// 访问者接口  
interface Visitor{  
    // 访问者访问被访问者  
    public void visit(VisitObject a);  
}  
  
// 被访问者实现类,说明具体要访问那个对象  
class VisitA implements Visitor{  
    @Override  
    public void visit(VisitObject visitObject){  
        System.out.println(visitObject.a);  
    }  
}  
  
class VisitB implements Visitor{  
    @Override  
    public void visit(VisitObject visitObject){  
        System.out.println(visitObject.b);  
    }  
}  

有问题欢迎大家指出~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值