本文主要参见自《Java与模式》
一、UML类图表示如下
二、角色如下
1.Product接口:
a.含有具体产品的共有接口。
2.ProductA,ProductB
a.工厂类所创建的这个角色的实例。
3.Factroy:
a.简单工厂模式的核心。
b.工厂类在客户端的直接调用下创建产品对象。
三、基本代码实现如下:
1.Product接口:
package com.jue.dp; public interface Fruit { void grow(); void harvest(); void plant(); }
2.ProductA,ProductB
package com.jue.dp; public class Apple implements Fruit { public static final String APPLE = "apple"; @Override public void grow() { LogUtil.logs(APPLE, "grow"); } @Override public void harvest() { LogUtil.logs(APPLE, "harvest"); } @Override public void plant() { LogUtil.logs(APPLE, "plant"); } }
其他雷同!
3.Factroy:
package com.jue.dp; public class FruitFactory { public static Fruit newInstance(String name) { if (name.equals("Apple")) { return new Apple(); } if (name.equals("Grape")) { return new Grape(); } if (name.equals("Strawberry")) { return new Strawberry(); } throw new BadFruitException(name); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Fruit f1 = FruitFactory.newInstance("Apple"); f1.plant(); f1.grow(); f1.harvest(); } }
四、优点:
1.责任分割:客户端可以免除直接创建产品对象的责任,客户端无需考虑如何创建,只需要知道创建什么以及负责消费产品。
五、缺点
1.开闭原则:
a.客户端符合开比原则
b.工厂类不符合:需要修改核心类,增加新的产品将导致工厂类的修改。
2.Factory变得臃肿:当产品比较多的时候,factory会无比臃肿。
3.无法继承:简单静态工厂的创建方法通常是static的,导致工厂角色无法形成继承结构。
六、扩展 : 使用反射可以创建任意产品对象。
public class FruitFactory2 { public static Fruit newInstance(String name) { Fruit f = null; try { f = (Fruit) Class.forName(name).newInstance(); } catch (Exception e) { e.printStackTrace(); } return f; } public static void main(String args[]){ Fruit f1 = FruitFactory2.newInstance("com.jue.dp.Apple"); f1.plant(); f1.grow(); f1.harvest(); } }
七、使用场景
a.简单工厂模式所创建的对象往往属于一个产品等级。
b.创建的对象比较少。
c.客户端关心于创建什么以及如何消费,而不关心如何创建。
八、简单工厂模式与单例模式的关系
1.抽象产品省略,工厂角色与具体产品合并,这种退化的简单工厂模式与单例有很多相似之处,但是与单例是不同的。
2.不同之处:
工厂模式总是创建新的实例。
单例模式要求单例类的构造器是私有的,禁止外部客户端对其实例化。
3. 联系
单例模式是建立在简单静态工厂模式基础之上的。
今天看了下Struts2 的struts-default.properties 配置,发现路还很长,拷了下官网的 Struts2默认配置,下还包括最新的struts-default.xml
### Struts default properties ###(can be overridden by a struts.properties file in the root of the classpath) ### ### Specifies the Configuration used to configure Struts ### one could extend org.apache.struts2.config.Configuration ### to build one's customize way of getting the configurations parameters into Struts # struts.configuration=org.apache.struts2.config.DefaultConfiguration ### This can be used to set your default locale and encoding scheme # struts.locale=en_US struts.i18n.encoding=UTF-8 ### if specified, the default object factory can be overridden here ### Note: short-hand notation is supported in some cases, such as "spring" ### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here # struts.objectFactory = spring ### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name ### indicates to the struts-spring integration if Class instances should be cached ### this should, until a future Spring release makes it possible, be left as true ### unless you know exactly what you are doing! ### valid values are: true, false (true is the default) struts.objectFactory.spring.useClassCache = true ### ensures the autowire strategy is always respected. ### valid values are: true, false (false is the default) struts.objectFactory.spring.autoWire.alwaysRespect = false ### if specified, the default object type determiner can be overridden here ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger" ### Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here ### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection ### using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's ### functions are integrated in DefaultObjectTypeDeterminer now. ### To disable tiger support use the "notiger" property value here. #struts.objectTypeDeterminer = tiger #struts.objectTypeDeterminer = notiger ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data # struts.multipart.parser=cos # struts.multipart.parser=pell struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152 ### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org/apache/struts2/extension/custom ### How request URLs are mapped to and from actions #struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper ### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do ### The blank extension allows you to match directory listings as well as pure action names ### without interfering with static resources, which can be specified as an empty string ### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,, struts.action.extension=action,, ### Used by FilterDispatcher ### If true then Struts serves static content from inside its jar. ### If false then the static content must be available at <context_path>/struts struts.serve.static=true ### Used by FilterDispatcher ### This is good for development where one wants changes to the static content be ### fetch on each request. ### NOTE: This will only have effect if struts.serve.static=true ### If true -> Struts will write out header for static contents such that they will ### be cached by web browsers (using Date, Cache-Content, Pragma, Expires) ### headers). ### If false -> Struts will write out header for static contents such that they are ### NOT to be cached by web browser (using Cache-Content, Pragma, Expires ### headers) struts.serve.static.browserCache=true ### Set this to false if you wish to disable implicit dynamic method invocation ### via the URL request. This includes URLs like foo!bar.action, as well as params ### like method:bar (but not action:foo). ### An alternative to implicit dynamic method invocation is to use wildcard ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}"> struts.enable.DynamicMethodInvocation = true ### Set this to true if you wish to allow slashes in your action names. If false, ### Actions names cannot have slashes, and will be accessible via any directory ### prefix. This is the traditional behavior expected of WebWork applications. ### Setting to true is useful when you want to use wildcards and store values ### in the URL, to be extracted by wildcard patterns, such as ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or ### "/foo/save". struts.enable.SlashesInActionNames = false ### use alternative syntax that requires %{} in most places ### to evaluate expressions for String attributes for tags struts.tag.altSyntax=true ### when set to true, Struts will act much more friendly for developers. This ### includes: ### - struts.i18n.reload = true ### - struts.configuration.xml.reload = true ### - raising various debug or ignorable problems to errors ### For example: normally a request to foo.action?someUnknownField=true should ### be ignored (given that any value can come from the web and it ### should not be trusted). However, during development, it may be ### useful to know when these errors are happening and be told of ### them right away. struts.devMode = false ### when set to true, resource bundles will be reloaded on _every_ request. ### this is good during development, but should never be used in production struts.i18n.reload=false ### Standard UI theme ### Change this to reflect which path should be used for JSP control tag templates by default struts.ui.theme=xhtml struts.ui.templateDir=template #sets the default template type. Either ftl, vm, or jsp struts.ui.templateSuffix=ftl ### Configuration reloading ### This will cause the configuration to reload struts.xml when it is changed struts.configuration.xml.reload=false ### Location of velocity.properties file. defaults to velocity.properties struts.velocity.configfile = velocity.properties ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext struts.velocity.contexts = ### Location of the velocity toolbox struts.velocity.toolboxlocation= ### used to build URLs, such as the UrlTag struts.url.http.port = 80 struts.url.https.port = 443 ### possible values are: none, get or all struts.url.includeParams = none ### Load custom default resource bundles # struts.custom.i18n.resources=testmessages,testmessages2 ### workaround for some app servers that don't handle HttpServletRequest.getParameterMap() ### often used for WebLogic, Orion, and OC4J struts.dispatcher.parametersWorkaround = false ### configure the Freemarker Manager class to be used ### Allows user to plug-in customised Freemarker Manager if necessary ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager ### Enables caching of FreeMarker templates ### Has the same effect as copying the templates under WEB_APP/templates struts.freemarker.templatesCache=false ### Enables caching of models on the BeanWrapper struts.freemarker.beanwrapperCache=false ### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap=true ### maxStrongSize for MruCacheStorage for freemarker, when set to 0 SoftCacheStorage which performs better in heavy loaded application ### check WW-3766 for more details struts.freemarker.mru.max.strong.size=0 ### configure the XSLTResult class to use stylesheet caching. ### Set to true for developers and false for production. struts.xslt.nocache=false ### Whether to always select the namespace to be everything before the last slash or not struts.mapper.alwaysSelectFullNamespace=false ### Whether to allow static method access in OGNL expressions or not struts.ognl.allowStaticMethodAccess=false ### Whether to throw a RuntimeException when a property is not found ### in an expression, or when the expression evaluation fails struts.el.throwExceptionOnFailure=false ### Logs as Warnings properties that are not found (very verbose) struts.ognl.logMissingProperties=false ### Caches parsed OGNL expressions, but can lead to memory leaks ### if the application generates a lot of different expressions struts.ognl.enableExpressionCache=true ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError() ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security struts.handle.exception=true
最新struts-default.xml 时间20130508
<?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id$ * * Licensed to the Apache Software Fou
双边滤波与一般的高斯滤波的不同就是:双边滤波既利用了位置信息<or 几何信息——高斯滤波只用了位置信息>又利用了像素信息来定义滤波窗口的权重。
像素值越接近,权重越大。双边滤波会去除图像的细节信息,又能保持边界。
对于彩色图像,像素值的接近与否不能使用RGB空间值,双边滤波的原始文献建议使用CIE颜色空间。
代码如下:
function resultI = BilateralFilt2(I,d,sigma) %%% %Author:LiFeiteng %Version:1.0——灰色图像 Time:2013/05/01 %Version:1.1——灰色/彩色图像 Time:2013/05/02 2013/05/05 %d 半窗口宽度 I = double(I); if size(I,3)==1 resultI = BilateralFiltGray(I,d,sigma); elseif size(I,3)==3 resultI = BilateralFiltColor(I,d,sigma); else error('Incorrect image size') end end function resultI = BilateralFiltGray(I,d,sigma) [m n] = size(I); newI = ReflectEdge(I,d); resultI = zeros(m,n); width = 2*d+1; %Distance D = fspecial('gaussian',[width,width],sigma(1)); S = zeros(width,width);%pix Similarity h = waitbar(0,'Applying bilateral filter...'); set(h,'Name','Bilateral Filter Progress'); for i=1+d:m+d for j=1+d:n+d pixValue = newI(i-d:i+d,j-d:j+d); subValue = pixValue-newI(i,j); S = exp(-subValue.^2/(2*sigma(2)^2)); H = S.*D; resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:)); end waitbar(i/m); end close(h); end function resultI = BilateralFiltColor(I,d,sigma) I = applycform(I,makecform('srgb2lab')); [m n ~] = size(I); newI = ReflectEdge(I,d); resultI = zeros(m,n,3); width = 2*d+1; %Distance D = fspecial('gaussian',[width,width],sigma(1)); % [X,Y] = meshgrid(-d:d,-d:d); % D = exp(-(X.^2+Y.^2)/(2*sigma(1)^2)); S = zeros(width,width);%pix Similarity h = waitbar(0,'Applying bilateral filter...'); set(h,'Name','Bilateral Filter Progress'); sigma_r = 100*sigma(2); for i=1+d:m+d for j=1+d:n+d pixValue = newI(i-d:i+d,j-d:j+d,1:3); %subValue = pixValue-repmat(newI(i,j,1:3),width,width); dL = pixValue(:,:,1)-newI(i,j,1); da = pixValue(:,:,2)-newI(i,j,2); db = pixValue(:,:,3)-newI(i,j,3); S = exp(-(dL.^2+da.^2+db.^2)/(2*sigma_r^2)); H = S.*D; H = H./sum(H(:)); resultI(i-d,j-d,1) = sum(sum(pixValue(:,:,1).*H)); resultI(i-d,j-d,2) = sum(sum(pixValue(:,:,2).*H)); resultI(i-d,j-d,3) = sum(sum(pixValue(:,:,3).*H)); end waitbar(i/m); end close(h); resultI = applycform(resultI,makecform('lab2srgb')); end
其中newI = ReflectEdge(I,d); %对称地扩展边界,在原始图像I的边界处镜像映射像素值
function newI = ReflectEdge(I,d) %Version:1.0——灰色图像 Time:2013/05/01 %Version:1.1——灰色/彩色图像 Time:2013/05/02 %考虑到实用性,决定不添加更多的边界处理选择,统一使用:reflect across edge if size(I,3)==1 newI = ReflectEdgeGray(I,d); elseif size(I,3)==3 newI = ReflectEdgeColor(I,d); else error('Incorrect image size') end end function newI = ReflectEdgeGray(I,d) [m n] = size(I); newI = zeros(m+2*d,n+2*d); %中间部分 newI(d+1:d+m,d+1:d+n) = I; %上 newI(1:d,d+1:d+n) = I(d:-1:1,:); %下 newI(end-d:end,d+1:d+n) = I(end:-1:end-d,:); %左 newI(:,1:d) = newI(:,2*d:-1:d+1); %右 newI(:,m+d+1:m+2*d) = newI(:,m+d:-1:m+1); end function newI = ReflectEdgeColor(I,d) %扩展图像边界 [m n ~] = size(I); newI = zeros(m+2*d,n+2*d,3); %中间部分 newI(d+1:d+m,d+1:d+n,1:3) = I; %上 newI(1:d,d+1:d+n,1:3) = I(d:-1:1,:,1:3); %下 newI(end-d:end,d+1:d+n,1:3) = I(end:-1:end-d,:,1:3); %左 newI(:,1:d,1:3) = newI(:,2*d:-1:d+1,1:3); %右 newI(:,m+d+1:m+2*d,1:3) = newI(:,m+d:-1:m+1,1:3); end
测试用例:
img = imread('.\lena.tif'); %%img = imread('.\images\lena_gray.tif'); img = double(img)/255; img = img+0.05*randn(size(img)); img(img<0) = 0; img(img>1) = 1; %img = imnoise(img,'gaussian'); figure, imshow(img,[]) title('原始图像') d = 6; sigma = [3 0.1]; resultI = BilateralFilt2(double(img), d, sigma); figure, imshow(resultI,[]) title('双边滤波后的图像')
结果:
Reference:
1.C Tomasi, R Manduchi.Bilateral Filtering for Gray and Color Images, - Computer Vision, 1998.