? 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。
? 1、设计模式为程序提供可拓展性。
? 2、遵循设计模式可以为程序提供维修性,可读性,规范性。
? 3、 面试问题
? 4、设计模式无处不在
? 5、成为优秀程序员必备条件。
? 设计模式是为了让程序,具有更好的:代码复用性,可读性(规范性),可拓展性,可靠性,使程序呈现高内聚,低耦合的特性
? 一个类应该只负责一项职责
? 1、降低类的复杂度,一个类只负责一项原则
? 2、提高类的可读性,可维护性。
? 3、降低变更引起的风险。
? 4、通常情况下,应当遵守单一职责原则。只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则。
? 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小接口上。
? 1)类a通过接口 interface 1依赖b,类c通过接口 interface 1 依赖d,如果接口 interface 对于a 和c来说不是最小接口,那么类b和类d必须去实现他们不需要的方法。
? 2)将接口interface 1拆分为独立的几个接口,类a和类c分别为与他们需要的接口建立依赖关系,也就是采用接口隔离原则。
? 3)接口interface 1 中出现的方法,根据实际情况拆分为三个接口。
?
1)高层模块不应该依赖低层模块,二者都应该依赖其抽象
2)抽象不应该依赖细节,细节应该依赖抽象
3)依赖倒转(倒置)的中心思想是面向接口编程
4)依赖倒转原则是基于这样的设计理念,相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定得多,在Java中,抽象指的是接口和抽象类,细节就是具体的实现类。
5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去实现。
package com.itsmallstudent.principle.inversion;
public class DependencyInversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
class Email{
public String getInfo(){
return "hello world";
}
}
/**
* 1,完成了Person接受消息的功能
* 方式1分析
* 1.简单,比较容易想到
* 2.如果获取对象是微信等新增类,那么person类需要新增对应方法
* @author cpms
*
*/
class Person{
public void receive(Email email){
System.out.println(email.getInfo());
}
}
//使用依赖倒转原则
package com.itsmallstudent.principle.inversion;
public class DependencyInversion2 {
public static void main(String[] args) {
Person2 person = new Person2();
person.receive(new Phone());
person.receive(new WeChat());
System.out.println();
}
}
interface Msg{
String getInfo();
}
class Phone implements Msg{
@Override
public String getInfo() {
// TODO Auto-generated method stub
return "手机短信:Hello World";
}
}
class WeChat implements Msg{
@Override
public String getInfo() {
// TODO Auto-generated method stub
return "微信消息:Hello World";
}
}
class Person2{
public void receive(Msg msg){
System.out.println(msg.getInfo());
}
}
interface Msg{
String getInfo();
}
interface Receicve{
String Receice(Msg msg);
}
class Person3 implements Receicve{
@Override
public String Receice(Msg msg) {
// TODO Auto-generated method stub
return msg.getInfo();
}
}
interface Msg{
String getInfo();
}
interface Receicve{
String Receice();
}
class Person3 implements Receicve{
private Msg yourMsg;
//构造方法
public Person3(Msg msg){
this.yourMsg=msg;
}
public Msg getYourMsg() {
return yourMsg;
}
//setter 方法
public void setYourMsg(Msg yourMsg) {
this.yourMsg = yourMsg;
}
@Override
public String Receice() {
// TODO Auto-generated method stub
return yourMsg.getInfo();
}
}
//创建一个更加基础的基类
class Basic{
//把更加基础的方法和成员写到basic中
}
//A类
class A extends Basic {
public int function1(int a,int b){
return a-b;
}
}
//B类
class B extends Basic{
//如果b想使用a的方法,使用组合关系
private A a = new A();
public int function1(int a, int b) {
// TODO Auto-generated method stub
return a+b;
}
public int function2(int a,int b){
return function1(a, b)+9;
}
//假如我们仍然想使用A的方法
public int function3(int a,int b){
return this.a.function1(a, b);
}
}
package com.itsmallstudent.principle.ocp;
/**
* 优点是比较好理解,简单易操作
* 缺点是违反了设计模式的ocp原则,则对扩展开放,对修改关闭,即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
* 比如我们这时要新增加一个图形种类,我们需要做如下修改,修改的地方比较多
* @author cpms
*
*/
public class Example {
public static void main(String[] args) {
//使用看看存在的问题
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawRectangle(new Rectangle());
graphicEditor.drawCircle(new Circle());
}
}
//这是一个用于绘图的类
class GraphicEditor{
//接受shape对象
public void drawShape(Shape s){
if(s.my_type==1){
drawRectangle(s);
}else if(s.my_type==2) {
drawCircle(s);
}
}
//绘制矩形
public void drawRectangle(Shape r){
System.out.println("绘制矩形");
}
//绘制圆形
public void drawCircle(Shape r){
System.out.println("绘制圆形");
}
}
class Shape{
int my_type;
}
class Rectangle extends Shape{
Rectangle() {
super.my_type=1;
}
}
class Circle extends Shape{
public Circle() {
super.my_type=2;
}
}
改进的思路分析
? 思路:把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,
//这是一个用于绘图的类
class GraphicEditor1{
//接受shape对象
public void drawShape(Shape1 e){
e.darw();
}
}
abstract class Shape1{
int my_type;
abstract void darw();
}
class Rectangle2 extends Shape1{
public Rectangle2() {
// TODO Auto-generated constructor stub
super.my_type=1;
}
@Override
void darw() {
// TODO Auto-generated method stub
System.out.println("绘制矩形");
}
}
class Circle2 extends Shape1{
public Circle2() {
// TODO Auto-generated constructor stub
super.my_type=2;
}
@Override
void darw() {
// TODO Auto-generated method stub
System.out.println("绘制圆形");
}
}
代码
package com.itsamllstudent.principle.demeter;
import java.util.ArrayList;
import java.util.List;
public class Demeter1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//
schoolManager.printAllEmployee(new CollegeManager());
}
}
//学校总部员工
class Employee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//学院员工
class CollegeEmployee{
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private String id;
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployees(){
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) {
CollegeEmployee employee = new CollegeEmployee();
employee.setId("学院员工id为"+i);
list.add(employee);
}
return list;
}
}
//学校的管理类
// 分析SchoolManger 类的直接朋友类有哪些,Employee,CollegeManager
// CollegeEmployee不是直接朋友,而是一个陌生类,这样违背了迪米特法则。
class SchoolManager{
public List<Employee> getAllEmployees(){
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 10; i++) {
Employee employee = new Employee();
employee.setId("学院总部员工id为"+i);
list.add(employee);
}
return list;
}
//分析问题
//1.CollegeEmployee不是SchoolManager的直接朋友
//2.CollegeEmployee是以局部变量方法出现在SchoolManager
//3.违反了迪米特法则
void printAllEmployee(CollegeManager sub){
List<CollegeEmployee> list = sub.getAllEmployees();
System.out.println("-----------分公司员工----------------");
for (CollegeEmployee e : list) {
System.out.println(e.getId());
}
List<Employee> list2 = this.getAllEmployees();
System.out.println("-----------学校总部员工------------------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
改进如下
package com.itsamllstudent.principle.demeter.improve;
import java.util.ArrayList;
import java.util.List;
public class ImproveDemeter1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//输出
schoolManager.printAllEmployee(new CollegeManager());
}
}
//学校总部员工
class Employee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//学院员工
class CollegeEmployee{
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private String id;
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployees(){
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) {
CollegeEmployee employee = new CollegeEmployee();
employee.setId("学院员工id为"+i);
list.add(employee);
}
return list;
}
//输出学院员工的信息
public void printEmployee() {
List<CollegeEmployee> list = this.getAllEmployees();
System.out.println("-----------分公司员工----------------");
for (CollegeEmployee e : list) {
System.out.println(e.getId());
}
}
}
//学校的管理类
class SchoolManager{
//
public List<Employee> getAllEmployees(){
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 10; i++) {
Employee employee = new Employee();
employee.setId("学院总部员工id为"+i);
list.add(employee);
}
return list;
}
void printAllEmployee(CollegeManager sub){
sub.printEmployee();
List<Employee> list2 = this.getAllEmployees();
System.out.println("-----------学校总部员工------------------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
基本介绍
原则是尽量使用合成/聚合的方式,而不是使用继承
原文:https://www.cnblogs.com/It-smallstudent/p/14714216.html