Java中常用的设计模式有哪些请详细说明一下工厂模式
1.单例模式(有的书上说叫单态模式其实都一样)
该模式主要目的是使内存中保持1个对象
2.工厂模式
该模式主要功能是统一提供实例对象的引用。看下面的例子:
public class Factory{
public ClassesDao getClassesDao(){
ClassesDao cd = new ClassesDaoImpl();
return cd;
}
}
interface ClassesDao{
public String getClassesName();
}
class ClassesDaoImpl implements ClassesDao {
public String getClassesName(){
System.out.println(“A班“);
}
}
class test
{
public static void main(String args){
Factory f = new Factory();
f.getClassesDao().getClassesName();
}
}
这个是最简单的例子了,就是通过工厂方法通过接口获取对象的引用
3.建造模式
该模式其实就是说,一个对象的组成可能有很多其他的对象一起组成的,比如说,一个对象的实现非常复杂,有很多的属性,而这些属性又是其他对象的引用,可能这些对象的引用又包括很多的对象引用。封装这些复杂性,就可以使用建造模式。
4.门面模式
这个模式个人感觉像是Service层的一个翻版。比如Dao我们定义了很多持久化方法,我们通过Service层将Dao的原子方法组成业务逻辑,再通过方法向上层提供服务。门面模式道理其实是一样的。
5.策略模式
这个模式是将行为的抽象,即当有几个类有相似的方法,将其中通用的部分都提取出来,从而使扩展更容易。
java工厂模式,懂的人进
举两个例子以快速明白Java中的简单工厂模式:
女娲抟土造人
话说:“天地开辟,未有人民,女娲抟土为人。”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面。
女娲造人,这就是简单工厂模式的应用。
首先,在这个造人的思想里面,有几个重要的角色:女娲本身、抽象的人的概念和女娲所造出的一个个具体的人。
1.)女娲是一个工厂类,也就是简单工厂模式的核心角色。
2.)具休的一个个的人,包括张三,李四等。这些人便是简单工厂模式里面的具体产品角色
3.)抽象的人是最早只存在于女娲的头脑里的一个想法,女娲按照这个想法造出的一个个具体的人,便都符合这个抽象的人的定义。换言之,这个抽象的想法规定了所有具体的人必须都有的接口(特征或者功能)
其UML类图出下所示:
理解了上面的这些东西,再来理解下面的例子,对照理解,相信看完这篇文章,便对java简单工厂模式有一个很好的理解:
有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列水果:
葡萄 Grape
草莓 Stuawberry
苹果 Apple
水果与其他植物不同,最终可以采摘食用,那么一个自然的做法是建立一个各种水果都适用的接口,以便与其他农场里的植物区分开来,
此时,则是为水果类声明了一个接口,表现在代码上:
1 public interface Fruit {
2 // 生长
3 void grow();
4 // 收获
5 void harvest();
6 // 种植
7 void plant();
8 }
9
10
水果接口规定出所有的水果必须实现的接口,包括任何水果类必须具备的方法plant(),grow(),和harvest();
Apple类是水果类的一种,因此它实现了水果接口所声明的所有方法。另处,由于苹果是多年生植物,因此多出一个treeAge性质,描述苹果的树龄。代码如下所示:
package fac;
public class Apple implements Fruit { // 通过implements实现接口Fruit
private int treeAge;
public void grow() {
log( “ Apple is growing “ );
}
public void harvest() {
log( “ Apple has been harvested “ );
}
public void plant() {
log( “ Apple ha been planted “ );
}
public static void log(String msg) {
System.out.println(msg);
}
public int getTreeAge() {
return treeAge;
}
public void setTreeAge( int treeAge) {
this .treeAge = treeAge;
}
}
同理,葡萄 Grape:
package fac;
public class Grape implements Fruit{
private boolean seedless;
public void grow(){
log(“Grape is growing.“);
}
public void harvest(){
log(“Grape has been harvested“);
}
public void plant(){
log(“Grape ha been planted“);
}
public static void log(String msg){
System.out.println(msg);
}
public boolean isSeedless() {
return seedless;
}
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
}
草莓 Stuawberry:
package fac;
public class Strawberry implements Fruit{
public void grow(){
log(“Strawberry is growing“);
}
public void harvest(){
log(“Strawberry has been harvested“);
}
public void plant(){
log(“Strawberry has been planted“);
}
public static void log(String msg){
System.out.println(msg);
}
}
农场园丁也是系统的一部分,由一个类来代表,FruitGardener类,代码如下:
package fac;
public class FruitGardener{
public static Fruit factory(String which)throws Exception{
if(which.equalsIgnoreCase(“apple“)){
return new Apple();
}else if(which.equalsIgnoreCase(“strawberry“)){
return new Strawberry();
}else if (which.equalsIgnoreCase(“grape“)){
return new Grape();
}else{
throw new Exception(“Bad fruit request“);
}
}
}
这时有人来果园玩,和园丁说,给我们介绍下你的水果吧。于是园丁:
package fac;
public class People {
public static void main(String args) throws Exception {
FruitGardener fg=new FruitGardener();
Fruit ap=fg.factory(“Apple“);
ap.grow();
Fruit gp=fg.factory(“Grape“);
gp.plant();
Fruit dd=fg.factory(“ddd“);//抛出Bad fruit request异常
}
}
(注:以上代码在JDK5.0,Myeclise3.2下编译通过)
类比两个例子,园丁就相当于女娲,而水果就相当于具体的人,接口水果类就相当于存在于类女娲思想里的人的抽象概念。
由以上两个例子可得出,简单工厂模式需要由以下角色组成:
接口
接口的实现类(简单工厂模式里面的具体产品角色)
工厂
理解了以下两个例子,再来看第三个例子:
注意对比以下三个实例的不同
实例1:
package org.jzkangta.factorydemo01;
//定义接口
interface Car{
public void run();
public void stop();
}
//具体实现类
class Benz implements Car{
public void run(){
System.out.println(“Benz开始启动了。。。。。“);
}
public void stop(){
System.out.println(“Benz停车了。。。。。“);
}
}
//具体实现类
class Ford implements Car{
public void run(){
System.out.println(“Ford开始启动了。。。“);
}
public void stop(){
System.out.println(“Ford停车了。。。。“);
}
}
//工厂
class Factory{
public static Car getCarInstance(){
return new Ford();
}
}
public class FactoryDemo01 {
public static void main(String args) {
Car c=Factory.getCarInstance();
c.run();
c.stop();
}
}
实例二:
package fac;
//定义接口
interface Car{
public void run();
public void stop();
}
//具体实现类
class Benz implements Car{
public void run(){
System.out.println(“Benz开始启动了。。。。。“);
}
public void stop(){
System.out.println(“Benz停车了。。。。。“);
}
}
class Ford implements Car{
public void run(){
System.out.println(“Ford开始启动了。。。“);
}
public void stop(){
System.out.println(“Ford停车了。。。。“);
}
}
//工厂
class Factory{
public static Car getCarInstance(String type){
Car c=null;
if(“Benz“.equals(type)){
c=new Benz();
}
if(“Ford“.equals(type)){
c=new Ford();
}
return c;
}
}
public class FactoryDemo02 {
public static void main(String args) {
Car c=Factory.getCarInstance(“Benz“);
if(c!=null){
c.run();
c.stop();
}else{
System.out.println(“造不了这种汽车。。。“);
}
}
}
实例三:
interface Car{
public void run();
public void stop();
}
class Benz implements Car{
public void run(){
System.out.println(“Benz开始启动了。。。。。“);
}
public void stop(){
System.out.println(“Benz停车了。。。。。“);
}
}
class Ford implements Car{
public void run(){
System.out.println(“Ford开始启动了。。。“);
}
public void stop(){
System.out.println(“Ford停车了。。。。“);
}
}
class Toyota implements Car{
public void run(){
System.out.println(“Toyota开始启动了。。。“);
}
public void stop(){
System.out.println(“Toyota停车了。。。。“);
}
}
class Factory{
public static Car getCarInstance(String type){
Car c=null;
try {
c=(Car)Class.forName(“org.jzkangta.factorydemo03.“+type).newInstance();//利用反射得到汽车类型
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
public class FactoryDemo03 {
public static void main(String args) {
Car c=Factory.getCarInstance(“Toyota“);
if(c!=null){
c.run();
c.stop();
}else{
System.out.println(“造不了这种汽车。。。“);
}
}
}
对比三个实例:
实例一,虽然实现了简单工厂,但每次只能得到一种汽车,如果我们想换一种,就得修改工厂,太不方便,而实例二则改变了这种情况,便得我们可以按照我们的需要更换汽车,但我们所更换的汽车必须是实现类中有的,如果我们想要增加一种汽车的时候,我们还是得更改工厂,通过改进,实例三利用反射机制,得到汽车类型,这样当我们需要增加一种新的汽车时,就无需要再修改工厂,而只需要增加要实现的类即可。也就是说要增加什么样的汽车直接增加这个汽车的类即可,而无需改变工厂。从而达到了工厂分离的效果。
java简单工厂模式是什么
简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
那么简单工厂模式是在什么场景下使用呢,下面就以本人的理解举例说明:
就拿登录功能来说,假如应用系统需要支持多种登录方式如:口令认证、域认证(口令认证通常是去数据库中验证用户,而域认证则是需要到微软的域中验证用户)。那么自然的做法就是建立一个各种登录方式都适用的接口,如下图所示:
public interface Login {
//登录验证
public boolean verify(String name , String password);
}
public class DomainLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
}
}
public class PasswordLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 业务逻辑
*/
return true;
}
}
我们还需要一个工厂类LoginManager,根据调用者不同的要求,创建出不同的登录对象并返回。而如果碰到不合法的要求,会返回一个Runtime异常。
public class LoginManager {
public static Login factory(String type){
if(type.equals(“password“)){
return new PasswordLogin();
}else if(type.equals(“passcode“)){
return new DomainLogin();
}else{
/**
* 这里抛出一个自定义异常会更恰当
*/
throw new RuntimeException(“没有找到登录类型“);
}
}
}
测试类:
public class Test {
public static void main(String args) {
// TODO Auto-generated method stub
String loginType = “password“;
String name = “name“;
String password = “password“;
Login login = LoginManager.factory(loginType);
boolean bool = login.verify(name, password);
if (bool) {
/**
* 业务逻辑
*/
} else {
/**
* 业务逻辑
*/
}
}
}
简单工厂模式的结构如下图:
我们可以设想一下真实的场景,如果把上面的Test当做一个servlet的话,当客户端发起登录请求——》请求交给服务端的Servlet——》Servlet根据客户端传递的loginType调用工厂类LoginManager的factory()方法——》factory()方法根据参数loginType创建相应的登录验证类(DomainLogin或PasswordLogin)并返回——》登录验证类调用方法verify()验证用户名密码是否正确
假如不使用简单工厂模式则验证登录Servlet代码如下(假设Test为一个Servlet,变量loginType、name、password表示从客户端传递过来的参数):
public class Test {
public static void main(String args) {
// TODO Auto-generated method stub
String loginType = “password“;
String name = “name“;
String password = “password“;
//处理口令认证
if(loginType.equals(“password“)){
PasswordLogin passwordLogin = new PasswordLogin();
boolean bool = passwordLogin.verify(name, password);
if (bool) {
/**
* 业务逻辑
*/
} else {
/**
* 业务逻辑
*/
}
}
//处理域认证
else if(loginType.equals(“passcode“)){
DomainLogin domainLogin = new DomainLogin();
boolean bool = domainLogin.verify(name, password);
if (bool) {
/**
* 业务逻辑
*/
} else {
/**
* 业务逻辑
*/
}
}else{
/**
* 业务逻辑
*/
}
}
}
上面的代码会不会很蛋疼啊。。。呵呵
《JAVA与模式》一书中使用java.text.DataFormat类作为简单工厂模式的典型例子叙述。
简单工厂模式的优点
模式的核心是工厂类。这个类含有必要的逻辑判断,可以决定在什么时候创建哪一个登录验证类的实例,而调用者则可以免除直接创建对象的责任。简单工厂模式通过这种做法实现了对责任的分割,当系统引入新的登录方式的时候无需修改调用者。
简单工厂模式的缺点
这个工厂类集中了所以的创建逻辑,当有复杂的多层次等级结构时,所有的业务逻辑都在这个工厂类中实现。什么时候它不能工作了,整个系统都会受到影响。
用java 编写程序写出简单的工厂模式
java中工厂模式分为:
-
简单工厂模式(Simple Factory)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)
每种方法的实现不同
提供一个简单工厂模式的案例:
public abstract class Woman {
private String mySkill;
public String getMySkill() {
return mySkill;
}
public Woman() {
//System.out.println(“我是女人“);
}
public void setMySkill(String mySkill) {
this.mySkill = mySkill;
}
}
—————————-
public class LovelinessWoman extends Woman{
/*
* 可爱型女人
*/
public LovelinessWoman()
{
String mySkill=“撒过娇、出过轨、勾引领导下过水“;
this.setMySkill(mySkill);
}
}
—————————–
public class SteelinessWoman extends Woman{
/*
* 冷酷型女人
*/
public SteelinessWoman()
{
String mySkill=“装过神、弄过鬼,跟别人老公亲过嘴“;
this.setMySkill(mySkill);
}
}
————————————–
public class WomanMakeFactory {
public Woman findWoman(int typeID) {
switch (typeID) {
case 1:
return new LovelinessWoman();
case 2:
return new VirtuousWoman();
case 3:
return new SteelinessWoman();
default:
return null;
}
}
public Woman findWoman(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
/*
* Type t = Type.GetType(“SimpleFactory.“ + type);
* Woman wm =
* (Woman)Activator.CreateInstance(t); return wm;
*/
String string=“cn.jbit.design.simplefactory.“+type;
Class c = Class.forName(string);
Woman wm = (Woman) c.newInstance();
return wm;
}
}
————————-
调用
public class Test2 {
/**
* @param args
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
*/
public static void main(String args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Scanner input=new Scanner(System.in);
boolean sel=false;
do {
System.out.println(“请选择你要找的女人的类型“);
System.out.println(“LovelinessWoman:可爱型女人 VirtuousWoman:善良型女人 SteelinessWoman:冷酷型女人“);
String typeid=input.next();
WomanMakeFactory factory = new WomanMakeFactory();
Woman wm=factory.findWoman(typeid);
System.out.println(“该类型女人的新标准:“);
System.out.println(wm.getMySkill());
System.out.println(“还想看看别的类型吗?y代表想,n代表再也不想了“);
sel=input.next().equals(“y“);
} while (sel);
}
}
求java工厂模式的一个简单代码例子,尽量简单
这个应该比较简单一点。
某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等,且用户可以根据要求动态选择日志记录方式。现使用工厂方法模式设计该系统,并写出相应Java代码。
interface Log{
public void writeLog();
}
class FileLog implements Log{
public void writeLog(){
System.out.println(“文件记录“);
}
}
class DatabaseLog implements Log{
public void writeLog(){
System.out.println(“数据库记录“);
}
}
interface LogFactory{
public Log createLog();
}
class FileLogFactory implements LogFactory{
public Log createLog(){
return new FileLog();
}
}
class DatabaseLogFactory implements LogFactory{
public Log createLog(){
return new DatabaseLog();
}
}
public class Client{
public static void main(String args) {
try{
Log log;
LogFactory factory;
//这里可以改成使用DOM和Java反射机制读取XML文件,获取工厂类名
factory=new DatabaseLogFactory ();
log=factory.createLog();
log.writeLog();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
java工厂模式例子
产品
public interface Work {
void doWork();
}
ConcreteProduct
public class StudentWork implements Work {
public void doWork() {
System.out.println(“学生做作业!“);
}
}
public class TeacherWork implements Work {
public void doWork() {
System.out.println(“老师审批作业!“);
}
}
生产者
public interface IWorkFactory {
Work getWork();
}
ConcreteCreator
public class StudentWorkFactory implements IWorkFactory {
public Work getWork() {
return new StudentWork();
}
}
public class TeacherWorkFactory implements IWorkFactory {
public Work getWork() {
return new TeacherWork();
}
}
Test
public class Test {
public static void main(String args) {
IWorkFactory studentWorkFactory = new StudentWorkFactory();
studentWorkFactory.getWork().doWork();
IWorkFactory teacherWorkFactory = new TeacherWorkFactory();
teacherWorkFactory.getWork().doWork();
}
}
关于java工厂模式
呵,我最近也在研究这个,文字一堆的概念性的东西我就不说了,看着就烦~我理解的工厂模式应该这样的:对于初学者来说,设计一个程序往往是边写代码边修正,缺乏一个环节:设计工厂模式我觉得应该是以设计为第一步的编程方法首先拿到一个项目后,先分析这个项目你准备写哪些类,分别实现哪些功能然后看看你的个各类中是否有功能相同或者功能类似的部分,将这些部分提取出来然后按照他们的层次设计不同的接口,最后为所有接口设计一个抽象类 举个例子,假设我们要描述一个人的特征,可以定义一个human类,并赋予它成员变量:age,sex,height,weight…等等等等。那么在描述这个人的时候,可以实例化这个human类,然后采用human.age=19; human.sex=“男性“;等等这类方法来描述这个对象。这样的描述不能说有错,但并不是工厂模式。假设有四个不同的人,先提取他们的共同特征,2男2女,都是人。那么可以这样描述他们:先定义一个顶层的抽象类:人类然后定义2个接口,分别对人类进行扩展性描述:男人,女人再定义2个接口,再对上面的类进行扩展性描述:年轻男人,年老男人,年轻女人,年老女人那么引用了年轻男人这个接口的类就直接被赋予了人类、性别、年龄这三个属性特征。也就是说,如果用前一种方式来描述一个人,它只是一个孤立的类,用工厂模式来描述一个人,它其实是一个树形结构。 表面上看起来,工厂模式写起来似乎更加的麻烦,其实它有它的优点所在:1、能体现你的几个类的层次结构,父子关系,引用关系。而不是为了引用代码就使用继承,为了多重继承就使用接口,我觉得这些都是错误的用法。2、假设需要你描述100个人,每个人都要用50个形容词来修饰他,那么第一种方法无疑是艰巨的任务。为了描述一个人的某个特征,你不得不去描述他们的49个特征,这样的工作要重复100次!但如果用工厂模式,你只需要建立好工厂模式的构架,选择就接近对象特征的那个类进行实例化就可以了!3、在维护方法,一旦程序需要扩展功能,第一种方法就只能不断的向human类添加成员变量,向滚雪球一样越滚越大,而你所有引用了human类的地方都必须修改,对于一个大的项目来说维护工作是致命的!而使用工厂模式,你可以随时在任意两个类中插入其他的类,只需要更改上下的引用而已,而你其他引用了这些类的地方则完全不受其影响! 所以才说JAVA是一门设计的语言,以上只是我个人的理解,至于对不对,还在实践中~~
Java的工厂模式有哪一些,分别有什么作用,一般用在哪些地方
我简单的说下,举个例子,当我们的程序结构比较繁杂时,比如有100个类,而类中又有很多方法,这些方法之间都互相有依赖关系,也就是一个方法之间的某段逻辑处理需要用到另一个类中的代码逻辑,这种时候对于整个程序而言是非常不利于开发的(我们需要考虑到很多类、方法之间的耦合问题),那么就有一个概念了,也就是面对接口编程。通俗的说就是把类中的方法封装起来,外部调用的人完全不需要考虑方法是如何实现的,但是这样做也有一个不好的地方,我们的接口是不提供方法实现的,而需要在类中实现接口的方法。那么问题产生了,我们在new接口对象的时候需要明确的知道他的实例类。
想象一下,如果程序在继续庞大,接口非常多,接口实例类非常多,这样又会产生我们之前的问题(我们需要考虑到很多类、方法之间的耦合问题)那么这个时候就产生了一中设计思想,也就是工厂模式,这种模式的核心思想就是管理接口的实例对象,把接口和实例对象之间的关系封装起来处理,外部需要用到某个接口的实例时,由工厂进行分配,而不需要关注具体是哪个实例。
如果你做到比较复杂的程序时你应该就能体会到了。
什么是工厂模式有没有用工厂模式解决实际问题
工厂模式的思想主要为:多个类似的子类继承同一个父类,对其父类中的变量进行操作;工厂类负责判断、控制哪个子类被执行,而工厂类调用子类完成后,返回的结果是该子类的父类,该父类中的变量已经被操作过了,访问该父类,得到我们想要的结果
例如:
public interface Fruit {
void grow();//生长
void harvest();//收获
void plant();//种植
}
public class Apple implements Fruit{
private int treeAge;
public void grow() {
System.out.println(“Apple is growing“);
}
public void harvest() {
System.out.println(“Apple has been harvested“);
}
public void plant() {
System.out.println(“Apple has been planted“);
}
public int getTreeAge()
{
return treeAge;
}
public void setTreeAge(int age)
{
this.treeAge=age;
}
}
public class Grape implements Fruit {
private boolean seedless;
public void grow() {
System.out.println(“Apple is growing“);
}
public void harvest() {
System.out.println(“Apple has been harvested“);
}
public void plant() {
System.out.println(“Apple has been planted“);
}
public boolean getSeedless()
{
return seedless;
}
public void setSeedless(boolean seed)
{
this.seedless=seed;
}
}
public class FruitGardener {
public static Fruit factory(String which) throws BadFruitException
{
if(which.equalsIgnoreCase(“apple“))
{
return new Apple();
}
else if(which.equalsIgnoreCase(“grape“))
{
return new Grape();
}
else
{
throw new BadFruitException(“Bad Fruit request“);
}
}
}
public class BadFruitException extends Exception{
public BadFruitException(String msg)
{
super(msg);
}
}
public static void main(String args)
{
try
{
FruitGardener.factory(“apple“);
FruitGardener.factory(“grape“);
}
catch(BadFruitException e)
{
System.out.println(e);
}
}
}