假设您有以下统计相关类的层次结构,其结构类似于 Template method pattern :
interface S {
// Method definitions up-to and including the S3 class
}
class S0 implements S {
// Code that counts samples
}
class S1 extends S0 {
// Code that calls the superclass methods and also computes the mean
}
class S2 extends S1 {
// Code that calls the superclass methods and also computes the variance
}
class S3 extends S2 {
// Code that calls the superclass methods and also computes the skewness
}
S0C , S1C , S2C和 S3C来自 S0 , S1 , S2和 S3分别带有检查收敛的代码副本:S接口(interface),这完全破坏了任何模块化的感觉。S* 的功能具有新方法的类。如果我可以根据需要创建子类而无需重复代码,我可能会这样做。如果我能在使用地点(不太可能)做到这一点,那就更好了。 S*类是使用模板方法构建的:class S0 {
int addSample(double x) {
...;
}
double getMean() {
return Double.NaN;
}
}
class S1 extends S0 {
int addSample(double x) {
super.addSample(x);
...;
}
double getMean() {
return ...;
}
}
S*C第一个解决方案的扩展类将是这样的:interface S {
int addSample(double x);
double getMean();
}
class S0C extends S0 implements S {
int addSample(double x) {
super.addSample(x);
...;
}
boolean hasConverged() {
return ...;
}
}
class S1C extends S1 {
int addSample(double x) {
super.addSample(x);
...;
}
boolean hasConverged() {
return ...;
}
}
hasConverged() 的重复方法。 class CC<T extends S> implements S {
T o = ...;
int addSample(double x) {
o.addSample(x);
...;
}
double getMean() {
return o.getMean();
}
boolean hasConverged() {
return ...;
}
}
NB - 并且为了能够访问例如hasConverged()方法,新的装饰器需要:CC 相同的接口(interface)CC相同的接口(interface)对于其包装的对象类型... S*方法,如果我想能够使用 NB与 S*不使用的对象 CC S* 时类,我仍然需要原件完好无损。放例如通用父类(super class)中的收敛功能意味着相关行为(及其性能影响)现在将存在于所有子类中,这绝对不是我想要的。 最佳答案
根据您最近的编辑。
正如您可能已经意识到的那样,装饰器不适合于此。这是因为它解决的是单个功能的扩充,而不是整个类树的扩充。
实现这一目标的一种可能方式是使用策略。策略以算法为重点;它允许您解耦行为代码(对不起,如果这里和那里有一点 C#)
样本类
public class S {
private List<Integer> Samples = new List<Integer>();
public void addSample(int x){
Samples.Add(new Integer(x));
}
public void Process(IOp[] operations){
for (Op operation : operations){
Process(operation);
}
}
public void Process(ICollection<IOp> operations){
for (Op operation : operations){
Process(operation);
}
}
public void Process(IOp operation){
operation.Compute(this.Samples);
}
}
public interface IOp {
// Interface is optional. Just for flexibility.
public void Compute(List<Integer> data);
}
public class Op<T> implements IOp{
// Generics is also optional. I use this to standardise data type of Result, so that it can be polymorphically accessed.
// You can also put in some checks to make sure Result is initialised before it is accessed.
public T Result;
public void Compute(List<Integer> data);
}
class ComputeMeanOperation extends Op<double>{
public void Compute(List<Integer> data){
/* sum and divide to get mean */
this.Result = /* ... */
}
}
class CheckConvergenceOperation extends Op<boolean>{
public void Compute(List<Integer> data){
/* check convergence */
this.Result = /* ... */
}
}
public static void main(String args[]) {
S s = new S();
s.addSample(1);
/* ... */
ComputeMeanOperation op1 = new ComputeMeanOperation();
CheckConvergenceOperation op2 = new CheckConvergenceOperation ();
// Anonymous Operation
Op<Integer> op3 = new Op<Integer>(){
public void Compute(List<Integer> samples){
this.Result = samples[0]; // Gets first value of samples
}
}
s.Process(op1); // Or use overloaded methods
s.Process(op2);
s.Process(op3);
System.out.println("Op1 result: " + op1.Result);
System.out.println("Op2 result: " + op2.Result);
System.out.println("Op3 result: " + op3.Result);
}
关于java - Java 中装饰器模式的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7707363/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
“输出”是一个序列化的OpenStruct。定义标题try(:output).try(:data).try(:title)结束什么会更好?:) 最佳答案 或者只是这样:deftitleoutput.data.titlerescuenilend 关于ruby-on-rails-更好的替代方法try(:output).try(:data).try(:name)?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht