大话java编程思想

编程入门 行业动态 更新时间:2024-10-24 09:27:03

<a href=https://www.elefans.com/category/jswz/34/1768613.html style=大话java编程思想"/>

大话java编程思想

为什么80%的码农都做不了架构师?>>>   

首先提一下java的设计原则:

1.CHANGE (能应对变化)

2.KISS(keep it simple &studio 保持代码简单的易读性)

3.DRY(don't repeat youself 不要写一些重复的代码)

4.SRP(single responsibility principle 单一职责原则)

5.OCP(open closed principle 对外开放,对内封闭)

6.LSP(liskov substitution principle 里氏置换原则)

7.ISP(interface single principle 接口隔离原则)

8.DIP(dependence Inversion principle 依赖倒置原则)

当然,还有其他很多例如:CARP LOD COC ....

关于java的设计原则,网上有很多.可以参考:

现在,开始要说的是,在什么样的场景下使用他们.

案例:输出三行 hello World

首先,我们肯定想到的是:

public class HelloWorld {public static void main(String[] args) {System.out.println("Hello World");System.out.println("Hello World");System.out.println("Hello World");}
}

现在,需求变化了,客户希望输出的是三个Hello Java .那么怎么办呢?修改很简单,直接复制Java粘贴替换World就可以.但是,这显然有问题的,如果输出是10多二十行呢?那不是要复制粘贴而多次?这时候,可以把HelloWorld抽取出来,单独做一个类.该类提供一个方法,返回HelloWorld语带代码:

public class HelloWorld {public static void main(String[] args) {System.out.println(new A().getStr());System.out.println(new A().getStr());System.out.println(new A().getStr());}
}class A {public String getStr(){return "Hello World" ;}
}

但是,很明显.客户有可能要输出的是Hello Java ,Hello Html ...显然,每次都需要修改类A,这就违反了之前的开闭原则.那么怎么重构呢?可以这样:

public class HelloWorld {public static void main(String[] args) {System.out.println(new A().getStr(new Java()));System.out.println(new A().getStr(new World()));System.out.println(new A().getStr(new Html()));}
}class A {public String getStr(B b){return "Hello "+b.getcontent() ;}
}
abstract class B {public String getcontent() {return setStr() ;}abstract  String setStr() ;
}class Java extends B{@OverrideString setStr() {return "Java";}
}class World extends B {@OverrideString setStr() {return "World";}
}class Html extends B{@OverrideString setStr() {return "Html";}
}

这样,下次如果需要PHP的时候,只需要扩展类B 然后返回php就行了,不在需要修改源代码.这里每次都需要new Java 很明显,这里用之前提到的LSP(里氏替换原则),但是又有一个问题,每次调用都需要去写实例化代码,这样代码显的比较的臃肿.也违反了之前提到的SRP(单一职责原则)这时候,我们采用Java设计模式的代理模式,做一个工厂,工厂传入一个参数.让工厂来实例化.于是代码如下:

public class HelloWorld {public static void main(String[] args) {System.out.println(new A().getStr(HelloFactory.getInstance("Java")));System.out.println(new A().getStr(HelloFactory.getInstance("Html")));System.out.println(new A().getStr(HelloFactory.getInstance("World")));}
}class A {public String getStr(B b){return "Hello "+b.getcontent() ;}
}
abstract class B {public String getcontent() {return setStr() ;}abstract  String setStr() ;
}class Java extends B{@OverrideString setStr() {return "Java";}
}class World extends B {@OverrideString setStr() {return "World";}
}class Html extends B{@OverrideString setStr() {return "Html";}
}class HelloFactory {public static B getInstance(String str){switch (str) {case "Java":return new Java() ;case "Html":return new Html() ;case "Hello":return new World() ;default  :return null ;}}
}

但是这样还有一个问题,如果我要新增一个php,那么工厂类又要重新写!很明显,违反了开闭原则.这时候,我们可以采用反射机制来实现,代码如下:

package test;public class HelloWorld {public static void main(String[] args) {try {System.out.println(new A().getStr(HelloFactory.getInstance("Java")));System.out.println(new A().getStr(HelloFactory.getInstance("Html")));System.out.println(new A().getStr(HelloFactory.getInstance("World")));} catch (Exception e) {e.printStackTrace();}}
}class A {public String getStr(B b) {return "Hello " + b.getcontent();}
}abstract class B {public String getcontent() {return setStr();}abstract String setStr();
}class Java extends B {@OverrideString setStr() {return "Java";}
}class World extends B {@OverrideString setStr() {return "World";}
}class Html extends B {@OverrideString setStr() {return "Html";}
}class HelloFactory {public static B getInstance(String str) throws Exception {// 这里采用的是包名+类名形式,因为我这个类是在test包下.return (B) Class.forName("test." + str).newInstance();}
}

现在可以直接新增一个php的类,然后通过工厂来实例化了.但是,这里还有一个问题,如果是第三方使用我的方法来输出Hello World ,那么每次第三方要新增的时候,我都要去修改我的源代码...oh,no!!必须重构~~,那么采用接口方式吧,把控制权给到第三方(使用我代码开发的人):

package test;public class HelloWorld {public static void main(String[] args) {try {System.out.println(new A().getStr(HelloFactory.getInstance("Java")));System.out.println(new A().getStr(HelloFactory.getInstance("Html")));System.out.println(new A().getStr(HelloFactory.getInstance("World")));} catch (Exception e) {e.printStackTrace();}}
}class A {public String getStr(B b) {return "Hello " + b.getcontent();}
}interface B {public String getcontent();
}class Java implements B {public String getcontent() {return "Java";}
}class World implements B {@Overridepublic String getcontent() {return "World";}
}class Html implements B {@Overridepublic String getcontent() {return "Html";}
}class HelloFactory {public static B getInstance(String str) throws Exception {// 这里采用的是包名+类名形式,因为我这个类是在test包下.return (B) Class.forName("test." + str).newInstance();}
}

现在,第三方使用我的程序的时候,只需要实现我提供的接口B,就可以了.不再依赖我去修改我自己的程序了.但是,如果我要想输出的是Java Hello,或者就是Html这样的格式的时候呢? 不是还需要修改我的代码么?所以,我必须把更多的控制权给到使用者(第三方).:

package test;public class HelloWorld {public static void main(String[] args) {try {System.out.println(HelloFactory.getInstance("Java").getStr(n->{return n+" Hello" ;}));System.out.println(HelloFactory.getInstance("Html").getStr(n->{return n+" is too hard" ;}));System.out.println(HelloFactory.getInstance("World").getStr(n->{return n+" is open" ;}));} catch (Exception e) {e.printStackTrace();}}
}abstract class A {public String getStr(C c) {return c.setStr(getName()) ;}abstract String getName() ;
}interface C {public String setStr(String str);
}class Html extends A {@OverrideString getName() {return "Html";}
}
class Java extends A {@OverrideString getName() {return "Java";}
}
class World extends A {@OverrideString getName() {return "World";}
}class HelloFactory {public static A getInstance(String str) throws Exception {// 这里采用的是包名+类名形式,因为我这个类是在test包下.return (A) Class.forName("test." + str).newInstance();}
}

这样,第三方想要什么格式的都有了.但是这里还有一个问题,如果我不实用Java,而要使用php的时候,每次都要实现抽象类,然后使用匿名接口,然后再重新编译.那么如果做成配置文件,是不是就不再需要重新编译了呢?于是可以改写:

package test;import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;public class HelloWorld {public static void main(String[] args) {Properties properties = new Properties();try {InputStream inputStream = new BufferedInputStream(new FileInputStream("src/test/com/mySet.properties"));properties.load(inputStream);System.out.println(HelloFactory.getInstance(properties.getProperty("key1").toString()).getStr(n -> {return n + " Hello";}));System.out.println(HelloFactory.getInstance(properties.getProperty("key2").toString()).getStr(n -> {return n + " Hello";}));System.out.println(HelloFactory.getInstance(properties.getProperty("key3").toString()).getStr(n -> {return n + " Hello";}));} catch (Exception e) {e.printStackTrace();}}
}abstract class A {public String getStr(C c) {return c.setStr(getName());}abstract String getName();
}interface C {public String setStr(String str);
}class Html extends A {@OverrideString getName() {return "Html";}
}class Java extends A {@OverrideString getName() {return "Java";}
}class World extends A {@OverrideString getName() {return "World";}
}class HelloFactory {public static A getInstance(String str) throws Exception {// 这里采用的是包名+类名形式,因为我这个类是在test包下.return (A) Class.forName("test." + str).newInstance();}
}

配置文件(mySet.properties):

key1=Java
key2=Html
key3=World

到这里,如果第三方想要输出什么格式,都可以自由发挥.想要输出php只需修改配置文件就可以了.也不需要再对我的代码惊醒重新编译.貌似比较完善了..

但是,真的这样吗?

现在,写了这么多代码,但是好像我什么都没做...要实现什么样的输出,都需要去先实现我的抽象类,然后在修改配置文件.我什么都没做啊,貌似.但是,比起最初的版本,我实际确实做了太多的工作,那么该不该如此做呢?例如客户只需要输出一个Hello World,而你却给我如此一大堆,最还要我自己写一大堆实现类,配置.就为了一个Hello World? 肯定有病!!

所以,这就是代码的另一个原则YAGNI(You Ain’t Gonna Need It     你是不是真的需要它!) 我理解为中庸,儒家思想嘛.

对于Java思想来说,这只是冰山一角.自我勉励吧.

转载于:

更多推荐

大话java编程思想

本文发布于:2024-02-05 02:30:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1673427.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:大话   思想   java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!