面向对象设计原则
单一职责原则
- 是最简单的面向对象设计原则,它用于控制类的粒度大小
开闭原则
- 通过定义一个抽象类,而不去实现,使得业务可以灵活拓展
里氏替换原则
- 如果出现JavaCoder必须重写父类的方法的时候, 就不符合里氏替换原则了,那么这个时候,我们可以把自己的思维抬高,定义一个更高级的抽象类, 他没有实现某个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public abstract class People {
public abstract void coding(); class Coder extends People{ @Override public void coding() { System.out.println("我会打代码"); } }
class JavaCoder extends People{ public void game(){ System.out.println("艾欧尼亚最强王者已上号"); }
public void coding() { System.out.println("摆烂了,啊对对对"); } } }
|
依赖倒转原则
高层模块不应依赖于底层模块,它们都应该依赖抽象。抽象不应依赖于细节,细节应该依赖于抽象。
接口隔离原则
客户端不应依赖那些它不需要的接口。
合成复用原则
合成复用原则(Composite Reuse Principle)的核心就是委派。
迪米特法则
每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Main { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost", 8080); Test test = new Test(); test.test(socket); }
static class Test {
public void test(Socket socket){ System.out.println("IP地址:"+socket.getLocalAddress()); } } }
public class Main { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost", 8080); Test test = new Test(); test.test(socket.getLocalAddress().getHostAddress()); }
static class Test { public void test(String str){ System.out.println("IP地址:"+str); } } }
|
创建型
工厂方法模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class FruitFactory {
public static Fruit getFruit(String type) { switch (type) { case "苹果": return new Apple(); case "橘子": return new Orange(); default: return null; } } }
|
1 2 3 4 5 6
| public class Main { public static void main(String[] args) { Fruit fruit = FruitFactory.getFruit("橘子"); System.out.println(fruit); } }
|
1 2 3
| public abstract class FruitFactory<T extends Fruit> { public abstract T getFruit(); }
|
1 2 3 4 5 6
| public class AppleFactory extends FruitFactory<Apple> { @Override public Apple getFruit() { return new Apple(); } }
|
1 2 3 4 5 6 7 8 9 10
| public class Main { public static void main(String[] args) { test(new AppleFactory()::getFruit); }
private static void test(Supplier<Fruit> supplier){ System.out.println(supplier.get()+" 被吃掉了,真好吃。"); } }
|
抽象工厂模式
1 2 3 4 5 6 7 8 9 10 11
| public class Router { } public class Table { } public class Phone { } public abstract class AbstractFactory { public abstract Phone getPhone(); public abstract Table getTable(); public abstract Router getRouter(); }
|
建造者模式
实际上我们是通过建造者来不断配置参数或是内容,当我们配置完所有内容后,最后再进行对象的构建。
相比直接去new一个新的对象,建造者模式的重心更加关注在如何完成每一步的配置,同时如果一个类的构造方法参数过多,我们通过建造者模式来创建这个对象,会更加优雅。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class Student { ...
private Student(int id, int age, int grade, String name, String college, String profession, List<String> awards) { ... }
public static StudentBuilder builder(){ return new StudentBuilder(); }
public static class StudentBuilder{ int id; int age; int grade; String name; String college; String profession; List<String> awards;
public StudentBuilder id(int id){ this.id = id; return this; }
public StudentBuilder age(int age){ this.age = age; return this; } ...
public StudentBuilder awards(String... awards){ this.awards = Arrays.asList(awards); return this; } public Student build(){ return new Student(id, age, grade, name, college, profession, awards); toolbarsFlag} } }
|
单例模式
那么,什么是单例模式呢?顾名思义,单例那么肯定就是只有一个实例对象,在我们的整个程序中,同一个类始终只会有一个对象来进行操作。比如数据库连接类,实际上我们只需要创建一个对象或是直接使用静态方法就可以了,没必要去创建多个对象。
普通模式
1 2 3 4 5 6 7 8 9
| public class Singleton { private final static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance(){ return INSTANCE; } }
|
懒汉模式
在多线程环境下, 懒汉模式存在安全问题
等到用的时候,才去创建对象
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton { private static Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance(){ if(INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; } }
|
1 2 3 4 5 6
| public static synchronized Singleton getInstance(){ if(INSTANCE == null) { INSTANCE = new Singleton(); } return INSTANCE; }
|
1 2 3 4 5 6 7 8
| public static Singleton getInstance(){ if(INSTANCE == null) { synchronized (Singleton.class) { INSTANCE = new Singleton(); } } return INSTANCE; }
|
可以看到,这种情况下,IDEA会要求我们添加一个volatile
给INSTANCE
,各位还记得这个关键字有什么作用吗?没错,我们还需要保证INSTANCE
在线程之间的可见性,这样当其他线程进入之后才会拿INSTANCE
由其他线程更新的最新值去判断,这样,就差不多完美了。
1 2 3 4 5 6 7 8 9 10 11
| public class Singleton { private Singleton() {}
private static class Holder { private final static Singleton INSTANCE = new Singleton(); }
public static Singleton getInstance(){ return Holder.INSTANCE; } }
|
原型模式
并且通过复制这个原型来创建新的对象。也就是说,原型对象作为模板,通过克隆操作,来产生更多的对象,就像细胞的复制一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Student implements Cloneable{ String name;
public Student(String name){ this.name = name; } public String getName() { return name; }
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
|
- 使用这个方式,虽然这个对象是新创建的, 但是其中的属性和方法,确还是引用类型
1 2 3 4 5
| public static void main(String[] args) throws CloneNotSupportedException { Student student0 = new Student("小明"); Student student1 = (Student) student0.clone(); System.out.println(student0.getName() == student1.getName()); }
|
1 2 3 4 5 6
| @Override public Object clone() throws CloneNotSupportedException { Student student = (Student) super.clone(); student.name = new String(name); return student; }
|