六大原则
单一职责原则
- 一个类只负责一个功能领域的相应职责。也就是:对于一个类而言,应该只有一个引起它变化的原因。
开闭原则
- 一个实体应该对扩展开放,对修改关闭。
里氏替换原则
- 所有引用基类(父类)的地方必须能透明的使用其子类的对象。
接口隔离原则
- 使用多个专门的接口,而不应该使用单一的总接口。
迪米特原则
- 一个实体应当尽可能少地与其他实体发生相互作用,即尽可能的降低系统的耦合度。
依赖倒置原则
- 抽象不应该依赖细节,而是细节依赖抽象,即应面向接口编程,而不应面向实现编程。
策略模式
找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混合在一起。
策略模式定义了算法族(行为),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的用户。
当有n只鸭子,有个鸭子会叫、会游泳,有的鸭子不会叫、不会游泳,但是都会飞时,如何设计?
- 将可变的的一组行为从鸭子类duck中取出来,建立新类来代表每个行为,在鸭子类duck中包含设定行为的方法,这样就可以在“运行时”动态的改变鸭子的行为。
- 整合鸭子的行为,在duck类中定义两个实例变量FlyBehavior和QuackBehavior,子类在新建的时候通过构造函数去实例化这两个参数,通过setter方法动态的设置鸭子的行为。
观察者模式
定义了对象之间的一对多依赖,这样依赖,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。
交互,但是不太清楚彼此的细节,观察者模式提供了一种对象设计,让主题和观察者之间松耦合。主题只知道观察者实现了Observer接口,不需要知道观察者的具体类是谁,做了什么或者其他细节。
设计原则:为了交互对象之间的松耦合设计而努力。
装饰者模式
动态的将责任附加到对象上,若扩展功能,装饰者提供了比继承更有弹性的替代方案。(运行时扩展)
当一个咖啡有摩卡、浓缩咖啡、还有牛奶、奶泡各种调料时,如何去设计?
- 所有的咖啡类型以及调料都继承一个抽象类(Beverage),在这里继承是为了“类型匹配”而不是继承行为,行为通过组合关系得到。
- 设计原则:开闭原则,类应该对扩展开发,对修改关闭。
- Java I/O就是使用了装饰者模式的思想。
缺点:利用装饰者模式、常常造成设计中有大量的小类,数量实在太多,可能会造成此API程序员的困扰。
工厂模式
定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让实例化推迟到子类。
生成一家宠物店,用来创建宠物。
public interface AnimalFactory {
Animal createAnimal();
}
接着创建猫工厂跟狗工厂
// 继承着宠物工厂
public class CatFactory implements AnimalFactory {
@Override
// 创建猫
public Animal createAnimal() {
return new Cat();
}
}
// 继承着宠物工厂
public class DogFactory implements AnimalFactory {
// 创建狗
@Override
public Animal createAnimal() {
return new Dog();
}
}
动物实体类
public abstract class Animal {
// 所有的动物都会吃东西
public abstract void eat();
}
猫实体类
public class Cat extends Animal {
// 猫喜欢吃鱼
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
狗实体类
public class Dog extends Animal {
// 狗喜欢吃肉
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
那么现在想要一只狗就能用工厂生成了
AnimalFactory f = new DogFactory();
Animal a = f.createAnimal();
a.eat();
如果这个时候想要新添一个新动物,只需创建一个对应的实体工厂以及实体类就行了。
优点:
- 客户端不需要知道在负责对象的创建,明确了各个类的职责。
- 如果有新的实体对象添加,只需要添加一个具体的类和具体的工厂。
- 不会影响已有的代码,后期维护容易,增强系统的扩展性。
缺点:
- 需要额外的代码,增加了工作量。
简单工厂
只需要一个工厂创建所有的实体(动物)
public class AnimalFactory {
public static Dog createDog() {
return new Dog();
}
public static Cat createCat() {
return new Cat();
}
// 外界想要猫要狗,这里创建就好了
public static Animal createAnimal(String type) {
if ("dog".equals(type)) {
return new Dog();
} else if ("cat".equals(type)) {
return new Cat();
} else {
return null;
}
}
}
优点:
- 只需要一个具体工厂来完成创建对象,代码量少。
缺点:
- 每次添加新的实体时,都需要修改工厂,即当需求改变时,就要修改代码。
抽象工厂
抽象工厂创建的是一类产品,而不是一种产品。
动物有性别之分,这时候需要给动物添加性别,所以需要将元工厂进行修改。
public interface AnimalFactory {
Animal createDog();
Animal createCat();
}
创建雌性动物的工厂
public class FemaleAnimalFactory implements AnimalFactory {
// 生产母狗和母猫
@Override
public Animal createDog() {
return new FemaleDog();
}
@Override
public Animal createCat() {
return new FemaleCat();
}
}
创建雄性的工厂
public class MaleAnimalFactory implements AnimalFactory {
// 生产公狗和公猫
@Override
public Animal createDog() {
return new MaleDog();
}
@Override
public Animal createCat() {
return new MaleCat();
}
}
定义动物
public abstract class Animal {
// 所有的动物都会吃东西
public abstract void eat();
// 所有的动物都有性别
public abstract void gender();
}
public abstract class Cat extends Animal {
// 猫喜欢吃鱼
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public abstract class Dog extends Animal {
// 狗喜欢吃肉
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
猫分为公猫、母猫。狗分为公狗和母狗:
public class FemaleCat extends Cat {
public void gender() {
System.out.println("I am a female Cat");
}
}
单例模式
饿汉式
public class Singleton{
private static Singleton instand = new Singleton();
//将构造方法私有化
private Singleton(){}
public static Singleton getInstand(){
return instand;
}
}
懒汉式
public class Singleton{
private static volatile Singleton instand = null;
//将构造方法私有化
private Singleton(){}
public static Singleton getInstand(){
if(instand == null){
synchronized(Singleton){
if(instand == null){
instand = new Singleton();
}
}
}
return instand;
}
}
静态内部类懒汉式
public class Singleton{
//将构造方法私有化
private Singleton(){}
private static class LazyHolder{
private staitc final Singleton INSTAND = new Singleton();
}
public static final Singleton getInstand(){
return LazyHolder.INSTAND;
}
}
当任何一个线程第一次调用getInstand()时,LazyHolder被加载和初始化,此时静态初始化器将执行Singleton的初始化操作(只有被调用时才进行初始化);
初始化静态数据时,Java提供了线程安全保证。
枚举
public enum Singleton{
Singleton;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。