Java程序设计的基本原则是开闭原则,即一个软件实体如类、模板、函数、对扩展开放,对修改关闭。
1.模板设计模式:
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况 下,重新定义算法中的某些步骤。
在Java程序设计时,应对大量重复的方法抽取出来作为一个抽象基类,抽象基类中可定义一个final方法,定义声明此方法的方法体(流程),且后续的子类不能覆写这个方法。方法体中的流程可以利用this.方法名();
调用其他普通方法,可以为抽象的,等待子类实现,抽象类中的普通方法及各个流程也可被子类根据其功能要求覆写。也可以在方法体中写一个空白方法,专业名词为钩子,可供子类覆写。
public class TemplateDesign{
public static void main(String[] args){
System.out.println("柠檬茶一杯");
Tea tea=new Tea();
tea.makeDrink();
System.out.println("*********************");
System.out.println("芒果汁一杯");
Juice juice=new Juice();
juice.makeDrink();
System.out.println("*********************");
System.out.println("芒果汁一杯");
Juice juice2=new Juice();
juice2.makeDrink();
}
}
abstract class Drink{
//制作流程,定义为final方法,子类不可覆写,不可改变
public final void makeDrink(){
this.boilWater();
this.putWater();
this.addMajor();
//定义返回值为布尔类型的方法判断是否需要添加辅料
if(isAddMinor()){
this.addMinor();
}
this.finsh();
}
//固定流程,可定义为final方法,子类不需要更改
public final void boilWater(){
System.out.println("1.把水烧开");
}
public final void putWater(){
System.out.println("2.把水倒进杯子");
}
//抽象方法,需要子类实现
abstract public void addMajor();
abstract public void addMinor();
//返回值为布尔类型的方法,默认返回值为true,可供子类覆写
public boolean isAddMinor(){
return true;
}
public void finsh(){
System.out.println("饮品完成");
}
}
//Tea类继承Drink,必须实现父类所有的抽象方法,可覆写父类的非final方法
class Tea extends Drink{
public void addMajor(){
System.out.println("3.把茶倒进水中");
}
public void addMinor(){
System.out.println("4.添加柠檬片");
}
}
class Juice extends Drink{
public void addMajor(){
System.out.println("3.把浓缩芒果粉倒进水中");
}
//覆写父类的 isAddMinor()方法,增加返回结果的多样性
public boolean isAddMinor(){
System.out.println("是否加糖和牛奶:y/n");
java.util.Scanner scan=new java.util.Scanner(System.in);
String input=scan.nextLine();
if(input.equals("y")){
return true;
}
else if(input.equals("n")){
return false;
}
else{
System.out.println("任意键入符号,默认添加");
return true;
}
}
public void addMinor(){
System.out.println("4.加糖和牛奶");
}
}
2.简单工厂设计模式
创建接口类,在接口类中定义产品能实现的功能,通过不同的子类实现接口进而实现个子类需要的不同的功能
专门定义一个类,类中的方法传入接口的对象用来创建接口实现类的实例,被创建的实例通常都具有共同的父类。(利用了对象的多态)
但是在实例化对象时需要耦合子类的类名才能创建对象,因此我们采用创建生产电脑的工厂,客户需要购买什么样的电脑,只要输入类型编号就可以获取该电脑。将类 的实例化交给工厂易于解耦
//简单工厂模式
//定义第三方类,通过类中的方法传递接口的实现类的实例化对象,从而通过对象调用功能
public class SimpleFactoryPattern{
//buy方法传递接口的实现类的实例化对象
public void buy(Computer com){
com.printComputer();
}
public static void main(String[] args){
//交互式用户输入方式
System.out.println("请输入你想要的笔记本品牌:mac/ASUS/Alienware");
java.util.Scanner scan=new java.util.Scanner(System.in);
String type=scan.nextLine();
SimpleFactoryPattern client=new SimpleFactoryPattern();
//电脑工厂类负责解耦
ComputerFactory computer=new ComputerFactory();
client.buy(computer.getInstance(type));
//client.buy(ComputerFactory.getInstance(type));
}
//2.利用执行文件时,主方法传入参数实现解耦调用
/*public static void main(String[] args){
SimpleFactoryPattern client=new SimpleFactoryPattern();
ComputerFactory computer=new ComputerFactory();
String type=args[0];
if(args.length==0){
System.out.println("需传入参数,输入你需要的电脑型号:mac/ASUS/Alienware");
}
else {
client.buy(ComputerFactory.getInstance(type));
}
}*/
}
//共有的接口,定义抽象方法,需实现的功能
interface Computer{
void printComputer();
}
//子类实现接口
class MacComputer implements Computer{
public void printComputer(){
System.out.println("这是一台mac电脑");
}
}
//子类实现接口
class AsusComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕ASUS电脑");
}
}
//子类实现接口
class AlienwareComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕Alienware电脑");
}
}
//再定义一个工厂类用于解耦
class ComputerFactory{
//静态方法可通过类名之间调用,通过终端传递一个易懂的字符参数,返回接口相应的的实现类
public static Computer getInstance(String type){
Computer computer=null;
switch (type){
case "mac":
computer=new MacComputer();
break;
case "ASUS":
computer=new AsusComputer();
break;
case "Alienware":
computer=new AlienwareComputer();
break;
default:
System.out.println("暂时没有此类笔记本工厂");
}
return computer;
}
}
3.工厂方法模式
定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类。
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。实现了Java程序设计的开闭原则,每次添加新产品不需要修改原代码。但,当需添加其他产品族时,需要修改模板中的抽象方法,违背开闭原则。
基于之前的简单工厂模式,我们将之前的 ComputerFactory 抽象成一个接口,那么创建相应具体的工厂类去实现该接口的方法。
public class FactoryMethod{
public void buy(Computer com){
com.printComputer();
}
public static void main(String[] args){
ComputerFactory computer=new MacComputerFactory();
FactoryMethod client =new FactoryMethod();
client.buy(computer.getInstance());
}
}
interface Computer{
void printComputer();
}
class MacComputer implements Computer{
public void printComputer(){
System.out.println("这是一台mac电脑");
}
}
class AsusComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕ASUS电脑");
}
}
class AlienwareComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕Alienware电脑");
}
}
interface ComputerFactory{
Computer getInstance();
}
class MacComputerFactory implements ComputerFactory{
public Computer getInstance(){
return new MacComputer();
}
}
class AsusComputerFactory implements ComputerFactory{
public Computer getInstance(){
return new AsusComputer();
}
}
class AlienwareComputerFactory implements ComputerFactory{
public Computer getInstance(){
return new AlienwareComputer();
}
}
4.抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂方法模式和抽象工厂模式基本类似.
我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现。
一个接口实现一个功能,由不同的产品实现接口从而实现此功能,若要新增功能,则增加新接口,再由这些不同的产品(定义新的类,因为增加了新功能的产品也不是以前的产品了)实现此接口从而实现新功能。
定义一个第三方接口专业名词为抽象工厂,这个接口中的方法是通过参数返回值得到实现各功能的不同的产品的对象实例,因此需要有共同的父类,即功能接口名作为参数。有几个功能则定义几个抽象方法,再由不同的产品工厂类实现此方法,从而得到不同产品的实现功能的实例。
public class AbstrctFactory{
public void buyComputer(Computer com){
com.printComputer();
}
public void checkSystem(OperateSystem sys){
sys.printSystem();
}
public static void main(String[] args){
AbstrctFactory client=new AbstrctFactory();
ProcductFactory computer=new MacComputerFactory();
client.buyComputer(computer.getInstance());
client.checkSystem(computer.getSystemInstance());
}
}
interface Computer{
void printComputer();
}
class MacComputer implements Computer{
public void printComputer(){
System.out.println("这是一台mac电脑");
}
}
class AsusComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕ASUS电脑");
}
}
class AlienwareComputer implements Computer{
public void printComputer(){
System.out.println("这是一台华硕Alienware电脑");
}
}
interface OperateSystem{
void printSystem();
}
class MacComputerSystem implements OperateSystem{
public void printSystem(){
System.out.println("MacComputer的操作系统是mac os");
}
}
class AsusComputerSystem implements OperateSystem{
public void printSystem(){
System.out.println("AsusComputer的操作系统是windows10");
}
}
class AlienwareComputerSystem implements OperateSystem{
public void printSystem(){
System.out.println("AlienwareComputer的操作系统是windows vitas");
}
}
interface ProcductFactory{
Computer getInstance();
OperateSystem getSystemInstance();
}
class MacComputerFactory implements ProcductFactory{
public Computer getInstance(){
return new MacComputer();
}
public OperateSystem getSystemInstance(){
return new MacComputerSystem();
}
}
class AsusComputerFactory implements ComputerFactory{
public Computer getInstance(){
return new AsusComputer();
}
public OperateSystem getSystemInstance(){
return new AsusComputerSystem();
}
}
class AlienwareComputerFactory implements ComputerFactory{
public Computer getInstance(){
return new AlienwareComputer();
}
public OperateSystem getSystemInstance(){
return new AlienwareComputerSystem();
}
}
5.代理设计模式
两个子类共同实现一个接口,其中一个子类负责真实业务实现,另外一个子类完成辅助真实业务主题的操作。
在辅助类中创建 接口类的对象,通过构造方法,将真实业务的对象作为参数,对接口类的对象实例化,通过实例化对象调用真实业务的方法。
public class ProxySubjectTest{
public static void main(String[] args){
Subject subject=SubjectFactory.getInstance();
subject.buyComputer();
}
}
interface Subject{
void buyComputer();
}
class RealSubject implements Subject{
public void buyComputer(){
System.out.println("买电脑");
}
}
class ProxySubject implements Subject{
private Subject sub;
public ProxySubject(Subject sub){
this.sub=sub;
}
public void produce(){
System.out.println("生产电脑");
}
public void afterBuy(){
System.out.println("售后");
}
public void buyComputer(){
this.produce();
this.sub.buyComputer();
this.afterBuy();
}
}
class SubjectFactory{
public static Subject getInstance(){
return new ProxySubject(new RealSubject());
}
}