一.设计模式概述
A:概述
设计模式(Design pattern)是一套反复被使用的,多数人知晓的,经过分类编目的,代码设计经验的总结。
使用设计模式的目的:
使用设计模式,是为了可重复使用代码,让代码更容易被其他人理解,保证代码的可靠性以及代码的结构清晰。
B:分类
创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
行为型模式(对象的功能): 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
结构型模式(对象的组成): 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器 模式、状态模式、策略模式、职责链模式、访问者模式
二.简单工厂模式概述和使用
A:简单工厂模式概述: 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
B:优点: 实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,
而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态 的增加产品。明确了类的职责
C:缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,
就需要不断的修改工厂类,不利于后期的维护
D:案例演示
分析:如果我们需要多次创建相同的对象那么每次都要去,new 对象,这样是必要耗费资源的,我们使用工厂类,把所有的创建对象的代码,都由工厂去做,客户端只需要说明你要什么需求,这样结构就比较清晰,并且好管理,具体实现如下
有两种方式
a:在工厂类中,给每一个可能用到的类创建一个静态方法来创建对象,如果在客户端有需要,直接调用这个静态方法即可
b:在工厂类创建一个创建对象的方法,有参,参数指明客户端的需求,然后进行判断,根据需要匹配,返回所要的对象。
案例演示如下:
工厂类:
public class AnimalFactory {
private AnimalFactory() {
super();
}
// public static Animal createDog() {
// return new Dog();
// };
// public static Animal createCat() {
// return new Cat();
// }
public static Animal creatAnimal(String s) {
if(s.equals("dog")) {
return new Dog();
}else if(s.equals("Cat")){
return new Cat();
}
return null;
}
}
父类和两个子类:
public class Animal {
public void eat() {
};
}
public class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal{
public void eat() {
System.out.println("狗吃肉");
}
}
测试类:
public class Test {
public static void main(String[] args) {
//工厂模式,用一个工厂类专门来生产产品
//方法一
// Animal createDog = AnimalFactory.createDog();
// createDog.eat();
// Animal createCat = AnimalFactory.createCat();
// createCat.eat();
//方法二
//通过传名称,直接创建
Animal dog1 = AnimalFactory.creatAnimal("dog");
dog1.eat();
Animal cat = AnimalFactory.creatAnimal("Cat");
cat.eat();
}
测试结果:
狗吃肉
猫吃鱼
E:抽象工厂概述和使用
a:工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现
b:好处
客户端再也不需要对象的创建,具体的创建对象的工作由具体的类去实现,如果客户端想要添加一个新的对象,那么无需改动已有的代码,只需要添加一个具体的类和一个具体的工厂实现类,后期好维护增强了系统的扩展性。
c:弊端
使用抽象工厂类的缺点是增加了代码量,需要额外的写代码。
d:案例演示
在此只用一个小狗的案例做示范
一个接口,抽象工厂类
public interface AnimalFactory {
public abstract Aniaml creatAnimal();
}
一个父类
public abstract class Aniaml {
public abstract void eat();
}
一个狗狗工厂类
public class DogFactory implements AnimalFactory{
@Override
public Aniaml creatAnimal() {
return new Dog();
}
}
一个狗类
public class Dog extends Aniaml{
@Override
public void eat() {
System.out.println("小狗喜欢吃肉");
}
}
测试类
public class Test {
public static void main(String[] args) {
AnimalFactory dogFactory = new DogFactory();
Aniaml aniaml=dogFactory.creatAnimal();
aniaml.eat();
AnimalFactory CatFoctiry=new CatFactory();
Aniaml aniaml2 = CatFoctiry.creatAnimal();
aniaml2.eat();
}
}
如果此时客户又想添加一个新的对象,那么不用改动源代码,只需在一个类和该类的工厂实现类
具体如下:
public class Cat extends Aniaml{
@Override
public void eat() {
System.out.println("小花猫喜欢吃鱼");
}
}
public class CatFactory implements AnimalFactory {
@Override
public Aniaml creatAnimal() {
return new Cat() ;
}
}
三.单例设计模式
A:单例设计模式概述和使用
a:设计思想就是,让内存中存在一个对象
b:问:怎么实现单例设计模式?
答:
*构造私有化
*本身提供一个对象
*通过公共的方法让外界访问
c:案例演示之饿汉式
测试类:
public class Test {
public static void main(String[] args) {
Student student1 = Student.getStudent();
Student student2 = Student.getStudent();
System.out.println(student1==student2);
}
}
public class Student {
//第一步:私有化构造
private Student() {
super();
}
//第二步:在类中自己创建一个对象
private static Student student=new Student();
//第三步:提供一个静态的公共的方法,返回这个学生对象
public static Student getStudent() {
return student;
}
}
注:单例模式之饿汉式 体现是一种延迟加载的思想
案例演示懒汉式
分析:懒汉式就是把对象的创建放到了方法中,当有需要时再创建,而不是直接创建。
具体实现如下:
public class Test {
//懒汉式,把对象创建放到需要时再创建。
public static void main(String[] args) {
Student student1 = Student.getStudent();
Student student2 = Student.getStudent();
System.out.println(student1==student2);//true
}
}
public class Student {
//第一步 私有化构造
private Student() {
super();
}
//第二步 定义 一个学生对象
private synchronized static Student student=null;
//第三步 提供公共的静态方法 只适用于懒汉式
public static Student getStudent() {
if(student==null) {
student=new Student();
}
return student;
}
}
四.Runtime类
A:Runtime类概述
概述:每一个java应用程序都有其自己的Runtime运行时类,它的主要作用是使得应用程序和运行环境相连接,
返回与当前应用程序相关的java运行时对象。getRuntime(),大多数类 Runtime
方法是实例方法,必须对目前的运 行时对象调用。
B:public Process exec(String command)
-
在一个单独的进程中执行指定的字符串命令。
案例演示:
public class Test2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Runtime runtime = Runtime.getRuntime();
// exec(command); 可以执行某些DOS命令
runtime.exec("mspaint");
runtime.exec("calc");
}
}
五.模板设计模式
A:模板设计模式概述:
模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
B:优点:使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
缺点:如果算法骨架有修改的话,则需要修改抽象类
案例演示:计算for循环和复制文
抽象方法类:
public abstract class CalcTime {
public void Caltime() throws Exception {
long time1 = System.currentTimeMillis();
//把这些具体的功能抽象为方法
//fortime();
//copyfile();
testTime();
long time2=System.currentTimeMillis();
//计算这个方法的耗时
System.out.println(time2-time1);
}
public abstract void testTime();
public void fortime() {
for(int i=0;i<1000;i++) {
System.out.println("");
}
}
public void copyfile() throws Exception {
FileInputStream fis=new FileInputStream(new File("D:\\MyTest.java"));
FileOutputStream fos=new FileOutputStream(new File("E:\\MyTest.java"));
byte[] by=new byte[1024];
int len=0;
while((len=fis.read(by))!=-1) {
fos.write(by, 0, len);
}
fis.close();
fos.close();
}
}
复制文件类:
public class FiletTest extends CalcTime {
@Override
public void testTime(){
try {
// 复制文件
File file = new File("D:\\MyTest.java");
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(new File("E:\\MyTest.java"));
byte[] by = new byte[1024];
int len = 0;
while ((len = fis.read(by)) != -1) {
fos.write(by, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for循环类
public class Fortest extends CalcTime{
@Override
public void testTime() {
for(int i=0;i<1000;i++) {
System.out.println("");
}
}
}
测试类:
public class Test {
public static void main(String[] args) throws Exception {
// CalcTime calcTime = new CalcTime();
// calcTime.Caltime();
CalcTime fortest = new Fortest();
fortest.Caltime();
FiletTest filetTest = new FiletTest();
filetTest.Caltime();
}
}
分析:这样做的好处就是当你想要计算任意一个任务的耗时,不必修改原有的代码,只需要写出你的类重写testTime()方法就可以。代码灵活,易于保护,结构清晰。