1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起.------分离变化与不变化的部分,框架实际就是把业务与其余不变的代码进行分离,好让程序员更好的进行 if else 操作.
2.针对接口编程,不针对实现编程.------面向抽象,不面向具体的实现,代码如果依赖于具体的实现可拓展性比较差,牵一发而动全身.
java分为编译期和运行期,在编译期如果编写的代码依赖与具体的实现,后期拓展功能会频繁的更改代码.
但是当编译期依赖于抽象的时候,在运行期会根据传入具体的类型执行代码,所以不需要频繁更改代码.
举个例子:
定义一个接口Animal,会发出声音
public interface Animal { void makeSound(); }
定义两个具体的类Cat,Dog,实现接口Animal
public class Cat implements Animal{ @Override public void makeSound() { System.out.println("喵喵喵"); } }
public class Dog implements Animal{ @Override public void makeSound() { System.out.println("汪汪汪"); } }
编写测试类
public class AnimalTest { public static void main(String[] args) { Cat cat = new Cat(); test(cat); } private static void test(Cat cat) { cat.makeSound(); } }
可以看到,如果test类依赖于具体的cat类型,如果这时候需要传入dog参数,就需要在改写一遍代码如:
public class AnimalTest { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); test(cat); test(dog); } private static void test(Cat cat) { cat.makeSound(); } private static void test(Dog dog) { dog.makeSound(); } }
如果后期在有别的动物出现,就需要不停的重载test方法,其实我们这边关心的只是动物发出的声音,完全可以用Animal类来替代具体的类,比如
public class AnimalTest { public static void main(String[] args) { Cat cat = new Cat(); Dog dog = new Dog(); test(cat); test(dog); } private static void test(Animal animal) { animal.makeSound(); } // private static void test(Cat cat) { // cat.makeSound(); // } // private static void test(Dog dog) { // dog.makeSound(); // } }
这边参数直接声明成Animal接口,在运行期根据传入的具体类型来执行子类的实现方法,这种操作也叫向上转型.
这样实现的话代码就比较简洁,而且代码拓展性与可维护性也比较好,就算在来100只动物,test类不需要更改.
3.多用组合,少用继承. ------ 继承会强制子类继承某些不需要的方法或者实现,但是组合的话可以自由添加与删除.
原文:https://www.cnblogs.com/lishuaiqi/p/11074933.html