文章目录
1 面向对象思想设计原则
在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计原则。
- 单一职责原则
- 开闭原则
- 里氏替换原则
- 依赖注入原则
- 接口分离原则
- 迪米特原则
1.1 单一职责原则
其实就是开发人员经常说的”高内聚,低耦合”
也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则。
1.2 开闭原则
核心思想是:一个对象对扩展开放,对修改关闭。
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码。
也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以改变和扩展的。
1.3 里氏替换原则
核心思想:在任何父类出现的地方都可以用它的子类来替代。
其实就是说:同一个继承体系中的对象应该有共同的行为特征。
1.4 依赖注入原则
核心思想:要依赖于抽象,不要依赖于具体实现。
其实就是说:在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他类的具体类。为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。
1.5 接口分离原则
核心思想:不应该强迫程序依赖它们不需要使用的方法。
其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口中。
1.6 迪米特原则
核心思想:一个对象应当对其他对象尽可能少的了解
其实就是说:降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部工作原理,它可以使各个模块耦合度降到最低,促进软件的复用
2 设计模式
2.1 设计模式概述
- 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
- 设计模式不是一种方法和技术,而是一种思想
- 设计模式和具体的语言无关,学习设计模式就是要建立面向对象的思想,尽可能的面向接口编程,低耦合,高内聚,使设计的程序可复用
- 学习设计模式能够促进对面向对象思想的理解,反之亦然。它们相辅相成
2.2 设计模式的分类
- 创建型模式 对象的创建
- 结构型模式 对象的组成(结构)
- 行为型模式 对象的行为
2.3 简单工厂模式
又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
优点
客户端不需要在负责对象的创建,从而明确了各个类的职责
缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护
2.2 工厂方法模式
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。(针对每一个具体的实现提供一个具体工厂)
优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
缺点
需要额外的编写代码,增加了工作量
2.3 单例设计模式
单例设计模式概述
单例模式就是要确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供。
如何保证类在内存中只有一个对象呢?
A: 把构造方法私有
B: 在成员位置自己创建一个对象
C: 通过一个公共的方法提供访问
分类
- 饿汉式
类一加载就创建对象 - 懒汉式
用的时候,才去创建对象
面试题:单例模式的思想是什么?请写一个代码体现。
开发:饿汉式(是不会出问题的单例模式)
面试:懒汉式(可能会出问题的单例模式)
A:懒加载(延迟加载)
B:线程安全问题
a:是否多线程环境 是
b:是否有共享数据 是
c:是否有多条语句操作共享数据 是
饿汉式直接返回对象,原子语句不会产生线程安全问题
懒汉式举例:
public class Teacher {
private Teacher() {
}
private static Teacher t = null;
public synchronized static Teacher getTeacher() {//间synchronized关键字解决懒汉式同步安全问题才正确
// t1,t2,t3
if (t == null) {
//t1,t2,t3
t = new Teacher();
}
return t;
}
}
饿汉式举例:
我们在开发中用的都是饿汉式,举例:JDK提供的一个单例模式应用的类Runtime。
Runtime:每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
exec(String command)
class Runtime {
private Runtime() {}
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
}
单例模式优点
在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
单例模式缺点
没有抽象层,因此扩展很难。
职责过重,在一定程序上违背了单一职责
2.4 模板设计模式
概念:
模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
优点:
使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
缺点:
如果算法骨架有修改的话,则需要修改抽象类
举例:
需求:请给我计算出一段代码的运行时间
public abstract class GetTime {
// 需求:请给我计算出一段代码的运行时间
public long getTime() {
long start = System.currentTimeMillis();
// for循环
// for (int x = 0; x < 10000; x++) {
// System.out.println(x);
// }
// 视频
// try {
// BufferedInputStream bis = new BufferedInputStream(
// new FileInputStream("a.avi"));
// BufferedOutputStream bos = new BufferedOutputStream(
// new FileOutputStream("b.avi"));
// byte[] bys = new byte[1024];
// int len = 0;
// while ((len = bis.read(bys)) != -1) {
// bos.write(bys, 0, len);
// }
// bos.close();
// bis.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// 再给我测试一个代码:集合操作的,多线程操作,常用API操作的等等...
code();
long end = System.currentTimeMillis();
return end - start;
}
public abstract void code();
}
//具体的code内容放到子类来实现
public class IODemo extends GetTime{
@Override
public void code() {
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("a.avi"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("b.avi"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.5 装饰设计模式
装饰设计模式概述
装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案
优点
使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能
缺点
正因为可以随意组合,所以就可能出现一些不合理的逻辑
举例:

public class PhoneDemo {
public static void main(String[] args) {
Phone p = new IPhone();
p.call();
System.out.println("------------");
// 需求:我想在接电话前,听彩铃
PhoneDecorate pd = new RingPhoneDecorate(p);
pd.call();
System.out.println("------------");
// 需求:我想在接电话后,听音乐
pd = new MusicPhoneDecorate(p);
pd.call();
System.out.println("------------");
// 需求:我要想手机在接前听彩铃,接后听音乐
// 自己提供装饰类,在打电话前听彩铃,打电话后听音乐
pd = new RingPhoneDecorate(new MusicPhoneDecorate(p));
pd.call();
System.out.println("----------");
// 想想我们在IO流中的使用
// InputStream is = System.in;
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(
System.out)));
Scanner sc = new Scanner(System.in);
}
}
2.6 适配器设计模式
适配器设计模式概述
将一个类的接口转换成另外一个客户希望的接口。从而使原来不能直接调用的接口变的可以调用。
优点
让本来不适合使用的接口变得适合使用
缺点
一次只能适配一个类,使用有一定的局限性
案例:
* 问题:
* 接口(方法比较多) -- 实现类(仅仅使用一个,也得把其他的实现给提供了,哪怕是空实现)
* 太麻烦了。
* 解决方案:
* 接口(方法比较多) -- 适配器类(实现接口,仅仅空实现) -- 实现类(用哪个重写哪个)
/*
* 针对用户操作的四种功能
*/
public interface UserDao {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
public abstract class UserAdapter implements UserDao {
@Override
public void add() {
}
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void find() {
}
}
public class UserDaoImpl2 extends UserAdapter {
@Override
public void add() {
System.out.println("添加功能");
}
}
1570

被折叠的 条评论
为什么被折叠?



