Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
In languages with dynamic typing, the use of polymorphism may trigger errors on a super-class.
I will try to explain my question with a simple example:
Supposing a language with dynamic typing (like ECMAScript) and the following class structure:
class A{
private idA;
public A(){
idA=0;
}
public foo(){
update();
if (this.idA!=3) Throws new Exception(" What is happening? ");
}
private update(){
this.idA = 3;
}
}
class B extends A{
private idB;
public B(){
super();
idB=0;
}
public foo(){
super.foo();
// Any operation between A::update and B::update()
if (this.idB!=0) Throws new Exception("hmmm, that could not happend!");
update();
}
private update(){
this.idB = 5;
}
}
In this very simple example, when i create an object of the class B, B::foo() call the parent A::foo(), which call "update". The object is an instance of B, so the "update" functions called is B::update, after that, in B::foo, the update function is again called (B::update). The final result is that A::update is never called, and idA still 0.
The class A work correctly when used alone, but after to extend it with B, the function foo() fail.
What is the correct solution this problem:
1) Force the class A to call A::update , that mean an ugly code every call to his own function (protect the super-class):
A::foo(){
A::update();
if (this.idA!=3) Throws new Exception(" What is happening? ");
}
2) B::update is an extension of A::update, so B::update must call itself the parent function (prepare the sub-class, and deal with problems):
B::foo(){
super.foo();
... // Any operation that must be performed between A::update and B::update
}
B::update(){
super.update();
this.idB = 5;
}
But in this case is the A::foo which call update, not the B::foo. That mean others problems.
3) Any other solution.
As a summary:
How to protect the super-class code against polymorphism?
Add protections into the super-class.
Deal with these problem creating the child-class
The language must do that! (do not know if it is possible with dynamically typed languages)
I am looking for a very theoretical /canonical solution to this question.
EDITED: to take the problem out of the constructor and clarify some points.
It's generally considered a very bad practice to call instance methods, and especially virtual instance methods from within a constructor exactly for this reason (but also for the reason that the object isn't done being "initialized" yet).
3) Any other solution.
Doc, it hurts when I do this.
Then don't do that!
Seriously, if you need to set IdA in the constructor of A, don't do it by calling update, do it by explicitly setting the value of IdA in the constructor for A.
The base class should protect itself from harmful overrides. In keeping with the open/close principle, it should be open to extension but closed to modification. Overriding update is a harmful modification of the base class's intended behaviour. In your example, there is no benefit in overriding update because both A::update and B::update are private methods that deal with private variables. There isn't even an expectation that they should be executed together judging by your exception in B::foo. If B::update was named differently, there wouldn't be anything wrong with your implementation. It would probably be OK anyway: since no language I know of will let you override a private method, B::update could hide A::update rather than overriding it.
Depending on the language, you can limit which methods can be overridden in different ways. Some languages require an indicator (a keyword or attribute usually) that a method can be overridden, others to show that it can't. Private methods are generally not overridable, but not all languages have access modifiers at all, and everything is effectively public. In this case you would have to use some kind of convention as suggested by #PoByBolek.
tl;dr: Children have no business with their parents' privates.
You're probably not going to like my answer but: convention and disciplin.
Establish conventions for
when it is safe for a child class to override a method without calling the parent class implementation,
when a child class has to call the parent class implementation of an overridden method,
when a child class must not override a parent class method.
Document these conventions and stick to them. They should probably be part of your code; either in form of comments or naming conventions (whatever works for you). I could think of something like this:
/*
* #final
*/
function shouldNotBeOverridden() {
}
/*
* #overridable
* #call-super
*/
function canBeOverriddenButShouldBeCalledFromChildClasses() {
}
/*
* #overridable
*/
function canBeOverridenWithoutBeingCalledFromChildClasses() {
}
This may help someone reading your code to figure out which methods he may or may not override.
And if someone still overrides your #final methods, you hopefully have thorough testing ;)
I like this answer to a somewhat similar question regarding python:
You could put a comment in there to the effect of:
# We'll fire you if you override this method.
If the language allows one class to call a private method of another class this way, the programmer has to understand and live with that. If I'm understanding your objective, foo and update should be overridden and update should be protected. They would then call the method in the parent class, when necessary. The derived foo method wouldn't need to call update, because calling foo in the parent class would take care of that. The code could work like this:
class A{
private idA;
public A(){
idA=0;
}
public foo(){
update();
if (this.idA!=3) Throws new Exception("idA not set by update");
}
protected update(){
this.idA = 3;
}
}
class B extends A{
private idB;
public B(){
super();
idB=0;
}
#Override
public foo(){
super.foo();
// Any operation between A::update and B::update()
if (this.idB!=5) Throws new Exception("idB not set by super.foo");
}
#Override
protected update(){
super.Update()
this.idB = 5;
}
}
I changed the exceptions to match expectations.
Related
I have two classes, E and F.
In class F, I'm trying to call the method which I created in class E called printData(), but I'm unable to call it. There is an error which says 'printData cannot be resolved or is not a field'. What is the reason? See the screenshots below. I did import the package as well(import login.*;)
package login;
public class E {
public void printData {
System.out.println("Hello...");
}
}
Class E
package testing;
import login.*;
public class F {
public void main(String[] args) {
B b = new B();
b.printData
}
}
Class F
In case it is not clear from my comment, your mistake is that in your main method of class F, you are creating an object of class B, which clearly does not have a public method printData, as opposed to class E, which does.
As this is basically a typo, I am voting to close this question, as it is of very little use to other users. You should not be disheartened, if the question is closed. This is normal behaviour on this site, to try to restrict the size of the repository of questions and answers to ones, which would be of greater use to more people.
I have included your code within the body of the question (as you should have done). People here do not appreciate images, as they cannot be copied. This also makes it clearer than you have a syntax error in calling the method: you need b.printData();. Without the parentheses, the compiler takes printData to be a field, not a method, hence the nature of your error message.
My goal is to write a class and have a function in it that contains code to run (in a run() function for example) in a background thread. Here are some requirements of my class (and related classes):
Ensure that when I write the run() function, the code is guaranteed to run in a background thread without the programmer needing to know anything about threading and without having to remember to call any other code in that run() function related to the threading.
Have a completion function function that is set elsewhere that is called when the background thread is finished its processing without the programmer having to write code in this run() function to make the call.
Pretty much let someone derive a class from some base class and then write their background code in it in a run() function without writing anything else related to managing the background thread, completion function, etc.
Here's the code I might write in C#, in two DIFFERENT files:
class MyBase
{
public Action completionFunction = NULL;
public void begin()
{
RunInOtherThread( run ); // This function call is just pseudo-code for running that run() function in a background thread.
if( completionFunction != Null )
completionFunction();
}
virtual protected void run() = 0 // so this class cannot be instantiated
{
}
};
And in the other file:
class MySpecificClass : MyBase
{
override void run()
{
// Do important stuff here!
}
};
I do not know how to meet my requirements in Swift. They left out the "protected" level of protection for reasons that do not make sense to me (like thinking that I could not just fire a programmer that screwed up the code by exposing a base class protected function through a public function).
I am not familiar enough with some of the features of Swift to get these results. I do not need to have the classes work like the C# code even though it is a pretty good solution for me and my C# programmers.
How can I meet my requirements Swift?
BTW, I have seen Q&A about this with no reasonable way to fake the protected access level. I don't need to fake it, I just need another way to achieve the goal of hiding code in a derived class from all the world except for the base class, or something like that.
I'd be tempted to use protocols for this, rather than sub-classing. For example:
public protocol MyBase {
// *** This requires any object that conforms to the protocol
// *** to provide these, without specifying what they do
var completionFunction: (() -> ())? {get set}
func run()
}
public extension MyBase {
// *** This extension provides all objects that conform to the
// *** protocol with this function
func begin() {
RunInOtherThread( self.run ) // This function call is just pseudo-code for running that run() function in a background thread.
if let c = self.completionFunction {
c()
}
}
}
public class MySpecificClass: MyBase {
// *** Now, rather than subclassing, we simply conform to the protocol
public var completionFunction: (() -> ())? = nil
public func run() {
// *** No need to `override` - but *must* be supplied
// Do important stuff here!
}
}
Does anyone know the best way to refactor a God-object?
Its not as simple as breaking it into a number of smaller classes, because there is a high method coupling. If I pull out one method, i usually end up pulling every other method out.
It's like Jenga. You will need patience and a steady hand, otherwise you have to recreate everything from scratch. Which is not bad, per se - sometimes one needs to throw away code.
Other advice:
Think before pulling out methods: on what data does this method operate? What responsibility does it have?
Try to maintain the interface of the god class at first and delegate calls to the new extracted classes. In the end the god class should be a pure facade without own logic. Then you can keep it for convenience or throw it away and start to use the new classes only
Unit Tests help: write tests for each method before extracting it to assure you don't break functionality
I assume "God Object" means a huge class (measured in lines of code).
The basic idea is to extract parts of its functions into other classes.
In order to find those you can look for
fields/parameters that often get used together. They might move together into a new class
methods (or parts of methods) that use only a small subset of the fields in the class, the might move into a class containing just those field.
primitive types (int, String, boolean). They often are really value objects before their coming out. Once they are value object, they often attract methods.
look at the usage of the god object. Are there different methods used by different clients? Those might go in separate interfaces. Those intefaces might in turn have separate implementations.
For actually doing these changes you should have some infrastructure and tools at your command:
Tests: Have a (possibly generated) exhaustive set of tests ready that you can run often. Be extremely careful with changes you do without tests. I do those, but limit them to things like extract method, which I can do completely with a single IDE action.
Version Control: You want to have a version control that allows you to commit every 2 minutes, without really slowing you down. SVN doesn't really work. Git does.
Mikado Method: The idea of the Mikado Method is to try a change. If it works great. If not take note what is breaking, add them as dependency to the change you started with. Rollback you changes. In the resulting graph, repeat the process with a node that has no dependencies yet. http://mikadomethod.wordpress.com/book/
According to the book "Object Oriented Metrics in Practice" by Lanza and Marinescu, The God Class design flaw refers to classes that tend to centralize the intelligence of the system. A God Class performs too much work on its own, delegating only minor details to a set of trivial classes and using the data from other classes.
The detection of a God Class is based on three main characteristics:
They heavily access data of other simpler classes, either directly or using accessor methods.
They are large and complex
They have a lot of non-communicative behavior i.e., there is a low
cohesion between the methods belonging to that class.
Refactoring a God Class is a complex task, as this disharmony is often a cumulative effect of other disharmonies that occur at the method level. Therefore, performing such a refactoring requires additional and more fine-grained information about the methods of the class, and sometimes even about its inheritance context. A first approach is to identify clusters of methods and attributes that are tied together and to extract these islands into separate classes.
Split Up God Class method from the book "Object-Oriented Reengineering Patterns" proposes to incrementally redistribute the responsibilities of the God Class either to its collaborating classes or to new classes that are pulled out of the God Class.
The book "Working Effectively with Legacy Code" presents some techniques such as Sprout Method, Sprout Class, Wrap Method to be able to test the legacy systems that can be used to support the refactoring of God Classes.
What I would do, is to sub-group methods in the God Class which utilize the same class properties as inputs or outputs. After that, I would split the class into sub-classes, where each sub-class will hold the methods in a sub-group, and the properties which these methods utilize.
That way, each new class will be smaller and more coherent (meaning that all their methods will work on similar class properties). Moreover, there will be less dependency for each new class we generated. After that, we can further reduce those dependencies since we can now understand the code better.
In general, I would say that there are a couple of different methods according to the situation at hand. As an example, let's say that you have a god class named "LoginManager" that validates user information, updates "OnlineUserService" so the user is added to the online user list, and returns login-specific data (such as Welcome screen and one time offers)to the client.
So your class will look something like this:
import java.util.ArrayList;
import java.util.List;
public class LoginManager {
public void handleLogin(String hashedUserId, String hashedUserPassword){
String userId = decryptHashedString(hashedUserId);
String userPassword = decryptHashedString(hashedUserPassword);
if(!validateUser(userId, userPassword)){ return; }
updateOnlineUserService(userId);
sendCustomizedLoginMessage(userId);
sendOneTimeOffer(userId);
}
public String decryptHashedString(String hashedString){
String userId = "";
//TODO Decrypt hashed string for 150 lines of code...
return userId;
}
public boolean validateUser(String userId, String userPassword){
//validate for 100 lines of code...
List<String> userIdList = getUserIdList();
if(!isUserIdValid(userId,userIdList)){return false;}
if(!isPasswordCorrect(userId,userPassword)){return false;}
return true;
}
private List<String> getUserIdList() {
List<String> userIdList = new ArrayList<>();
//TODO: Add implementation details
return userIdList;
}
private boolean isPasswordCorrect(String userId, String userPassword) {
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
private boolean isUserIdValid(String userId, List<String> userIdList) {
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
public void updateOnlineUserService(String userId){
//TODO updateOnlineUserService for 100 lines of code...
}
public void sendCustomizedLoginMessage(String userId){
//TODO sendCustomizedLoginMessage for 50 lines of code...
}
public void sendOneTimeOffer(String userId){
//TODO sendOneTimeOffer for 100 lines of code...
}}
Now we can see that this class will be huge and complex. It is not a God class by book definition yet, since class fields are commonly used among methods now. But for the sake of argument, we can treat it as a God class and start refactoring.
One of the solutions is to create separate small classes which are used as members in the main class. Another thing you could add, could be separating different behaviors in different interfaces and their respective classes. Hide implementation details in classes by making those methods "private". And use those interfaces in the main class to do its bidding.
So at the end, RefactoredLoginManager will look like this:
public class RefactoredLoginManager {
IDecryptHandler decryptHandler;
IValidateHandler validateHandler;
IOnlineUserServiceNotifier onlineUserServiceNotifier;
IClientDataSender clientDataSender;
public void handleLogin(String hashedUserId, String hashedUserPassword){
String userId = decryptHandler.decryptHashedString(hashedUserId);
String userPassword = decryptHandler.decryptHashedString(hashedUserPassword);
if(!validateHandler.validateUser(userId, userPassword)){ return; }
onlineUserServiceNotifier.updateOnlineUserService(userId);
clientDataSender.sendCustomizedLoginMessage(userId);
clientDataSender.sendOneTimeOffer(userId);
}
}
DecryptHandler:
public class DecryptHandler implements IDecryptHandler {
public String decryptHashedString(String hashedString){
String userId = "";
//TODO Decrypt hashed string for 150 lines of code...
return userId;
}
}
public interface IDecryptHandler {
String decryptHashedString(String hashedString);
}
ValidateHandler:
public class ValidateHandler implements IValidateHandler {
public boolean validateUser(String userId, String userPassword){
//validate for 100 lines of code...
List<String> userIdList = getUserIdList();
if(!isUserIdValid(userId,userIdList)){return false;}
if(!isPasswordCorrect(userId,userPassword)){return false;}
return true;
}
private List<String> getUserIdList() {
List<String> userIdList = new ArrayList<>();
//TODO: Add implementation details
return userIdList;
}
private boolean isPasswordCorrect(String userId, String userPassword)
{
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
private boolean isUserIdValid(String userId, List<String> userIdList)
{
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
}
Important thing to note here is that the interfaces () only has to include the methods used by other classes. So IValidateHandler looks as simple as this:
public interface IValidateHandler {
boolean validateUser(String userId, String userPassword);
}
OnlineUserServiceNotifier:
public class OnlineUserServiceNotifier implements
IOnlineUserServiceNotifier {
public void updateOnlineUserService(String userId){
//TODO updateOnlineUserService for 100 lines of code...
}
}
public interface IOnlineUserServiceNotifier {
void updateOnlineUserService(String userId);
}
ClientDataSender:
public class ClientDataSender implements IClientDataSender {
public void sendCustomizedLoginMessage(String userId){
//TODO sendCustomizedLoginMessage for 50 lines of code...
}
public void sendOneTimeOffer(String userId){
//TODO sendOneTimeOffer for 100 lines of code...
}
}
Since both methods are accessed in LoginHandler, interface has to include both methods:
public interface IClientDataSender {
void sendCustomizedLoginMessage(String userId);
void sendOneTimeOffer(String userId);
}
There are really two topics here:
Given a God class, how its members be rationally partitioned into subsets? The fundamental idea is to group elements by conceptual coherency (often indicated by frequent co-usage in client modules) and by forced dependencies. Obviously the details of this are specific to the system being refactored. The outcome is a desired partition (set of groups) of God class elements.
Given a desired partition, actually making the change. This is difficult if the code base has any scale. Doing this manually, you are almost forced to retain the God class while you modify its accessors to instead call new classes formed from the partitions. And of course you need to test, test, test because it is easy to make a mistake when manually making these changes. When all accesses to the God class are gone, you can finally remove it. This sounds great in theory but it takes a long time in practice if you are facing thousands of compilation units, and you have to get the team members to stop adding accesses to the God interface while you do this. One can, however, apply automated refactoring tools to implement this; with such a tool you specify the partition to the tool and it then modifies the code base in a reliable way. Our DMS can implement this Refactoring C++ God Classes and has been used to make such changes across systems with 3,000 compilation units.
I have C++ code (not mine, so it is not editable). Problem is with extending protected functions and class.
#include "ExtraClass.h"
...
MyClass::MyClass()
{
...
protected:
bool Func{}
ExtraClass m_Foo;
...
}
I need access in Python to m_Foo methods and protected functions like Func() like
from MyClass import *
bar = MyClass()
bar.m_Foo.Run() //something like this
but have an compiler error:
*error: ‘ExtraClass MyApp::m_Foo’ is protected*
PS. If I change protected with public (just for try). I can access *m_Foo* only in readonly mode:
class_<MyClass>("MyClass", init<>())
.def_readonly("m_Foo", &MyClass::m_Foo)
Changing to *def_readwrite* went to compiler error:
/boost_1_52_0/boost/python/data_members.hpp:64:11: error: no match for ‘operator=’ in ‘(((ExtraClass)c) + ((sizetype)((const boost::python::detail::member<ExtraClass, MyClass>*)this)->boost::python::detail::member<ExtraClass, MyClass>::m_which)) = d’
Thank you for any help!
In general, if you want to wrap protected members, then you need to derive a (wrapper) class from the parent that makes the members public. (You can simply say using Base::ProtectedMember in a public section to expose it instead of wrapping it). You will then have wrap it normally. Like this:
class MyWrapperClass : public MyClass {
public:
using MyClass::m_Foo;
};
In this particular example (which is really not fully baked), if you want to access m_Foo, then you need to wrap ExtraClass. Assuming that you have The problem with readwrite is likely the implementation of ExtraClass (which probably doesn't supply a operator= that you can use).
These three tests are identical, except that they use a different static function to create a StartInfo instance. I have this pattern coming up all trough my testcode, and would love
to be be able to simplify this using [TestCase], or any other way that reduces boilerplate code. To the best of my knowledge I'm not allowed to use a delegate as a [TestCase] argument, and I'm hoping people here have creative ideas on how to make the code below more terse.
[Test]
public void ResponseHeadersWorkinPlatform1()
{
DoResponseHeadersWorkTest(Platform1StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform2()
{
DoResponseHeadersWorkTest(Platform2StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform3()
{
DoResponseHeadersWorkTest(Platform3StartInfo.CreateOneRunning);
}
void DoResponseHeadersWorkTest(Func<ScriptResource,StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr).Start();
//assert some things here
}
Firstly, I don't think the original is too bad. It's only messy if your assertions are different from test case to test case.
Anyway, you can use a test case, but it can't be done via a standard [TestCase] attribute due to using more complicated types. Instead, you need to use a public IEnumerable<> as the data provider and then tag your test method with a [TestCaseSource] attribute.
Try something like:
public IEnumerable<Func<ScriptResource, StartInfo>> TestCases
{
get
{
yield return Platform1StartInfo.CreateOneRunning;
yield return Platform2StartInfo.CreateOneRunning;
yield return Platform3StartInfo.CreateOneRunning;
}
}
[TestCaseSource("TestCases")]
public void MyDataDrivenTest(Func<ScriptResource, StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr);
// do asserts
}
}
This is a more concise version of the standard pattern of yielding TestCaseData instances containing the parameters. If you yield instances of TestCaseData you can add more information and behaviours to each test (like expected exceptions, descriptions and so forth), but it is slightly more verbose.
Part of the reason I really like this stuff is that you can make one method for your 'act' and one method for your 'assert', then mix and match them independently. E.g. my friend was doing something yesterday where he used two Actions to say ("when method Blah is called, this method on the ViewModel should be triggered"). Very terse and effective!
It looks good. Are you looking to add a factory maybe ? Or you could add these methods to a Action List(in test setup) and call first action delegate, second action delegate and third action delegate.