Java基础入门菜鸟入门学习第二十一天——Java面向对象(十五)

Java面向对象——设计模式(一)

5.6工厂模式

5.6.1工厂模式定义

  • 针对于一些比较复杂的对象,可能创建时是很麻烦的一个过程,而且创建的花销也比较大。内部创建的逻辑较为复杂,我们通过工厂实现了内部的复杂逻辑,对于调用者而言只需要针对工厂操作即可,无需关系内部的具体逻辑,降低了调用者的复杂度以及学习成本,对于实际的被调用者而言提高了安全度。

5.6.2工厂模式分类

i.简单工厂

代码演示:

package com.mage.oop07.part;
public class Car{
    int speed;
    public Car(){
        
    }
    public void run(){
        
    }
    public void setSpeed(int speed){
        this.speed=speed;
    }
    public int getSpeed() {
    	return speed;
    }
}
public class Audi extends Car{
    private String type;
    Audi(){
        
    }
    public void run(){
        System.out.println("奥迪以每秒"+speed+"的速度");
    }
    public String getType(){
        return this.type;
    }
    public void setType(String type){
        this.type=type;
    }
}
public class AuTuo extends Car{
    private String type;
    AuTuo(){
        
    }
    public void run(){
        System.out.println("奥拓以每秒"+speed+"的速度前行");
    }
    public String getType(){
        return type;
    }
    public void setType(String type){
        this.type=type;
    }                
}
public class CarFactory{
    public static Car getInstance(String carType){
        Car car=null;
        if("奥迪".equals(carType)){
            car=new Audi();
        }else if("奥拓".equals(carType)){
            car=new AuTuo();
        }
        return car;
    }
}
package com.mage.oop07.part.test;
public class Test{
     public static void main(String[] args){
        Car c=CarFactory.getInstance("奥拓");
        c.setSpeed(20);
        c.run();
    }
}                           
执行结果:
奥拓以每秒20的速度前行
  • 简单工厂在一定程度上确实降低来开发复杂度以及调用难度。
  • 对于代码的拓展支持没有那么好。
  • 在所有设计模式中,都需要支持6大原则:开闭原则——对于拓展开放,对于修改关闭。
ii.模板方法

代码演示:

public class Test{
	public static void main(String[] args){
		DrinkFlow dc=new DrinkCoff();
		dc.flow();
		System.out.println("================");
		DrinkFlow dt=new DrinkTea();
		dt.flow();
	}
}
public abstract class DrinkFlow{
	private void boil(){
        System.out.println("烧水");
	}
	private void pour(){
        System.out.println("倒水");
	}
	abstract void stir();
	private void drink(){
        System.out.println("干了");
	}
	public void flow(){
		boil();
        pour();
        stir();
        drink();
	}
}
public class DrinkCoff extends DrinkFlow{
	public void stir(){
        System.out.println("搅拌");
	}
}
public class DrinkTea extends DrinkFlow{
	public void stir(){
        System.out.println("冲泡");
	}
}
烧水
倒水
搅拌
干了
================
烧水
倒水
冲泡
干了

  • 方法模板就是将相同的业务功能提取到父类中,将相同的业务流程也编写在父类中。
  • 将核心业务逻辑或者是算法逻辑延迟到子类中编写。
  • 通过不同的对象调用相同的功能,最后的结果也是不同的。
iii.策略模式(用接口的实现多态)
有一个学生的数组,查看学生数组中学生年龄在12-23岁之间的学生信息。
有一个学生的数组,查看学生数组中学生分数在33-70岁之间的学生信息
public class Student {
	private int id;
	private String name;
	private int age;
	private int score;
	public Student() {
		
	}
	public Student(int id,String name,int age,int score) {
		this.id=id;
		this.name=name;
		this.age=age;
		this.score=score;
	}
	public void setScore(int score) {
		this.score=score;
	}
	public int getScore() {
		return score;
	}
	public void setAge(int age) {
		this.age=age;
	}
	public int getAge() {
		return age;
	}
	public String toString() {
		return name+" "+id+" "+age+" "+score;
	}	
}
public class Demo1{
	public static void main(String[] args) {
		//声明一个学生数组,存放5个学生信息
		Student stu1=new Student(1,"张山",12,60);
		Student stu2=new Student(2,"张三",15,66);
		Student stu3=new Student(3,"李四",34,70);
		Student stu4=new Student(4,"小二",49,80);
		Student stu5=new Student(5,"王二",18,90);
		//声明一个学生数组  存储学生对象
		Student[] stus=new Student[] {stu1,stu2,stu3,stu4,stu5};
		FilterScore(stus);
		FilterAge(stus);
	}
	//编写一个方法将学生数组中的学生信息进行过滤,取出符合要求的对象
	public static void FilterScore(Student[] stus) {
		//判断获取的每一个对象是否符合要求
		for(int i=0;i<stus.length; i++) {
			if(stus[i].getScore()>=33&&stus[i].getScore()<=70) {
				System.out.println(stus[i]);
			}
		}
	}
	public static void FilterAge(Student[] stus) {
		for(int i=0;i<stus.length;i++) {
			if(stus[i].getAge()>=20&&stus[i].getAge()<90) {
				System.out.println(stus[i]);
			}
		}
	}
}
  • 对于上述的内容而言,不满足后期的业务扩展所带来的问题。如果出现新的需求需要修改代码。也就意味着不满足开闭原则。

统一接口:满足创建的实现类对象可以传入到形式参数中去

public interface Filter1 {
	public abstract void filter(Student[] stus);
}

编写对应的实现类

public class FilterScore implements Filter1{
	@Override
	public void filter(Student[] stus) {
		for(int i=0;i<stus.length; i++) {
			if(stus[i].getScore()>=33&&stus[i].getScore()<=70) {
				System.out.println(stus[i]);
			}
		}
	}
}

public class FilterAge implements Filter1{
	@Override
	public void filter(Student[] stus) {
		for(int i=0;i<stus.length;i++) {
			if(stus[i].getAge()>=20&&stus[i].getAge()<90) {
				System.out.println(stus[i]);
			}
		}
	}
}

策略模式的代码

public class Demo1{
	public static void main(String[] args) {
		//声明一个学生数组,存放5个学生信息
		Student stu1=new Student(1,"张山",12,60);
		Student stu2=new Student(2,"张三",15,66);
		Student stu3=new Student(3,"李四",34,70);
		Student stu4=new Student(4,"小二",49,80);
		Student stu5=new Student(5,"王二",18,90);
		//声明一个学生数组  存储学生对象
		Student[] stus=new Student[] {stu1,stu2,stu3,stu4,stu5};
		FilterScore filter=new FilterScore();
		filter(filter,stus);
        FilterAge a=new FilterAge();
		filter(a,stus);
	}
    //策略模式的代码重点
	public static void filter(Filter1 filter,Student[] stus) {
        //Filter filter = new FilterScore()
		filter.filter(stus);//多态
	}
}
执行结果:
张山 1 12 60
张三 2 15 66
李四 3 34 70
李四 3 34 70
小二 4 49 80
  • 以上代码的核心问题主要是:用户的需求是不断发生改变的。导致类的个数不断增加,后期维护的成本增加,再加上某些类可能只会被使用一次,后期优化会用到匿名内部类来优化(内部类会给优化的方法)

你可能感兴趣的:(java学习笔记)